Lua 接口(Interface)实现方式之一

interface是面向对象编程语言中接口操作的关键字,功能是把所需成员组合起来,以封装一定功能的集合。它好比一个模板,在其中定义了对象必须实现的成员,通过类或结构来实现它。接口不能包含成员的任何代码,只定义成员本身。接口成员的具体代码由实现接口的类提供。接口使用interface关键字进行声明。

在Lua中也可以封装这种类似的Interface。

function BasePanel:ctor(options)
    ro(self):addBehavior("Logic.behaviors.BindableBehavior"):exportMethods()
end
local romt = {}
romt.__call = function(self, target)
    if target then
        return BehaviorObject.extend(target)
    end
    printError("ro() - invalid target")
end
setmetatable(ro, romt)

local BindableBehavior = class("BindableBehavior",ro.Behavior)

function BindableBehavior:ctor()
    self.__items = {}
    BindableBehavior.super.ctor(self,"BindableBehavior")
end

function BindableBehavior:bind_text(scope,key,text,format,tagname)
    local item = scope:bind_text(key,text,format,tagname)
    table.insert(self.__items,item)
    return item
end

function BindableBehavior:bind_object(scope,key,object,format,tagname)
    local item = scope:bind_object(key,object,format,tagname)
    table.insert(self.__items,item)
    return item
end

function BindableBehavior:bind_func(scope,key,func,format,tagname)
    local item = scope:bind_func(key,func,format,tagname)
    table.insert(self.__items,item)
    return item
end

function BindableBehavior:unbind_point(object)
    for i=#self.__items,1,-1 do
        local item = self.__items[i]
        if item.custom ~= nil and item.custom == object then
            item:unbind("unbind_point")
            table.remove(self.__items,i)
            break
        end
    end
end

function BindableBehavior:has_bind_point(object)
    for i=#self.__items,1,-1 do
        local item = self.__items[i]
        if item.custom == object then
            return item
        end
    end
    return false
end

function BindableBehavior:bind_point(key,object,condition,tagname)
    if key == nil or object == nil then
        log("bind_point error =>"..tostring(key),"BINDING")
        return
    end
    local function on_point(k,v)
        if v == 0 then
            if object ~= nil and object.gameObject ~= nil then
                object.gameObject:SetActive(false)
            end
        else
            if object ~= nil and object.gameObject ~= nil then
                if not condition or ro.mu:isOpen(condition,false) then
                    object.gameObject:SetActive(true)
                else
                    object.gameObject:SetActive(false)
                end
            end
        end
    end
    local points = ro.user.role.points
    self:unbind_point(object)
    local item = points:bind_func(key,on_point,nil,tagname)
    item.custom = object
    table.insert(self.__items,item)
    return item
end

function BindableBehavior:update_bindings()
    if #self.__items > 0 then
        --log("update_bindings:"..#self.__items,"BIND")
        for i,item in ipairs(self.__items) do
            item:update()
        end
    end
end

function BindableBehavior:clear_bindings()
    --log(self:getTarget().__cname.."=>clear_bindings","BINDING")
    for i,item in ipairs(self.__items) do
        item:unbind()
    end
    self.__items = {}
end

function BindableBehavior:exportMethods()
    self:exportMethods_(
    {
        "bind_text",
        "bind_object",
        "bind_func",
        "bind_point",
        "unbind_point",
        "has_bind_point",
        "update_bindings",
        "clear_bindings",
    })
    return self.target_
end
return BindableBehavior

local Registry = require("Logic.Registry")
local BehaviorObject = {}
function BehaviorObject.extend(target)
    if target.extendcomponent == nil then
        target.extendcomponent = true
        target.components_ = {}
        function target:checkBehavior(name)
            return self.components_[name] ~= nil
        end

        function target:printBehaviors(tag)
            tag = tag or ""
            for k,v in pairs(self.components_) do
                print(tostring(self.__cname).."===>"..tostring(tag).."===>",k)
            end
        end

        function target:addBehavior(name,auto_export)
            local component
            if not self:checkBehavior(name) then
                component = Registry.newObject(name)
                self.components_[name] = component
                component:bind_(self)
                if auto_export then
                    component:exportMethods()
                end
            else
                component = self:getBehavior(name)
            end
            return component
        end

        function target:removeBehavior(name)
            local component = self.components_[name]
            if component then component:unbind_() end
            self.components_[name] = nil
        end

        function target:getBehavior(name)
            return self.components_[name]
        end
    end
    return target
end
return BehaviorObject

local Registry = class("Registry")

Registry.classes_ = {}
Registry.objects_ = {}

function Registry.add(cls, name)
    assert(type(cls) == "table" and cls.__cname ~= nil, "Registry.add() - invalid class")
    if not name then name = cls.__cname end
    if Registry.classes_[name] == nil then
        Registry.classes_[name] = cls
    else
        print(string.format("Registry.add() - class \"%s\" already exists", tostring(name)))
    end
end

function Registry.remove(name)
    assert(Registry.classes_[name] ~= nil, string.format("Registry.remove() - class \"%s\" not found", name))
    Registry.classes_[name] = nil
end

function Registry.exists(name)
    return Registry.classes_[name] ~= nil
end

function Registry.newObject(name, ...)
    local cls = Registry.classes_[name]
    if not cls then
        -- auto load
        pcall(function()
            cls = require(name)
            Registry.add(cls, name)
        end)
    end
    assert(cls ~= nil, string.format("Registry.newObject() - invalid class \"%s\"", tostring(name)))
    return cls.new(...)
end

function Registry.setObject(object, name)
    assert(Registry.objects_[name] == nil, string.format("Registry.setObject() - object \"%s\" already exists", tostring(name)))
    assert(object ~= nil, "Registry.setObject() - object \"%s\" is nil", tostring(name))
    Registry.objects_[name] = object
end

function Registry.getObject(name)
    assert(Registry.objects_[name] ~= nil, string.format("Registry.getObject() - object \"%s\" not exists", tostring(name)))
    return Registry.objects_[name]
end

function Registry.removeObject(name)
    assert(Registry.objects_[name] ~= nil, string.format("Registry.removeObject() - object \"%s\" not exists", tostring(name)))
    Registry.objects_[name] = nil
end

function Registry.isObjectExists(name)
    return Registry.objects_[name] ~= nil
end

return Registry

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值