private void ReadTask()
        {
            while (!_cancelTokenSource.Token.IsCancellationRequested)
            {
                //check if data is available
                if (_dataWaitHandle.WaitOne(0, false))
                {
                    var result = _serialPort.ReadLine();
                    OnLine?.Invoke(result.AsSpan());
                    _dataWaitHandle.Reset();
                }

                WaitHandle.WaitAny(new WaitHandle[] { _dataWaitHandle, _cancelTokenSource.Token.WaitHandle });
            }
        }
Beispiel #2
0
        /// <summary>
        /// Progress the story using the given input.
        /// This yields line data from internal dialogue runner, whose data is passed via invoking actions.
        /// If delayed next was called previously, this runner is current waiting for that to finish and won't run the next line.
        /// </summary>
        /// <param name="input"></param>
        public static LineTag Next(string input = "", bool auto = false)
        {
#if UNITY_EDITOR
            string caller = (new System.Diagnostics.StackTrace()).GetFrame(auto ? 2 : 1).GetMethod().Name;
            Debug.Log($"Kataru.Runner.Next('{input}') from {caller}.");
#endif
            if (isWaiting)
            {
#if UNITY_EDITOR
                Debug.LogWarning($@"Called Runner.Next while runner was busy waiting.
                                    Don't call Runner.Next until Runner.DelayedNext has finished.");
#endif
                return(LineTag.End);
            }

            FFI.Next(input);
            Tag = FFI.Tag();
#if UNITY_EDITOR
            Debug.Log($"Tag: {Tag}");
#endif
            switch (Tag)
            {
            case LineTag.Choices:
                OnChoices.Invoke(FFI.LoadChoices());
                break;

            case LineTag.InvalidChoice:
                OnInvalidChoice.Invoke();
                break;

            case LineTag.Dialogue:
                Dialogue dialogue = FFI.LoadDialogue();
#if UNITY_EDITOR
                Debug.Log($"{dialogue.name}: '{dialogue.text}'");
#endif
                CharacterDelegates.Invoke(dialogue.name, new object[] { dialogue });
                break;

            case LineTag.Command:
                Command command = FFI.GetCommand();
#if UNITY_EDITOR
                Debug.Log($"Calling command '{command.name}'");
                if (string.IsNullOrEmpty(command.name))
                {
                    throw new KeyNotFoundException($"Received empty Kataru command. Did you use a global command as a character command?");
                }
#endif
                ConcurrentDictionary <Delegate, bool> delegates;
                if (CommandDelegates.TryGetValue(command.name, out delegates))
                {
                    object[] @params = new object[] { };
                    foreach (var @delegate in delegates.Keys)
                    {
                        @params = command.Params(@delegate.Method);
                        break;
                    }
                    CommandDelegates.Invoke(command.name, @params);
                }
                else
                {
                    throw new KeyNotFoundException($"No Kataru command named '{command.name}' was registered in Unity. Are you missing a command definition, attribute, or reference?");
                }
                break;

            case LineTag.InputCommand:
                OnInputCommand?.Invoke(FFI.LoadInputCommand());
                break;

            case LineTag.End:
                Exit();
                break;
            }
            OnLine?.Invoke(Tag);
            return(Tag);
        }