module("message", package.seeall) FOO = 1 BAR = 2 BAZ = 3 ALPHA = 1 BETA = 2 GAMMA = 3 -- NULLメッセージ(インタフェースはあるが中身がないメッセージ)をつくる function create_null_message() local result = { protocol = "null", type = "null" } function result:load(sequence) end function result:dispatch(receiver) end return result end -- 基本形のメッセージをつくる function create_message(protocol) local result = { ["protocol"] = protocol } -- ディスパッチ関数の定義 -- receiver:protocol_type_receivedという名前の関数を呼び出す function result:dispatch(receiver) if receiver then local f = receiver[self.protocol .. "_" .. self.type .. "_received"] if not f then f = receiver["default_received"] if not f then f = function(x, y) end end end f(receiver, self) end end return result end -- sequence から protocol foo のメッセージを作る関数群 function load_foo_alpha(self, sequence) self.type = "alpha" end function load_foo_beta(self, sequence) self.type = "beta" end function load_foo_gamma(self, sequence) self.type = "gamma" end function load_foo(sequence) local foo = create_message("foo") local type = sequence:byte(2) if type == ALPHA then foo.load = load_foo_alpha elseif type == BETA then foo.load = load_foo_beta elseif type == GAMMA then foo.load = load_foo_gamma else foo = create_null_message() end foo:load(sequence) return foo end -- sequence から protocol bar のメッセージを作る関数群 function load_bar_alpha(self, sequence) self.type = "alpha" end function load_bar_beta(self, sequence) self.type = "beta" end function load_bar_gamma(self, sequence) self.type = "gamma" end function load_bar(sequence) local bar = create_message("bar") local type = sequence:byte(2) if type == ALPHA then bar.load = load_bar_alpha elseif type == BETA then bar.load = load_bar_beta elseif type == GAMMA then bar.load = load_bar_gamma else bar = create_null_message() end bar:load(sequence) return bar end -- sequence から protocol baz のメッセージを作る関数群 function load_baz_alpha(self, sequence) self.type = "alpha" end function load_baz_beta(self, sequence) self.type = "beta" end function load_baz_gamma(self, sequence) self.type = "gamma" end function load_baz(sequence) local baz = create_message("baz") local type = sequence:byte(2) if type == ALPHA then baz.load = load_baz_alpha elseif type == BETA then baz.load = load_baz_beta elseif type == GAMMA then baz.load = load_baz_gamma else baz = create_null_message() end baz:load(sequence) return baz end -- sequence からメッセージを作る関数 function load(sequence) local protocol = sequence:byte(1) if protocol == FOO then return load_foo(sequence) elseif protocol == BAR then return load_bar(sequence) elseif protocol == BAZ then return load_baz(sequence) else return create_null_message end end
require("message") -- メッセージを受け取るオブジェクト receiver の定義 receiver = {} -- protocol:foo / type:alpha を受け取る関数 function receiver:foo_alpha_received(msg) print("foo-alpha received") end -- protocol:bar / type:beta を受け取る関数 function receiver:bar_beta_received(msg) print("bar-beta received") end -- protocol:baz / type:gamma を受け取る関数 function receiver:baz_gamma_received(msg) print("baz-gamma received") end -- メッセージに対応する関数がない場合、デフォルトで呼び出される関数 function receiver:default_received(msg) print("default received") end -- サンプルのメッセージ messages = { string.char(message.FOO, message.ALPHA), string.char(message.FOO, message.BETA), string.char(message.BAR, message.BETA), string.char(message.BAZ, message.GAMMA) } -- メッセージを load (deserialize) してディスパッチ for i = 1, #messages do msg = message.load(messages[i]) msg:dispatch(receiver) end
実行結果。
foo-alpha received default received bar-beta received baz-gamma received
まだLuaはまだまだ道半ば。というかまだ入り口。
12/16追記
なんか"type
"がハイライトされてるなと思ったら、型の種類が入ってる値だった。上書きしてしまった。