連想配列を楽に実装

PureNScripterで擬似ハッシュ - 永字八法の続き。
今度はLuaを使ってみる。
前提として、json.luaを使う。
http://www.chipmunkav.com/downloads/Json.lua
このファイルを、nscr.exeと同じフォルダに"json.lua"の名前で保存しておくこと。文字コードはShift-JISで。
なお、前回と違って何を放りこんでも問題がないのが実に素敵。
また、キャッシュ機能を実装しているので、大量に動かしてもそれなりに速度は出る。
loadgosubの時には、cache_clear()関数を実行しておくべき。

system.lua

この内容を、どっか適当に書く。

-- json
NL_dofile("Json.lua")
do

	local json_cache = {}
	function cache_clear()
		json_cache = {}
	end
	
	function get_json_object(num)
		if type(json_cache[num])=="nil" then
			local str = NSGetStrValue(num)
			if str:len()==0 then
				json_cache[num] = {}
			else
				json_cache[num] = Json.Decode(str)
			end
		end
		return json_cache[num]
	end

	function set_json_object(num)
		NSSetStrValue(num, Json.Encode(json_cache[num]))
	end

	function get_object_and_param_and_value()
		-- オブジェクトの取得
		local ob_num = NSPopStrRef()
		local ob = get_json_object(ob_num)
		
		-- パラメータの取得
		NSPopComma()
		local param = NSPopStr()
		
		-- 現在値の取得
		local now_value
		if type(ob[param])=="nil" then
			if mode2 then -- int
				now_value = 0
			else -- str
				now_value = ""
			end
		else
			if mode2 then -- int
				now_value = tonumber(ob[param])
			else -- str
				now_value = ob[param]
			end
		end
		return ob_num, ob, param, now_value
	end

	function json_main(mode1, mode2) -- mode1はget/set, mode2はint/str
		local ob_num, ob, param, now_value = get_object_and_param_and_value()
		NSPopComma()
		if mode1 then -- set
			if mode2 then -- int
				ob[param] = tostring(NSPopInt())
			else -- str
				ob[param] = NSPopStr()
			end
			set_json_object(ob_num)
		else -- get
			if mode2 then -- int
				NSSetIntValue(NSPopIntRef(), now_value)
			else -- str
				NSSetStrValue(NSPopStrRef(), now_value)
			end
		end
	end

	function json_main2(mode1) -- mode1はexist/delete
		local ob_num, ob, param, now_value = get_object_and_param_and_value()
		if mode1 then -- exist
			NSPopComma()
			local res = NSPopIntRef()
			if type(ob[param])=="nil" then
				NSSetIntValue(res, 0)
			else
				NSSetIntValue(res, 1)
			end
		else -- delete
			ob[param] = nil
			set_json_object(ob_num)
		end
	end

	NSExec("luasub getint")
	NSExec("luasub getstr")
	NSExec("luasub setint")
	NSExec("luasub setstr")
	NSExec("luasub exist_param")
	NSExec("luasub delete_param")

	function NSCOM_getint() json_main(false, true, true) end
	function NSCOM_getstr() json_main(false, false, true) end
	function NSCOM_setint() json_main(true, true, true) end
	function NSCOM_setstr() json_main(true, false, true) end
	function NSCOM_exist_param() json_main2(true) end
	function NSCOM_delete_param() json_main2(false) end
end

これで準備完了

解説

使い方は前回と同じ。加えて、二つの命令を追加した。
exist_paramとdelete_param。
前者はあるオブジェクトにあるパラメータがあるかどうかを調べる。引数は、「オブジェクトの文字列変数,パラメータ名,結果を受け取る数値変数」
後者はあるオブジェクトからあるパラメータを完全に削除する。引数は、「オブジェクトの文字列変数,消したいパラメータ名」

サンプルスクリプト

00.txt

*define
deletemenu
game
*start

setint $100,"north",50
setstr $100,"south","うまくいったかな?"

mesbox $100,"$100"

getstr $100,"south",$50
mesbox $50,"$50"

exist_param $100,"north",%0
%0
exist_param $100,"west",%1
%1

delete_param $100,"north"
mesbox $100,"$100"

end