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
{
}
}
// (略)
※名前空間は適宜調整してください。