c++ - 如何让tolua++在collect函数中调用自定义代码

标签 c++ lua garbage-collection tolua++

标题几乎说明了一切。 我不希望 tolua++ 生成只调用的代码

delete self;

在收集函数中。我希望它做这样的事情:

some_custom_collector(self);

是否可以在 .pkg 文件中指定?

最佳答案

几天后我又回到了这个问题上,我需要快速的解决方案。我意识到没有办法做到这一点。所以我为 tolua++ 做了一个补丁,但是我在 CEGUI 源中找到了版本。 所以它以非常丑陋的方式完成,但它非常易于使用并且有效

假设你有类 SomeClass,并且你想要 lua 函数 delete 和 collect 函数调用 SomeClass_CustomFinalizer,你可以在你的 SomeClass.pkg 文件中这样指定:

tolua_outside void ~SomeClass @ SomeClass_CustomFinalizer();

所以不要像这样生成代码:

delete self;

它将生成如下代码:

SomeClass_CustomFinalizer(self);

这是补丁。即使您没有应用它,也应该很容易了解大概的想法并手动应用。

diff --git a/lua/basic.lua b/lua/basic.lua
index 99fc961..b4983e3 100644
--- a/lua/basic.lua
+++ b/lua/basic.lua
@@ -67,7 +67,8 @@ _basic_raw_push = {}
 _usertype = {}

 -- List of types that have to be collected
-_collect = {}
+_collect = {{}}
+_collect_custom_finalizers_index = 1

 -- List of types
 _global_types = {n=0}

diff --git a/lua/class.lua b/lua/class.lua
index 8580ce8..c8f275e 100644
--- a/lua/class.lua
+++ b/lua/class.lua
@@ -78,7 +78,10 @@ function classClass:requirecollection (t)
    -- classes that export constructors need to have a collector (overrided by -D flag on command line)
    if self._delete or ((not flags['D']) and self._new) then
        --t[self.type] = "tolua_collect_" .. gsub(self.type,"::","_")
-       t[self.type] = "tolua_collect_" .. clean_template(self.type)
+        t[self.type] = "tolua_collect_" .. clean_template(self.type)
+        if self.custom_finalizer then
+          t[_collect_custom_finalizers_index][self.type] = self.custom_finalizer
+        end
        r = true
    end
  return r

diff --git a/lua/function.lua b/lua/function.lua
index ce73cf8..0db9b2f 100644
--- a/lua/function.lua
+++ b/lua/function.lua
@@ -322,7 +322,11 @@ function classFunction:supcode (local_constructor)

  -- call function
  if class and self.name=='delete' then
-  output('  delete self;')
+   if self.custom_finalizer then
+       output('  ' .. self.custom_finalizer .. '(self);')
+   else
+       output('  delete self;')
+   end
  elseif class and self.name == 'operator&[]' then
   if flags['1'] then -- for compatibility with tolua5 ?
    output('  self->operator[](',self.args[1].name,'-1) = ',self.args[2].name,';')


@@ -679,14 +684,20 @@ function _Function (t)

  append(t)
  if t:inclass() then
- --print ('t.name is '..t.name..', parent.name is '..t.parent.name)
+
+--print ('t.name is '..t.name..', parent.name is '..t.parent.name)
+
   if string.gsub(t.name, "%b<>", "") == string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then
    t.name = 'new'
    t.lname = 'new'
    t.parent._new = true
    t.type = t.parent.name
    t.ptr = '*'
-  elseif string.gsub(t.name, "%b<>", "") == '~'..string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then
+ elseif string.gsub(t.name, "%b<>", "") == '~'..string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then
+   if t.lname ~= t.name then
+     t.parent.custom_finalizer = t.lname
+     t.custom_finalizer = t.lname
+   end
    t.name = 'delete'
    t.lname = 'delete'
    t.parent._delete = true

diff --git a/lua/package.lua b/lua/package.lua
index 6ba30fb..edc791a 100644
--- a/lua/package.lua
+++ b/lua/package.lua
@@ -135,12 +135,20 @@ function classPackage:preamble ()
        output('/* function to release collected object via destructor */')
        output('#ifdef __cplusplus\n')
        for i,v in pairs(_collect) do
-        output('\nstatic int '..v..' (lua_State* tolua_S)')
-           output('{')
-           output(' '..i..'* self = ('..i..'*) tolua_tousertype(tolua_S,1,0);')
-           output('    delete self;')
-           output('    return 0;')
-           output('}')
+            if i ~= _collect_custom_finalizers_index then
+
+            output('\nstatic int '..v..' (lua_State* tolua_S)')
+            output('{')
+            output(' '..i..'* self = ('..i..'*) tolua_tousertype(tolua_S,1,0);')
+            if _collect[_collect_custom_finalizers_index][i] then
+                output('  ' .. _collect[_collect_custom_finalizers_index][i] .. '(self);')
+            else
+                output('  delete self;')
+            end
+            output('   return 0;')
+            output('}')
+
+            end
        end
        output('#endif\n\n')
    end

您应该为 tolua++ 重新制作绑定(bind)代码并重新编译它。

关于c++ - 如何让tolua++在collect函数中调用自定义代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36200578/

相关文章:

C++简化版链表,当我加载数据创建链表,并输入更多数据时,似乎有差距

c++ - 在C++中,如何任意创建点位置?

使用 setfenv 定义 Lua 变量范围

machine-learning - 以张量作为输入的 MLP 构造

java - 在Java中重用对象的存储意味着什么?

c++ - 序列的宏递归扩展

string - 如何在字符串的字符之间添加空格

java - Java内存中Survivor Space的目的是什么?

java - 如何避免GC暂停?

c++ - 在内联汇编代码中使用 C++ 命名空间