public LuaAsyncAction Then(Action action)
        {
            var newAction = new LuaAsyncAction(action, _runner);

            Chained = newAction;
            return(newAction);
        }
        public LuaAsyncAction Do(Action action)
        {
            var actionObj = new LuaAsyncAction(action, this);

            _rootAction    = actionObj;
            _currentAction = _rootAction;
            return(actionObj);
        }
        private IEnumerator runActions()
        {
            _currentAction = _rootAction;
            while (true)
            {
                // if we're at the end
                if (_currentAction == null)
                {
                    if (_looping)
                    {
                        // if we're looping then start from the beginning again
                        _currentAction = _rootAction;
                    }
                    else
                    {
                        // otherwise simply stop running
                        stopRunning();
                        break;
                    }
                }

                // perform the action
                _currentAction.Action?.Invoke();

                // if we have a predicate, we need to check if it's satisfied or not
                if (_currentAction.UntilPredicate != null && !_currentAction.UntilPredicate.Predicate())
                {
                    // defer execution, we need to wait until the predicate is satisfied
                    yield return(null);

                    continue;
                }

                // if we didn't have a predicate, or if we had a predicate and it was satisfied, then we can move to
                // the next action
                switchToAction(_currentAction.Chained);
            }
        }
 private void switchToAction(LuaAsyncAction next)
 {
     _currentAction = next;
     next?.UntilPredicate?.Begin();
 }