我在C#中有一個虛擬機,它有兩個構造函數重載,五個事件處理函數和兩個公共屬性。我已經將這個虛擬機集成到了WinForms和Silverlight應用程序中,甚至可以在客戶端/服務器設置中將其用作Web應用程序。在WinRT中集成虛擬機
界面如下:
構造
public Engine(Stream gameFile) { .. }
public Engine(Stream gameFile, Stream saveFile) { .. }
活動
public OutputReady(object sender, OutputReadyEventArgs e);
public LineWanted(object sender, LineWantedEventArgs e);
public KeyWanted(object sender, KeyWantedEventArgs e);
public SaveRequested(object sender, SaveRestoreEventArgs e);
public LoadRequested(object sender, SaveRestoreEventArgs e);
屬性
public Dictionary<string, string> ChanneData { get; set; }
public byte[] SaveData { get; set; }
當WinForms和Silverlight中實現這一點,我不得不使用Invoke或類似的方法寫入UI線程。
在WinRT中,UI和後臺線程之間的切換隱藏在異步/等待和任務處理的後面,並且我還沒有真正能夠以我想要的方式移植我的虛擬機....作爲服務。
我可以在我的應用程序的MainForm中嵌入虛擬機,就像我在Silverlight中完成的那樣,但是我想要更多的MVC/Service實現。我想將虛擬機移除到一個具有簡單界面的服務,用於啓動遊戲,發送新命令,保存遊戲和加載遊戲。 MainForm不應該知道有關vm實現的任何信息。
我已經解決了這個問題超過了幾個小時,但仍然沒有足夠清楚的理解async/await和Tasks來完成它,以便它能正常工作。我可以讓引擎啓動併發送命令,但保存和加載失敗,我認爲這是因爲異步的東西無法正常工作。
的WinForms簡單的實現:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Threading;
using FyreVM;
namespace FyreVMTest
{
public partial class MainForm : Form
{
private Thread vmThread = null;
private Engine vm = null;
private AutoResetEvent inputReadyEvent = new AutoResetEvent(false);
private string command = "";
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
Assembly assembly = Assembly.GetExecutingAssembly();
Stream stream =
assembly.GetManifestResourceStream("FyreVMTest.Game.shadow-w8.ulx");
vm = new Engine(stream);
vm.KeyWanted += vm_KeyWanted;
vm.LineWanted += vm_LineWanted;
vm.LoadRequested += vm_LoadRequested;
vm.OutputReady += vm_OutputReady;
vm.SaveRequested += vm_SaveRequested;
vmThread = new Thread(VMThreadProc);
vmThread.IsBackground = true;
vmThread.Start();
}
private void VMThreadProc(object dummy)
{
try
{
vm.Run();
this.Invoke(new Action(GameFinished));
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void GameFinished()
{
this.Close();
}
private void RequestLine()
{
CommandLine.Focus();
}
private void vm_LineWanted(object sender, LineWantedEventArgs e)
{
this.Invoke(new Action(RequestLine));
inputReadyEvent.WaitOne();
e.Line = command;
}
private void vm_KeyWanted(object sender, KeyWantedEventArgs e)
{
//this.Invoke(new Action(RequestKey));
//inputReadyEvent.WaitOne();
//e.Char = entry[0];
}
private void vm_OutputReady(object sender, OutputReadyEventArgs e)
{
this.Invoke(new Action<Dictionary<string,string>>(HandleOutput), e.Package);
}
private void vm_SaveRequested(object sender, SaveRestoreEventArgs e)
{
e.Stream = (Stream)this.Invoke(new Func<Stream>(RequestSaveStream));
}
private void vm_LoadRequested(object sender, SaveRestoreEventArgs e)
{
e.Stream = (Stream)this.Invoke(new Func<Stream>(RequestLoadStream));
}
private Stream RequestSaveStream()
{
using (SaveFileDialog dlg = new SaveFileDialog())
{
dlg.Title = "Select Save File";
dlg.Filter = "Textfyre save files (*.tfq)|*.tfq";
if (dlg.ShowDialog() == DialogResult.Cancel)
return null;
else
{
return new FileStream(dlg.FileName,
FileMode.Create,FileAccess.Write);
}
}
}
private Stream RequestLoadStream()
{
using (OpenFileDialog dlg = new OpenFileDialog())
{
dlg.Title = "Load a Saved Game";
dlg.Filter = "Textfyre save files (*.tfq)|*.tfq";
if (dlg.ShowDialog() == DialogResult.Cancel)
return null;
else
{
return new FileStream(dlg.FileName, FileMode.Open, FileAccess.Read);
}
}
}
private void HandleOutput(Dictionary<string, string> package)
{
MainOutput.Clear();
foreach (string key in package.Keys)
{
MainOutput.AppendText(key + ": " + package[key]);
}
}
private void GoButton_Click(object sender, EventArgs e)
{
command = CommandLine.Text;
CommandLine.Text = "";
inputReadyEvent.Set();
}
}
}
所以我正在尋找指導如何實現這個在WinRT中。接口是一個問題,還是我需要將其更改爲WinRT更友好?如果沒關係,在一個類中實現它的最好方法是什麼,然後如何從MainForm調用該類?
任何指導非常感謝。
如果有幫助,一個示例非工作項目在這裏:https://github.com/ChicagoDave/FyreXaml/ –