/// <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);
 }
Example #9
0
    private void OnStateChangeEvent(IActorState previousState, IActorState nextState)
    {
        var handler = StateChangeEvent;

        if (handler != null)
        {
            handler(previousState, nextState);
        }
    }
Example #10
0
    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;
    }
Example #11
0
        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);
 }
Example #14
0
    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);
        }
    }
Example #16
0
        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);
 }
Example #20
0
        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);
 }
Example #22
0
        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;
 }
Example #24
0
    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;
        }
Example #27
0
        /// <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);
        }
Example #28
0
        /// <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);
        }
Example #29
0
    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);
        }
Example #31
0
    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);
    }
Example #32
0
        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);
     }
 }
Example #35
0
        /// <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();
                }
            });
        }
Example #44
0
 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();
         }
     }
 }