NScripterで連想配列を使えるようにする
Luaのテーブル変数をNScripterの文字列変数に圧縮・その逆の展開 - 永字八法とNSPopID()の実験 - 永字八法の続き。
使い方
onew %0 ; 新規連想配列を取得し、そのIDを%0に収める。 oset %0,file,"a.jpg" ; 連想配列のfileプロパティに、"a.jpg"を設定する。 oset %0,width,300,height,200 ; 連想配列のwidthプロパティとheightプロパティに数値を設定する。 osave %0 ; その連想配列を、一行にまとめて文字列変数に格納する。文字列変数の番号は、連想配列のIDに等しい。 oload %0 ; 一行にまとめた文字列を、連想配列に展開する。$1500を展開したなら、その連想配列のIDは1500になる。
特色
- osetメソッドとogetメソッドは、遅延引数取得を利用して不定長引数を実現している。一度に複数のプロパティを指定したい時は、その分だけどんどんつなげて伸ばせばいい。
- どちらも、プロパティを指定する時はダブルクォートでプロパティ名を囲まない。逆に囲むとエラーになる。
- プロパティは「0文字以上の、アルファベットで始まる制御記号を含まない半角文字の集合」と規定する。
- luacallを使っているので、saveやloadにも対応している……はず。
- key_typeテーブルに、あるプロパティがどんなデータ型を持っているかを記述し、それによって使う引数取得命令を変更する。月見 - senzogawaのNな日々で指摘されている「型混在の命令」に対する不完全な解答。
00.txt
*define luacall savepoint luacall load luasub onew luasub oget luasub oset luasub osave luasub oload game *start csvopen "dump.txt","w" onew %0 %0:$%0 csvwrite $%0 oset %0,width,200,height,300 oset %0,file,"a013.jpg" %0:$%0 csvwrite $%0 osave %0 %0:$%0 csvwrite $%0 oget %0,file,$0 $0 click end
system.lua
local objs = {} local obj_start = 1000 local obj_end = 2000 function NSCALL_savepoint() for num, obj in pairs(objs) do if obj.is_changed == true then obj_save(obj) end end return true end function NSCOM_osave() local num = NSPopInt() local obj = obj_load(num) if obj.is_changed == true then obj_save(obj) end end function obj_save(obj) local str = "" obj.is_changed = nil for key, value in pairs(obj) do str = str .. key .. "\t" .. value .. "\t" end NSSetStrValue(obj.id, str) obj.is_changed = false return true end function NSCALL_load(save_num) local str = "" for num = obj_start, obj_end do str = NSGetStrValue(num) if str ~= "" then obj_load(num) end end return true end function NSCOM_oload() local obj = obj_load(NSPopInt()) end function obj_load(num) local temp = objs[num] if temp ~= nil then return temp end temp = {} local str = "" str = NSGetStrValue(num) if str ~= "" then for key, value in string.gmatch(str, "([^\t]*)[\t]([^\t]*)[\t]") do temp[key] = value end end temp.id = num objs[num] = temp if str == "" then obj_save(temp) end return temp end function NSCOM_onew() NSSetIntValue(NSPopIntRef(), onew()) end function onew() local num = obj_start while NSGetStrValue(num) ~= "" do num = num + 1 end obj_load(num) return num end local key_type = { width = "number", height = "number", x = "number", y = "number" } function NSCOM_oset() local num = NSPopInt() local obj = obj_load(num) local key = "" local value = "" while NSCheckComma() == true do NSPopComma() key = NSPopID() NSPopComma() if key_type[key] == "number" then value = NSPopInt() else value = NSPopStr() end obj[key] = value end obj.is_changed = true end function NSCOM_oget() local num = NSPopInt() local obj = obj_load(num) local key = "" local res = 0 while NSCheckComma() == true do NSPopComma() key = NSPopID() NSPopComma() if key_type[key] == "number" then res = NSPopIntRef() NSSetIntValue(res, obj[key]) else res = NSPopStrRef() NSSetStrValue(res, obj[key]) end end end