All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.magicall.biz.event.Notice Maven / Gradle / Ivy

There is a newer version: 2.13.0
Show newest version
/*
 * Copyright (c) 2024 Liang Wenjian
 * magicall is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

package me.magicall.biz.event;

import me.magicall.relation.Owned;
import me.magicall.biz.Op;
import me.magicall.biz.event.SimpleNotice.Builder;

import java.time.Instant;
import java.util.Objects;
import java.util.stream.Stream;

/**
 * 通告。是对已发生之事的描述,是不可变的。可视为事件。
 * 为与其他系统常见的“事件/Event”相区别,故用“通告”为名。
 *
 * @param <_TargetOwner>   计划针对的对象的主人的类型。
 * @param <_TargetValType> 计划针对的对象的类型。
 */
public interface Notice<_TargetOwner, _TargetValType> extends Owned {

	/**
	 * 事件的结果
	 *
	 * @return 结果。
	 */
	Object getResult();

	/**
	 * 事件发生的时间。
	 *
	 * @return 发生的时间。
	 */
	Instant getHappenedTime();

	/**
	 * 是否发生在other事件之前。
	 *
	 * @param other 另一事件
	 * @return 是否发生在other事件之前。
	 */
	default boolean isBefore(final Notice other) {
		return getHappenedTime().isBefore(other.getHappenedTime());
	}

	/**
	 * 是否发生在other事件之后。
	 *
	 * @param other 另一事件
	 * @return 是否发生在other事件之后。
	 */
	default boolean isAfter(final Notice other) {
		return getHappenedTime().isBefore(other.getHappenedTime());
	}

	Op getOp();

	/**
	 * 本通知的主人,即主语。
	 *
	 * @return 主人
	 */
	@Override
	Object owner();

	/**
	 * 事件的目标/宾语(直接宾语)。若事件无宾语则返回空列表。
	 *
	 * @return 本通知的目标
	 */
	Target<_TargetOwner, _TargetValType> getTarget();

	//==============================因果链

	/**
	 * 触发本事件的原因事件。
	 *
	 * @return 原因。
	 */
	Notice getReason();

	/**
	 * 获取根源事件。
	 *
	 * @return 根源事件。
	 */
	default Notice getRootEvent() {
		Notice e = this;
		for (var reason = e.getReason(); reason != null; reason = reason.getReason()) {
			e = reason;
		}
		return e;
	}

	/**
	 * 是否other事件的直接或间接原因。
	 *
	 * @param other 另一事件。
	 * @return 是否other事件的直接或间接原因。
	 */
	default boolean isReasonOf(final Notice other) {
		return Stream.>iterate(other.getReason(), Objects::nonNull, Notice::getReason)
			.anyMatch(this::equals);
	}

	/**
	 * 是否other事件的直接原因。
	 *
	 * @param other 另一事件
	 * @return 是否other事件的直接原因。
	 */
	default boolean isDirectReasonOf(final Notice other) {
		return equals(other.getReason());
	}

	/**
	 * 是否由other事件直接触发。
	 *
	 * @param other 另一事件
	 * @return 是否由other事件直接触发。
	 */
	default boolean isTriggeredBy(final Notice other) {
		return Objects.equals(getReason(), other);
	}

	/**
	 * 是否other事件的效果之一。“效果”指本事件是由另一事件直接或间接触发。
	 *
	 * @param other 另一事件
	 * @return 是否other事件的效果之一。“效果”指本事件是由另一事件直接或间接触发。
	 */
	default boolean isEffectOf(final Notice other) {
		final var myReason = getReason();
		return myReason != null && other.isReasonOf(myReason);
	}

	//=======================================

	static <_TargetOwner, _TargetValue> Builder<_TargetOwner, _TargetValue> from(final Object owner) {
		return new Builder<>(owner);
	}

	static <_TargetOwner, _TargetValue> Notice<_TargetOwner, _TargetValue> resultOf(
		final Plan<_TargetOwner, _TargetValue> plan, final Object result) {
		return new SimplePlanRealizedNotice<>(plan, result);
	}
}