1.目的
スクリプト言語からC#で実装したモーター制御、通信、描画、入出力処理を制御し、 複数の期待に柔軟に対応できるアプリケーションづくりを支援する。
想定する使い方はたとえば次の通り。
-- 画面に文字を描画
screen = Screen.new();
screen.textOut("sample");
-- 文字の大きさを変更
screen.setFontSize(20);
-- 描画する位置を指定
screen.setPosition(100, 100);
-- 枠を描画
screen.drawRectangle(10, 10, 100, 100);
-- ボードの生成
board = {};
board[1] = PWMBoard.new();
board[2] = RotaryEncoderBoard.new();
-- ボードへ出力
t = board[1];
t:setPosition(2, 500); -- 出力2を50%にする
t:setPosition(3, 100); -- 出力3を10%にする
t:send(); -- データを送信する
-- ボードから入力
t = board[2];
t:recieve();
screen.textOut(t:getPosition());
-- コントローラからの入力受付
function onControllerInput(status) {
if status.maru then
MessageBox.show("○が押された");
end
}
-- 1フレームごと呼び出される関数
function onFrame() {
-- 描画処理など
}
2. 使い方
先ほどのページのREADME.mdの中のWin32: Downloadよりダウンロードし、展開する。中にある3つのDLLのうちNLua.dllを参照に追加し、残り2つは実行ファイルと同じディレクトリに入れる。
3. 使用例
たとえばコンソール画面を次のように操作できるプログラムをC#で作る。
・8x8の画面上に適当なマークが設置できるようになっている。
・現在の位置はハイライトされる。
・メニューと称して、適当な数のアイテムから1つ選ぶことができる。
・ステータスと称して、画面の下にメッセージを表示できる。
using System; using NLua; using System.Collections.Generic; namespace cstest { public class Board { const int max_size = 8; string[] put_chars; public Board(NLua.Lua lua) { x = 0; y = 0; this.lua = lua; menu_mode = false; lua["MenuMode"] = false; menu_position = 0; menu_list = new List<Tuple<string, LuaFunction>>(); menu_size = 0; data = new int[max_size, max_size]; put_chars = new string[] { " ", "○", "×", "☆" }; for (int iy = 0; iy < max_size; ++iy) { for (int ix = 0; ix < max_size; ++ix) { data[ix, iy] = 0; } } } public void Show() { Console.Clear(); for (int iy = 0; iy < max_size; ++iy) { for (int ix = 0; ix < max_size; ++ix) { var t = data[ix, iy]; if (t < 0 || t >= 4) { throw new Exception(); } if(ix == x && iy == y) { Console.BackgroundColor = ConsoleColor.Gray; Console.ForegroundColor = ConsoleColor.White; } else { Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.White; } Console.Write(put_chars[t]); Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.White; } Console.WriteLine(); } if (menu_mode) { DrawMenu(); } Console.SetCursorPosition(0, max_size); Console.WriteLine(status_message); } public void Move(int x, int y) { this.x = x; this.y = y; } public void Put(int type) { data[x, y] = type; } public string Read() { return Console.ReadKey(true).Key.ToString(); } public void SetMenuList(NLua.LuaTable name_list, NLua.LuaTable event_list) { string name; LuaFunction func; int i = 1; menu_list.Clear(); while ((name = (string)name_list[i]) != null && (func = (LuaFunction)event_list[i]) != null) { menu_list.Add(new Tuple<string, LuaFunction>(name, func)); ++i; } menu_size = i - 1; } public void ShowMenu() { menu_mode = true; lua["MenuMode"] = true; DrawMenu(); } public void MenuPositionUp() { if (menu_position > 0) { --menu_position; } } public void MenuPositionDown() { ++menu_position; if (menu_position >= menu_size) { menu_position = menu_size - 1; } } public void CloseMenu() { menu_mode = false; lua["MenuMode"] = false; Show(); } public void MenuExecute() { LuaFunction func = menu_list[menu_position].Item2; func.Call(menu_position + 1); } public void ShowMessage(string str) { status_message = str; Console.SetCursorPosition(0, max_size); Console.WriteLine(str); } private void DrawMenu() { int i = 0; foreach (var item in menu_list) { Console.SetCursorPosition(max_size * 2, 2 + i); Console.Write("・"); if (i == menu_position) { Console.BackgroundColor = ConsoleColor.Blue; Console.ForegroundColor = ConsoleColor.White; } else { Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.White; } Console.Write(item.Item1); Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.White; ++i; } } private bool menu_mode; private int menu_position; private List<Tuple<string, LuaFunction>> menu_list; private int menu_size; private string status_message; private int x; private int y; private int[,] data; private NLua.Lua lua; } class Program { static void Main(string[] args) { NLua.Lua lua = new NLua.Lua(); Board board = new Board(lua); lua.RegisterFunction("Read", board, typeof(Board).GetMethod("Read")); lua.RegisterFunction("Put", board, typeof(Board).GetMethod("Put")); lua.RegisterFunction("Move", board, typeof(Board).GetMethod("Move")); lua.RegisterFunction("SetMenuList", board, typeof(Board).GetMethod("SetMenuList")); lua.RegisterFunction("ShowMenu", board, typeof(Board).GetMethod("ShowMenu")); lua.RegisterFunction("CloseMenu", board, typeof(Board).GetMethod("CloseMenu")); lua.RegisterFunction("MenuPositionUp", board, typeof(Board).GetMethod("MenuPositionUp")); lua.RegisterFunction("MenuPositionDown", board, typeof(Board).GetMethod("MenuPositionDown")); lua.RegisterFunction("MenuExecute", board, typeof(Board).GetMethod("MenuExecute")); lua.RegisterFunction("ShowMessage", board, typeof(Board).GetMethod("ShowMessage")); lua.RegisterFunction("Show", board, typeof(Board).GetMethod("Show")); lua.DoFile("./test.lua"); LuaFunction func = lua.GetFunction("onKey"); while(true) { string key = Console.ReadKey(true).Key.ToString(); func.Call(key); } lua.Close(); } } }そしてLua側から次のように制御する。
function F1(no) Mode = 0; ShowMessage("移動"); end function F2(no) Mode = 1; PutType = 0; ShowMessage("設置"); end function F3(no) ShowMessage(""); end function onKey(key) if MenuMode then if key == "DownArrow" then MenuPositionDown(); Show(); elseif key == "UpArrow" then MenuPositionUp(); Show(); elseif key == "Enter" then MenuExecute(); CloseMenu(); end elseif Mode == 0 then if key == "DownArrow" then pos_y = pos_y + 1; elseif key == "UpArrow" then pos_y = pos_y - 1; elseif key == "LeftArrow" then pos_x = pos_x - 1; elseif key == "RightArrow" then pos_x = pos_x + 1; elseif key == "Enter" then ShowMessage("移動終了"); Mode = -1; end Move(pos_x, pos_y); Show(); elseif Mode == 1 then if key == "DownArrow" then PutType = PutType + 1; elseif key == "UpArrow" then PutType = PutType - 1; elseif key == "Enter" then ShowMessage("設置終了"); Put(PutType); Mode = -1; end if PutType < 0 then PutType = 0; elseif PutType > 3 then PutType = 3; end Put(PutType); Show(); else if key == "M" then ShowMenu(); else print("KEY:" .. key); end end end Mode = -1; pos_x = 0; pos_y = 0; name_list = { "移動", "設置", "閉じる" }; event_list = { F1, F2, F3 }; SetMenuList(name_list, event_list);
0 件のコメント:
コメントを投稿