/// <summary> /// TBD /// </summary> /// <param name="watchee">TBD</param> /// <param name="watcher">TBD</param> protected void RemWatcher(IActorRef watchee, IActorRef watcher) { var watcheeSelf = watchee.Equals(Self); var watcherSelf = watcher.Equals(Self); if (watcheeSelf && !watcherSelf) { if (_state.ContainsWatchedBy(watcher)) { MaintainAddressTerminatedSubscription(() => { _state = _state.RemoveWatchedBy(watcher); if (System.Settings.DebugLifecycle) { Publish(new Debug(Self.Path.ToString(), Actor.GetType(), string.Format("no longer watched by {0}", watcher))); } }, watcher); } } else if (!watcheeSelf && watcherSelf) { Unwatch(watchee); } else { Publish(new Warning(Self.Path.ToString(), Actor.GetType(), string.Format("BUG: illegal Unwatch({0},{1} for {2}", watchee, watcher, Self))); } }
/// <summary> /// TBD /// </summary> /// <param name="actor">TBD</param> protected void UnwatchWatchedActors(ActorBase actor) { var watching = _state .GetWatching() .ToList(); if (!watching.Any()) { return; } MaintainAddressTerminatedSubscription(() => { try { // ➡➡➡ NEVER SEND THE SAME SYSTEM MESSAGE OBJECT TO TWO ACTORS foreach (var watchee in watching.OfType <IInternalActorRef>()) { watchee.SendSystemMessage(new Unwatch(watchee, _self)); } } finally { _state = _state.ClearWatching(); _state = _state.ClearTerminated(); } }); }
public static bool Handle(IActorState state, ICommand command) { if (command is CreateBasketCommand) { return(true); } else if (command is AddLineItemToBasketCommand) { // Validate and do side effects if ((state as BasketActorState).basket.LineItems.Count > 100) { return(false); } // success return(true); } else if (command is RemoveLineItemFromBasketCommand) { return((state as BasketActorState).basket .LineItems .Exists(li => li.Id == (command as RemoveLineItemFromBasketCommand).LineItem.Id)); } throw new NotImplementedException($"Unable to handle {command}"); }
protected void Awake() { animator = GetComponent <Animator>(); currentState = defaultState; flags = 0; //animator.AnimationCompleted = AnimationEventCompleted; //animator.AnimationEventTriggered = AnimationEventCallback; }
protected void ReceivedTerminated(Terminated t) { if (!_state.ContainsTerminated(t.ActorRef)) return; _state = _state.RemoveTerminated(t.ActorRef); // here we know that it is the SAME ref which was put in ReceiveMessage(t); }
protected void OnEnable() { currentState = defaultState; flags = 0; #if DEBUG_ACTORS Debug.Log("Actor Enabled: " + name); #endif }
/// <summary> /// <see cref="RequestMove"/>メッセージを受信して移動を行う /// </summary> public static IDisposable ReceiveRequestMoveOnMove(this IActorState self, Func <float> moveSpeedSelector) { return(self.Owner.Broker.Receive <RequestMove>() .SubscribeWithState(self, (x, _this) => { _this.AddMove(x.Direction, moveSpeedSelector); }) .AddTo(self.Events)); }
/// <summary> /// <see cref="RequestJump"/>を受信したらジャンプを行う /// </summary> public static void ReceiveRequestJumpOnJump(this IActorState self) { self.Owner.Broker.Receive <RequestJump>() .SubscribeWithState(self, (_, _this) => { _this.InvokeJump(); }) .AddTo(self.Events); }
private void OnStateChangeEvent(IActorState previousState, IActorState nextState) { var handler = StateChangeEvent; if (handler != null) { handler(previousState, nextState); } }
protected void TransitionToState(IActorState nextState) { Log(string.Format(Time.frameCount + " {0} Going from {1} to {2}", this, CurrentState.Name, nextState.Name), this); CurrentState.OnExit(); OnStateChangeEvent(CurrentState, nextState); nextState.OnEnter(); CurrentState = nextState; StateName = CurrentState.Name; }
protected void ReceivedTerminated(Terminated t) { if (!_state.ContainsTerminated(t.ActorRef)) { return; } _state = _state.RemoveTerminated(t.ActorRef); // here we know that it is the SAME ref which was put in ReceiveMessage(t); }
/// <summary> /// ジャンプを実行する /// </summary> public static void InvokeJump(this IActorState self) { if (!self.Owner.StatusController.CanJump) { return; } self.Owner.StatusController.AddJumpCount(); self.Owner.Movement.SetGravity(Vector2.up * self.Owner.Context.BasicStatus.JumpPower); }
/// <summary> /// <see cref="RequestInvokeGameEvent"/>メッセージを受信してゲームイベントを実行する /// </summary> public static void ReceiveRequestInvokeGameEventOnInvokeGameEvent(this IActorState self) { self.Owner.Broker.Receive <RequestInvokeGameEvent>() .Where(_ => self.Owner.StatusController.GameEvent != null) .SubscribeWithState(self, (_, _this) => { _this.Owner.StatusController.GameEvent.Invoke(_this.Owner); }) .AddTo(self.Events); }
public override IActorState toNextState(EActorAction action) { IActorState result = null; if (action == EActorAction.HERO_IDLE) { result = new HeroActorState_Idle(actor); } return(result); }
private void StateChangeHandler(IActorState previous, IActorState next) { var attackState = next as AttackState; if (attackState != null) { _currentCombo = attackState.ComboCount; _hitbox.enabled = true; Invoke(() => _hitbox.enabled = false, attackState.HitDuration); } }
public async Task <string> WriteEvent(IActorState actor, string eventid, string parentEventid, object data) { if (EventLogHandler != null) { var result = await EventLogHandler.Write(actor, new EventLog { Data = data, DateTime = DateTime.Now, ActorPath = actor.ActorPath, EventPath = actor.EventPath, EventID = eventid, ParentEventID = parentEventid }); return(result); } return(null); }
protected override void StateChangeHandler(IActorState previous, IActorState next) { if (next is FallState) { Animator.SetTrigger("Fall"); } else if (next is GroundedState) { Animator.SetTrigger("Ground"); } else if (next is JumpAttackState) // must check attack first since Jump > JumpAttack { Animator.SetTrigger("JumpAttack"); } else if (next is AttackState) { var attackState = (AttackState)next; Animator.SetInteger("Combo", attackState.ComboCount); Animator.SetTrigger("Attack"); } else if (next is CriticalHurtState) // must check critical first since Hurt > CriticalHurt { Animator.SetTrigger("CriticalHurt"); } else if (next is HurtState) { Animator.SetTrigger("Hurt"); } else if (next is DeathState) { Animator.SetTrigger("Death"); } else if (next is DiveState) { Animator.SetTrigger("Dive"); } else if (next is StrikeGroundState) { Animator.SetTrigger("StrikeGround"); CameraShake.ScreenShake(1, 0.7f); } else if (next is PrepareJumpState) { Animator.SetTrigger("PrepareJump"); } else if (next is ChargeAttackState) { Animator.SetTrigger("Charge"); } else if (next is JumpState) { Animator.SetTrigger("Jump"); } }
public static void ReceiveRequestFallOneWayPlatforms(this IActorState self) { self.Owner.Broker.Receive <RequestFallOneWayPlatforms>() .Where(_ => self.Owner.Movement.IsGrounded) .SubscribeWithState(self, (_, _this) => { _this.Owner.Movement.IgnoreOneWayPlatformsThisFrame = true; _this.Owner.Movement.SetGravity(Vector2.down * 5.0f); }) .AddTo(self.Events); }
/// <summary> /// <see cref="RequestFire"/>メッセージを受信して<see cref="ActorState.Name.Attack"/>ステートへ遷移する /// </summary> public static void ReceiveRequestFireOnChangeAttackState(this IActorState self) { self.Owner.Broker.Receive <RequestFire>() .Where(x => !self.Owner.AbnormalConditionController.Contains(Constants.AbnormalStatus.Fear)) .Where(x => self.Owner.StatusController.EquippedWeapons[x.EquippedWeaponIndex].CanFire) .SubscribeWithState(self, (x, _this) => { _this.Owner.StateManager.Change(ActorState.Name.Attack, new StateAttackContext(x.EquippedWeaponIndex)); }) .AddTo(self.Events); }
public Actor(IPerson person, IPlayer owner, IMapNode node, IActorState state) { Person = person; Owner = owner; Node = node; State = state; if (state == null) { State = new ActorState(person.Hp); } }
/// <summary> /// <see cref="Actor"/>の向きを移動方向と同期を取る /// </summary> public static void SyncActorDirection(this IActorState self) { self.Owner.Broker.Receive <Move>() .SubscribeWithState(self, (x, _this) => { var direction = x.Velocity.GetHorizontalDirection(); Assert.AreNotEqual(direction, Constants.Direction.None); _this.Owner.StatusController.SetDirection(direction); _this.Owner.ModelController.Turn(x.Velocity.GetHorizontalDirection()); }) .AddTo(self.Events); }
public void Start(IActorState <T> state) { // The state machine should only be started once. This forces script developers to transition to new states through the return-based scene flow paradigm. if (_started) { Engine.Services.Get <Logger>().LogEvent("Error: State Machine already started for Actor " + this.Actor.Name + " with behavior definition " + this.Actor.Behavior?.GetType().Name, LogTypes.ERROR, new Exception("Error: State Machine already started for Actor " + this.Actor.Name + " with behavior definition " + this.Actor.Behavior?.GetType().Name)); return; } this.CurrentState = state; _started = true; }
public IActorRef Unwatch(IActorRef subject) { var a = (IInternalActorRef)subject; if (!a.Equals(Self) && WatchingContains(a)) { a.Tell(new Unwatch(a, Self)); MaintainAddressTerminatedSubscription(() => { _state = _state.RemoveWatching(a); }, a); } _state = _state.RemoveTerminated(a); return a; }
public override IActorState toNextState(EActorAction action) { IActorState result = null; if (action == EActorAction.HERO_ONAIR_UP) { result = new HeroActorState_OnAir_Up(actor); } else if (action == EActorAction.HERO_ONAIR_DOWN) { result = new HeroActorState_OnAir_Down(actor); } return(result); }
protected override bool ReceiveRecover(object message) { BasketActorState state; if (message is IEvent) UpdateState(message as IEvent); else if (message is SnapshotOffer && (state = ((SnapshotOffer)message).Snapshot as BasketActorState) != null) State = state; else if (message is RecoveryCompleted) Console.WriteLine($"{PersistenceId} Recovery Completed."); else return false; return true; }
public IActorRef Watch(IActorRef subject) { var a = (IInternalActorRef)subject; if (!a.Equals(Self) && !WatchingContains(a)) { MaintainAddressTerminatedSubscription(() => { a.Tell(new Watch(a, Self)); // ➡➡➡ NEVER SEND THE SAME SYSTEM MESSAGE OBJECT TO TWO ACTORS _state = _state.AddWatching(a); }, a); } return a; }
/// <summary> /// TBD /// </summary> /// <param name="subject">TBD</param> /// <returns>TBD</returns> public IActorRef Watch(IActorRef subject) { var a = (IInternalActorRef)subject; if (!a.Equals(Self) && !WatchingContains(a)) { MaintainAddressTerminatedSubscription(() => { a.SendSystemMessage(new Watch(a, _self)); // ➡➡➡ NEVER SEND THE SAME SYSTEM MESSAGE OBJECT TO TWO ACTORS _state = _state.AddWatching(a, Option <object> .None); }, a); } return(a); }
/// <summary> /// TBD /// </summary> /// <param name="subject">TBD</param> /// <returns>TBD</returns> public IActorRef Unwatch(IActorRef subject) { var a = (IInternalActorRef)subject; if (!a.Equals(Self) && WatchingContains(a)) { a.SendSystemMessage(new Unwatch(a, _self)); MaintainAddressTerminatedSubscription(() => { _state = _state.RemoveWatching(a); }, a); } (_state, _) = _state.RemoveTerminated(a); return(a); }
public void updataState(IActorAction action) { if (action.actiontype != EActorAction.NONE) { // Debug.Log("updataState - " + this.state + " by action:" + action.actiontype);//######## IActorState asCur = this.state; IActorState asNext = asCur.toNextState(action.actiontype); if (asNext != null) { this.state = asNext; this.action = action; this.state.OnEnter(); } } }
/// <summary> /// <see cref="Actor"/>を移動させる /// </summary> public static void AddMove(this IActorState self, Vector2 direction, Func <float> moveSpeedSelector) { var moveSpeed = moveSpeedSelector(); var velocity = Vector2.zero; if (direction.x != 0.0f) { velocity.x = direction.x > 0.0f ? moveSpeed : -moveSpeed; } if (direction.y != 0.0f) { velocity.y = direction.y > 0.0f ? moveSpeed : -moveSpeed; } self.Owner.Movement.AddMove(velocity * Time.deltaTime); }
public override IActorState toNextState(EActorAction action) { IActorState result = null; if (action == EActorAction.NPC_IDLE) { result = new NPCActorState_Idle(actor); } else if (action == EActorAction.NPC_WALK) { result = new NPCActorState_Walk(actor); } else if (action == EActorAction.NPC_DIE) { result = new NPCActorState_Die(actor); } return(result); }
public void Update(GameTime gameTime) { try { var nextState = this.CurrentState?.Update(gameTime, this.Actor); if (this.CurrentState != nextState) { this.CurrentState?.OnExit(this.Actor); this.CurrentState = nextState; this.CurrentState?.OnEnter(this.Actor); } } catch (Exception ex) { Engine.Services.Get <Logger>().LogEvent("Error: " + ex.Message, LogTypes.ERROR, ex); } }
/// <summary> /// TBD /// </summary> protected void TellWatchersWeDied() { var watchedBy = _state .GetWatchedBy() .ToList(); if (watchedBy.Count == 0) { return; } try { // Don't need to send to parent parent since it receives a DWN by default /* * It is important to notify the remote watchers first, otherwise RemoteDaemon might shut down, causing * the remoting to shut down as well. At this point Terminated messages to remote watchers are no longer * deliverable. * * The problematic case is: * 1. Terminated is sent to RemoteDaemon * 1a. RemoteDaemon is fast enough to notify the terminator actor in RemoteActorRefProvider * 1b. The terminator is fast enough to enqueue the shutdown command in the remoting * 2. Only at this point is the Terminated (to be sent remotely) enqueued in the mailbox of remoting * * If the remote watchers are notified first, then the mailbox of the Remoting will guarantee the correct order. */ foreach (var w in watchedBy) { SendTerminated(false, (IInternalActorRef)w); } foreach (var w in watchedBy) { SendTerminated(true, (IInternalActorRef)w); } } finally { MaintainAddressTerminatedSubscription(() => { _state = _state.ClearWatchedBy(); }); } }
/// <summary> /// When this actor is watching the subject of <see cref="Terminated"/> message /// it will be propagated to user's receive. /// </summary> protected void WatchedActorTerminated(IActorRef actor, bool existenceConfirmed, bool addressTerminated) { if (WatchingContains(actor)) { MaintainAddressTerminatedSubscription(() => { _state = _state.RemoveWatching(actor); }, actor); if (!IsTerminating) { Self.Tell(new Terminated(actor, existenceConfirmed, addressTerminated), actor); TerminatedQueuedFor(actor); } } if (ChildrenContainer.Contains(actor)) { HandleChildTerminated(actor); } }
/// <summary> /// TBD /// </summary> /// <param name="subject">TBD</param> /// <param name="message">TBD</param> /// <returns>TBD</returns> public IActorRef WatchWith(IActorRef subject, object message) { if (message == null) { throw new ArgumentNullException(nameof(message), "message must not be null"); } var a = (IInternalActorRef)subject; if (!a.Equals(Self) && !WatchingContains(a)) { MaintainAddressTerminatedSubscription(() => { a.SendSystemMessage(new Watch(a, _self)); // ➡➡➡ NEVER SEND THE SAME SYSTEM MESSAGE OBJECT TO TWO ACTORS _state = _state.AddWatching(a, message); }, a); } return(a); }
public static bool Handle(IActorState state, ICommand command) { if (command is CreateBasketCommand) { return true; } else if (command is AddLineItemToBasketCommand) { // Validate and do side effects if ((state as BasketActorState).basket.LineItems.Count > 100) return false; // success return true; } else if (command is RemoveLineItemFromBasketCommand) { return (state as BasketActorState).basket .LineItems .Exists(li => li.Id == (command as RemoveLineItemFromBasketCommand).LineItem.Id); } throw new NotImplementedException($"Unable to handle {command}"); }
protected void TellWatchersWeDied() { var watchedBy = _state .GetWatchedBy() .ToList(); if (!watchedBy.Any()) return; try { // Don't need to send to parent parent since it receives a DWN by default /* * It is important to notify the remote watchers first, otherwise RemoteDaemon might shut down, causing * the remoting to shut down as well. At this point Terminated messages to remote watchers are no longer * deliverable. * * The problematic case is: * 1. Terminated is sent to RemoteDaemon * 1a. RemoteDaemon is fast enough to notify the terminator actor in RemoteActorRefProvider * 1b. The terminator is fast enough to enqueue the shutdown command in the remoting * 2. Only at this point is the Terminated (to be sent remotely) enqueued in the mailbox of remoting * * If the remote watchers are notified first, then the mailbox of the Remoting will guarantee the correct order. */ foreach (var w in watchedBy) SendTerminated(false, w); foreach (var w in watchedBy) SendTerminated(true, w); } finally { _state = _state.ClearWatching(); } }
public void TerminatedQueuedFor(IActorRef subject) { _state = _state.AddTerminated(subject); }
public BasketActor(string id) { State = new BasketActorState(); (State as BasketActorState).basket.Id = id; PersistenceId = id; }
public void UpdateState(IEvent evt) { State = (State as BasketActorState).Update(evt); }
protected void AddressTerminated(Address address) { // cleanup watchedBy since we know they are dead MaintainAddressTerminatedSubscription(() => { foreach (var a in _state.GetWatchedBy().Where(a => a.Path.Address == address).ToList()) { //_watchedBy.Remove(a); _state = _state.RemoveWatchedBy(a); } }); // send DeathWatchNotification to self for all matching subjects // that are not child with existenceConfirmed = false because we could have been watching a // non-local ActorRef that had never resolved before the other node went down // When a parent is watching a child and it terminates due to AddressTerminated // it is removed by sending DeathWatchNotification with existenceConfirmed = true to support // immediate creation of child with same name. foreach (var a in _state.GetWatching().Where(a => a.Path.Address == address)) { Self.Tell(new DeathWatchNotification(a, true /*TODO: childrenRefs.getByRef(a).isDefined*/, true)); } }
protected void RemWatcher(IActorRef watchee, IActorRef watcher) { var watcheeSelf = watchee.Equals(Self); var watcherSelf = watcher.Equals(Self); if (watcheeSelf && !watcherSelf) { if (_state.ContainsWatchedBy(watcher)) MaintainAddressTerminatedSubscription(() => { //_watchedBy.Remove(watcher); _state = _state.RemoveWatchedBy(watcher); if (System.Settings.DebugLifecycle) Publish(new Debug(Self.Path.ToString(), Actor.GetType(), string.Format("no longer watched by {0}", watcher))); }, watcher); } else if (!watcheeSelf && watcherSelf) { Unwatch(watchee); } else { Publish(new Warning(Self.Path.ToString(), Actor.GetType(), string.Format("BUG: illegal Unwatch({0},{1} for {2}", watchee, watcher, Self))); } }
protected void UnwatchWatchedActors(ActorBase actor) { var watching = _state .GetWatching() .ToList(); if (!watching.Any()) return; MaintainAddressTerminatedSubscription(() => { try { // ➡➡➡ NEVER SEND THE SAME SYSTEM MESSAGE OBJECT TO TWO ACTORS foreach (var watchee in watching.OfType<IInternalActorRef>()) watchee.Tell(new Unwatch(watchee, Self)); } finally { _state = _state.ClearWatching(); _state = _state.ClearTerminated(); } }); }
public void updataState(IActorAction action) { if(action.actiontype != EFSMAction.NONE){ // Debug.Log("updataState - " + this.state + " by action:" + action.actiontype);//######## IActorState asCur = this.state; IActorState asNext = asCur.toNextState(action.actiontype); if (asNext != null) { this.state = asNext; this.action = action; this.state.OnEnter(); } } }