LoginSignup
0
1

BVE 車掌の動作を取得する

Last updated at Posted at 2023-09-24

 BVEのATSプラグインがBVE本体から渡されるイベントは、車両になにか変化があったイベントのみであり、車掌の動作のイベントはない。
 しかし、プレイ中には見ることのできないBVEの標準出力には車掌の動作が出力されている。
 すなわち、プラグインがBVEの標準出力を乗っ取r(ry 取得すれば、車掌の動作による制御を実装することができる。

 Loadイベント後に取得できる標準出力内容は、現在のところ確認できているのは、「発車ベル: ON」「車掌: 停止位置よし」「車掌スイッチ: 開」「車掌スイッチ: 閉」「側灯滅」の5つ。
※非公式の機能のため、将来的に変更・廃止になる可能性がある。

1.BVEの標準出力を取得する

using System;
using System.ComponentModel;
using System.IO;
using System.Text;

namespace AtsPlugin.Core.Engine
{
    public class StdOut
    {
        // 標準出力に再出力するか?
        public bool Redirect { get; set; }
        // 標準出力
        TextWriter Console_StdOut { get; set; }
        // BVE標準出力の乗っ取り先
        StringWriter Bve_StdOut { get; set; }
        StringBuilder Bve_StdOut_StringBuilder { get; set; }
        // 実行間隔
        int Interval { get; set; } = 10;

        private BackgroundWorker bgWorker1 = new BackgroundWorker();

        //TimeEventArgs型のオブジェクトを返すようにする
        public delegate void StdOutRcvMessageEventHandler(object sender, StdOutRcvMessageEventArgs e);

        //イベントデリゲートの宣言
        public event StdOutRcvMessageEventHandler ReceiveMessage;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public StdOut()
        {
            Console_StdOut = Console.Out;
            Bve_StdOut = new StringWriter();
            Bve_StdOut_StringBuilder = Bve_StdOut.GetStringBuilder();
            Console.SetOut(Bve_StdOut);

            bgWorker1 = new BackgroundWorker();
            // キャンセル許可
            bgWorker1.WorkerSupportsCancellation = true;
            // ハンドラ
            bgWorker1.DoWork += new DoWorkEventHandler(bgWorker1_DoWork);
            bgWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker1_RunWorkerCompleted);

            bgWorker1.RunWorkerAsync();
        }

        public void Dispose()
        {
            if (bgWorker1.IsBusy)
            {
                bgWorker1.CancelAsync();
            }
            bgWorker1.Dispose();
        }

        private void bgWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            for(; ; )
            {
                if (worker.CancellationPending == true)
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    if (Bve_StdOut_StringBuilder.Length > 0)
                    {
                        string s = Bve_StdOut_StringBuilder.ToString();
                        Bve_StdOut_StringBuilder.Remove(0, Bve_StdOut_StringBuilder.Length);

                        //返すデータの設定
                        StdOutRcvMessageEventArgs e2 = new StdOutRcvMessageEventArgs();
                        e2.Message = s.Replace("\n", "").Replace("\r", "");
                        //イベントの発生
                        OnReceiveMessage(e2);

                        if (Redirect == true) Console_StdOut.Write(s);
                    }
                    System.Threading.Thread.Sleep(Interval);
                }
            }
        }

        private void bgWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {
              // キャンセルされた
            }
            else if (e.Error != null)
            {
              // エラーがあった
            }
            else
            {
              // 無事終了
            }
        }


        #region イベントクラス
        public class StdOutRcvMessageEventArgs : EventArgs
        {
            public string Message;
        }


        protected virtual void OnReceiveMessage(StdOutRcvMessageEventArgs e)
        {
            if (ReceiveMessage != null)
            {
                ReceiveMessage(this, e);
            }
        }
        #endregion

    }
}

2.実装する

namespace AtsPlugin.Core
{
  public class AtsMain
  {
    // 定義
    // BVE標準出力取得クラスのインスタンス
    private Engine.StdOut STD;

// (略)

    // Loadイベント内
    public void Load()
    {
      // (略)
      STD = new Engine.StdOut();
      // BVE標準出力に変化があったときに呼ばれるイベント
      STD.ReceiveMessage += new Engine.StdOut.StdOutRcvMessageEventHandler(this.CheckStdOut);
      // (略)
    }

    // お呼ばれされる関数
    private void CheckStdOut(object sender, Engine.StdOut.StdOutRcvMessageEventArgs e)
    {
      try
      {
        switch (e.Message)
        {
          case "発車ベル: ON":
            // 車掌が発車ベルを鳴らした際
            break;
          case "車掌: 停止位置よし":
            break;
          case "車掌スイッチ: 開":
            // 車掌が戸開け操作を開始した際
            break;
          case "車掌スイッチ: 閉":
            // 車掌が戸締め操作を開始した際
            break;
          case "側灯滅":
            break;
          default:
            break;
        }
      }
      catch
      {

      }
    }

// (略)

※名前空間は適宜調整してください。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1