140 lines
5.0 KiB
Lua
140 lines
5.0 KiB
Lua
--------------------------------------------------------------------------------
|
|
------------------------------ ##### ## ------------------------------
|
|
------------------------------ ## ## # ## ------------------------------
|
|
------------------------------ ## ## ## ## ------------------------------
|
|
------------------------------ ## ## # ## ------------------------------
|
|
------------------------------ ##### ### ###### ------------------------------
|
|
-------------------------------- --------------------------------
|
|
----------------------- An Object Request Broker in Lua ------------------------
|
|
--------------------------------------------------------------------------------
|
|
-- Project: OiL - ORB in Lua: An Object Request Broker in Lua --
|
|
-- Release: 0.4 --
|
|
-- Title : Object Request Dispatcher --
|
|
-- Authors: Renato Maia <maia@inf.puc-rio.br> --
|
|
--------------------------------------------------------------------------------
|
|
-- objects:Facet
|
|
-- object:object register(impl:object, key:string)
|
|
-- impl:object unregister(key:string)
|
|
-- impl:object retrieve(key:string)
|
|
--
|
|
-- dispatcher:Facet
|
|
-- success:boolean, [except:table]|results... dispatch(key:string, operation:string|function, params...)
|
|
--------------------------------------------------------------------------------
|
|
|
|
local luapcall = pcall
|
|
local setmetatable = setmetatable
|
|
local type = type --[[VERBOSE]] local select = select
|
|
|
|
local oo = require "oil.oo"
|
|
local Exception = require "oil.Exception" --[[VERBOSE]] local verbose = require "oil.verbose"
|
|
|
|
module("oil.kernel.base.Dispatcher", oo.class)
|
|
|
|
context = false
|
|
|
|
pcall = luapcall
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Objects facet
|
|
|
|
function __init(self, object)
|
|
self = oo.rawnew(self, object)
|
|
self.map = self.map or {}
|
|
return self
|
|
end
|
|
|
|
function register(self, impl, key, ...)
|
|
local result, except = self.map[key]
|
|
if result then
|
|
if result.object ~= impl then
|
|
result, except = nil, Exception{
|
|
reason = "usedkey",
|
|
message = "object key already in use",
|
|
key = key,
|
|
}
|
|
end
|
|
else --[[VERBOSE]] verbose:dispatcher("object ",impl," registered with key ",key)
|
|
self.map[key] = { object = impl, ... }
|
|
result = true
|
|
end
|
|
return result, except
|
|
end
|
|
|
|
function unregister(self, key)
|
|
local map = self.map
|
|
local impl = map[key]
|
|
if impl then --[[VERBOSE]] verbose:dispatcher("object with key ",key," unregistered")
|
|
impl = impl.object
|
|
map[key] = nil
|
|
end
|
|
return impl
|
|
end
|
|
|
|
function retrieve(self, key)
|
|
local servant = self.map[key]
|
|
return servant and servant.object
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Dispatcher facet
|
|
|
|
function dispatch(self, key, operation, default, ...)
|
|
local object = self.map[key]
|
|
if object then
|
|
object = object.object
|
|
local method = object[operation] or default
|
|
if method then --[[VERBOSE]] verbose:dispatcher("dispatching operation ",key,":",operation, ...)
|
|
return self.pcall(method, object, ...)
|
|
else
|
|
return false, Exception{
|
|
reason = "noimplement",
|
|
message = "no implementation for operation of object with key",
|
|
operation = operation,
|
|
key = key,
|
|
}
|
|
end
|
|
else
|
|
return false, Exception{
|
|
reason = "badkey",
|
|
message = "no object with key",
|
|
key = key,
|
|
}
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
--[[VERBOSE]] function verbose.custom:dispatcher(...)
|
|
--[[VERBOSE]] local params
|
|
--[[VERBOSE]] for i = 1, select("#", ...) do
|
|
--[[VERBOSE]] local value = select(i, ...)
|
|
--[[VERBOSE]] local type = type(value)
|
|
--[[VERBOSE]] if params == true then
|
|
--[[VERBOSE]] params = "("
|
|
--[[VERBOSE]] if type == "string" then
|
|
--[[VERBOSE]] self.viewer.output:write(value)
|
|
--[[VERBOSE]] else
|
|
--[[VERBOSE]] self.viewer:write(value)
|
|
--[[VERBOSE]] end
|
|
--[[VERBOSE]] elseif type == "string" then
|
|
--[[VERBOSE]] if params then
|
|
--[[VERBOSE]] self.viewer.output:write(params)
|
|
--[[VERBOSE]] params = ", "
|
|
--[[VERBOSE]] self.viewer:write((value:gsub("[^%w%p%s]", "?")))
|
|
--[[VERBOSE]] else
|
|
--[[VERBOSE]] self.viewer.output:write(value)
|
|
--[[VERBOSE]] if value == ":" then params = true end
|
|
--[[VERBOSE]] end
|
|
--[[VERBOSE]] else
|
|
--[[VERBOSE]] if params then
|
|
--[[VERBOSE]] self.viewer.output:write(params)
|
|
--[[VERBOSE]] params = ", "
|
|
--[[VERBOSE]] end
|
|
--[[VERBOSE]] self.viewer:write(value)
|
|
--[[VERBOSE]] end
|
|
--[[VERBOSE]] end
|
|
--[[VERBOSE]] if params then
|
|
--[[VERBOSE]] self.viewer.output:write(params == "(" and "()" or ")")
|
|
--[[VERBOSE]] end
|
|
--[[VERBOSE]] end
|