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 件のコメント:
コメントを投稿