sent = {} sent.register = function (cfg) if cfg.name == nil then error("sent.register: needs name") end if cfg.cls == nil then error("sent.register: needs cls") end local name = cfg.name local cls = cfg.cls local components = cfg.components or {} if cls.__sent_class_id ~= nil then error(string.format("sent.register: %s already registered", name)) return end -- Recreate config when calling native function, to ensure no metatable -- fuckery. local sent_class_id = __sent_register({ name = name, cls = cls, components = components, }) cls.__sent_class_id = sent_class_id cls.new = function(...) local arg = {...} -- Make object table, instantiate with runtime. local table = {} local sent_id = __sent_new(table, sent_class_id) table.__sent_id = sent_id -- Make 'tick' trampoline, used by runtime to do fast call into ticker -- without bind/argument push. table.__sent_tick = function() if table.tick ~= nil then table:tick() end end -- Configure components dispatcher. table.components = {} table.components.__sent_id = sent_id local components_meta = {} components_meta.__index = function(t, k) return __sent_components_index(t, k) end components_meta.__newindex = function(t, k, v) return __sent_components_newindex(t, k, v) end setmetatable(table.components, components_meta) -- Make table deref via table to class. local metatable = {} metatable.__index = cls setmetatable(table, metatable) -- Call initializer, if present. if table.init ~= nil then table:init(unpack(arg)) end return table end end