104 lines
3.6 KiB
Lua
104 lines
3.6 KiB
Lua
|
---------------------------------------------------------------------------
|
||
|
--- An helper module to map userdata __index and __newindex entries to
|
||
|
-- lua classes.
|
||
|
--
|
||
|
-- @author Emmanuel Lepage-Vallee <elv1313@gmail.com>
|
||
|
-- @copyright 2016 Emmanuel Lepage-Vallee
|
||
|
-- @release @AWESOME_VERSION@
|
||
|
-- @module gears.object.properties
|
||
|
---------------------------------------------------------------------------
|
||
|
|
||
|
local object = {}
|
||
|
|
||
|
local properties = setmetatable({}, { __mode = 'k' })
|
||
|
|
||
|
local function cobj_register(cobj)
|
||
|
local fallback = {}
|
||
|
|
||
|
function fallback:rawset(_, prop, val)
|
||
|
fallback[prop] = val
|
||
|
end
|
||
|
|
||
|
function fallback:rawget(_, prop)
|
||
|
return fallback[prop]
|
||
|
end
|
||
|
|
||
|
properties[cobj] = fallback
|
||
|
return fallback
|
||
|
end
|
||
|
|
||
|
--- Add the missing properties handler to a CAPI object such as client/tag/screen
|
||
|
-- Valid args:
|
||
|
--
|
||
|
-- * **getter**: A smart getter (handle property getter itself)
|
||
|
-- * **getter_fallback**: A dumb getter method (don't handle individual property getter)
|
||
|
-- * **getter_class**: A module with individual property getter/setter
|
||
|
-- * **getter_prefix**: A special getter prefix (like "get" or "get_" (default))
|
||
|
-- * **setter**: A smart setter (handle property setter itself)
|
||
|
-- * **setter_fallback**: A dumb setter method (don't handle individual property setter)
|
||
|
-- * **setter_class**: A module with individual property getter/setter
|
||
|
-- * **setter_prefix**: A special setter prefix (like "set" or "set_" (default))
|
||
|
-- * **auto_emit**: Emit "property::___" automatically (default: false). This is
|
||
|
-- ignored when setter_fallback is set or a setter is found
|
||
|
--
|
||
|
-- @param class A standard luaobject derived object
|
||
|
-- @tparam[opt={}] table args A set of accessors configuration parameters
|
||
|
function object.capi_index_fallback(class, args)
|
||
|
args = args or {}
|
||
|
|
||
|
local getter_prefix = args.getter_prefix or "get_"
|
||
|
local setter_prefix = args.setter_prefix or "set_"
|
||
|
|
||
|
local getter = args.getter or function(cobj, prop)
|
||
|
-- Look for a getter method
|
||
|
if args.getter_class and args.getter_class[getter_prefix..prop] then
|
||
|
return args.getter_class[getter_prefix..prop](cobj)
|
||
|
end
|
||
|
|
||
|
-- Make sure something like c:a_mutator() works
|
||
|
if args.getter_class and args.getter_class[prop] then
|
||
|
return args.getter_class[prop]
|
||
|
end
|
||
|
|
||
|
-- In case there is already a "dumb" getter like `awful.tag.getproperty'
|
||
|
if args.getter_fallback then
|
||
|
return args.getter_fallback(cobj, prop)
|
||
|
end
|
||
|
|
||
|
local fallback = properties[cobj] or cobj_register(cobj)
|
||
|
|
||
|
-- Use the fallback property table
|
||
|
return fallback[prop]
|
||
|
end
|
||
|
|
||
|
local setter = args.setter or function(cobj, prop, value)
|
||
|
-- Look for a setter method
|
||
|
if args.setter_class and args.setter_class[setter_prefix..prop] then
|
||
|
return args.setter_class[setter_prefix..prop](cobj, value)
|
||
|
end
|
||
|
|
||
|
-- In case there is already a "dumb" setter like `awful.client.property.set'
|
||
|
if args.setter_fallback then
|
||
|
return args.setter_fallback(cobj, prop, value)
|
||
|
end
|
||
|
|
||
|
local fallback = properties[cobj] or cobj_register(cobj)
|
||
|
|
||
|
-- Use the fallback property table
|
||
|
fallback[prop] = value
|
||
|
|
||
|
-- Emit the signal
|
||
|
if args.auto_emit then
|
||
|
cobj:emit_signal("property::"..prop, value)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Attach the accessor methods
|
||
|
class.set_index_miss_handler(getter)
|
||
|
class.set_newindex_miss_handler(setter)
|
||
|
end
|
||
|
|
||
|
return setmetatable( object, {__call = function(_,...) object.capi_index_fallback(...) end})
|
||
|
|
||
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|