Browse Source

It works! Kind of. Well, no crashes.

Added a check to see if a LuaType is reference counted.

I probably forgot to remove a whole bunch of debugging code, so if you see poorly placed strings everywhere, that was me trying to figure out what was going on.
Nate Starkey 13 years ago
parent
commit
23ef189318

+ 5 - 1
Include/Rocket/Core/Lua/LuaType.h

@@ -39,7 +39,7 @@ namespace Lua {
     template<> luaL_reg* GetAttrTable<type>() { return type##Getters; } \
     template<> luaL_reg* GetAttrTable<type>() { return type##Getters; } \
     template<> luaL_reg* SetAttrTable<type>() { return type##Setters; } \
     template<> luaL_reg* SetAttrTable<type>() { return type##Setters; } \
 
 
-//put this in the type.h file  NOT USED at this moment
+//put this in the type.h file
 #define LUATYPEDECLARE(type) \
 #define LUATYPEDECLARE(type) \
     template<> const char* GetTClassName<type>(); \
     template<> const char* GetTClassName<type>(); \
     template<> RegType<type>* GetMethodTable<type>(); \
     template<> RegType<type>* GetMethodTable<type>(); \
@@ -97,6 +97,10 @@ public:
     static  void extra_init(lua_State* L, int metatable_index);
     static  void extra_init(lua_State* L, int metatable_index);
     //Registers methods,getters,and setters to the type
     //Registers methods,getters,and setters to the type
     static void _regfunctions(lua_State* L, int meta, int method);
     static void _regfunctions(lua_State* L, int meta, int method);
+    //Says if it is a reference counted type. If so, then on push and __gc, do reference counting things
+    //rather than regular new/delete. Note that it is still up to the user to pass "true" to the push function's
+    //third parameter to be able to decrease the reference when Lua garbage collects an object
+    static bool is_reference_counted();
 private:
 private:
     LuaType(); //hide constructor
     LuaType(); //hide constructor
 
 

+ 1 - 1
Samples/luainvaders/data/main_menu.rml

@@ -32,6 +32,6 @@ end
 		<button onclick="Window.LoadMenu('high_score')">High Scores</button><br />
 		<button onclick="Window.LoadMenu('high_score')">High Scores</button><br />
 		<button onclick="Window.LoadMenu('options')">Options</button><br />
 		<button onclick="Window.LoadMenu('options')">Options</button><br />
 		<button onclick="Window.LoadMenu('help')">Help</button><br />
 		<button onclick="Window.LoadMenu('help')">Help</button><br />
-		<button onclick="game.Shutdown()">Exit</button>
+		<button onclick="Game.Shutdown()">Exit</button>
 	</body>
 	</body>
 </rml>
 </rml>

+ 0 - 4
Samples/luainvaders/lua/start.lua

@@ -1,11 +1,7 @@
 
 
 function Startup()
 function Startup()
-    --for k,v in pairs(rocket) do Log(k) end
-    --yes, maincontext is supposed to be global
-    --rocket.CreateContext("notmain",Vector2i(20,15))
     local escape = rocket.key_identifier["ESCAPE"]
     local escape = rocket.key_identifier["ESCAPE"]
     if escape ~= nil then
     if escape ~= nil then
-    
         maincontext = rocket.contexts()["main"]
         maincontext = rocket.contexts()["main"]
         maincontext:LoadDocument("data/background.rml"):Show()
         maincontext:LoadDocument("data/background.rml"):Show()
         local doc = maincontext:LoadDocument("data/main_menu.rml")
         local doc = maincontext:LoadDocument("data/main_menu.rml")

+ 7 - 7
Samples/luainvaders/src/LuaInterface.cpp

@@ -57,16 +57,16 @@ void LuaInterface::InitGame(lua_State *L)
     lua_pushcfunction(L,GameSetHighScoreName);
     lua_pushcfunction(L,GameSetHighScoreName);
     lua_setfield(L,game,"SetHighScoreName");
     lua_setfield(L,game,"SetHighScoreName");
 
 
-    lua_newtable(L);
-    lua_pushinteger(L,GameDetails::HARD);
-    lua_setfield(L,-2,"HARD");
+    lua_newtable(L); //table, Game
+    lua_pushinteger(L,GameDetails::HARD); //int,table,Game
+    lua_setfield(L,-2,"HARD");//table,Game
 
 
-    lua_pushinteger(L,GameDetails::EASY);
-    lua_setfield(L,-2,"EASY");
+    lua_pushinteger(L,GameDetails::EASY); //int,table,Game
+    lua_setfield(L,-2,"EASY"); //table,Game
 
 
-    lua_setfield(L,game,"difficulty"); //Game.difficulty = {HARD,EASY}
+    lua_setfield(L,game,"difficulty"); //Game
 
 
-    lua_pop(L,2); //pop both Game.difficulty and Game
+    lua_pop(L,1); //pop Game
 }
 }
 
 
 int GameShutdown(lua_State* L)
 int GameShutdown(lua_State* L)

+ 2 - 1
Samples/luainvaders/src/main.cpp

@@ -37,6 +37,7 @@
 #include "ElementGame.h"
 #include "ElementGame.h"
 #include "HighScores.h"
 #include "HighScores.h"
 #include <Rocket/Core/Lua/Interpreter.h>
 #include <Rocket/Core/Lua/Interpreter.h>
+#include "LuaInterface.h"
 
 
 Rocket::Core::Context* context = NULL;
 Rocket::Core::Context* context = NULL;
 
 
@@ -122,7 +123,7 @@ int main(int, char**)
 
 
 	// Fire off the startup script.
 	// Fire off the startup script.
 	//PythonInterface::Import("autoexec");
 	//PythonInterface::Import("autoexec");
-    //LuaInterface::Initialise(Interpreter::GetLuaState());
+    LuaInterface::Initialise(Rocket::Core::Lua::Interpreter::GetLuaState());
     Rocket::Core::Lua::Interpreter::LoadFile(Rocket::Core::String(APP_PATH).Append("lua/start.lua"));
     Rocket::Core::Lua::Interpreter::LoadFile(Rocket::Core::String(APP_PATH).Append("lua/start.lua"));
 
 
 	Shell::EventLoop(GameLoop);	
 	Shell::EventLoop(GameLoop);	

+ 1 - 0
Source/Controls/Lua/ElementDataGrid.h

@@ -23,6 +23,7 @@ namespace Core {
 namespace Lua {
 namespace Lua {
 //this will be used to "inherit" from Element
 //this will be used to "inherit" from Element
 template<> void LuaType<ElementDataGrid>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<ElementDataGrid>::extra_init(lua_State* L, int metatable_index);
+template<> bool LuaType<ElementDataGrid>::is_reference_counted();
 
 
 //methods
 //methods
 int ElementDataGridAddColumn(lua_State* L, ElementDataGrid* obj);
 int ElementDataGridAddColumn(lua_State* L, ElementDataGrid* obj);

+ 1 - 0
Source/Controls/Lua/ElementDataGridRow.h

@@ -27,6 +27,7 @@ namespace Core {
 namespace Lua {
 namespace Lua {
 //this will be used to "inherit" from Element
 //this will be used to "inherit" from Element
 template<> void LuaType<ElementDataGridRow>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<ElementDataGridRow>::extra_init(lua_State* L, int metatable_index);
+template<> bool LuaType<ElementDataGridRow>::is_reference_counted();
 
 
 //getters
 //getters
 int ElementDataGridRowGetAttrrow_expanded(lua_State* L);
 int ElementDataGridRowGetAttrrow_expanded(lua_State* L);

+ 1 - 0
Source/Controls/Lua/ElementForm.h

@@ -18,6 +18,7 @@ namespace Core {
 namespace Lua {
 namespace Lua {
 //this will be used to "inherit" from Element
 //this will be used to "inherit" from Element
 template<> void LuaType<ElementForm>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<ElementForm>::extra_init(lua_State* L, int metatable_index);
+template<> bool LuaType<ElementForm>::is_reference_counted();
 
 
 //method
 //method
 int ElementFormSubmit(lua_State* L, ElementForm* obj);
 int ElementFormSubmit(lua_State* L, ElementForm* obj);

+ 2 - 0
Source/Controls/Lua/ElementFormControl.h

@@ -17,6 +17,8 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 template<> void LuaType<ElementFormControl>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<ElementFormControl>::extra_init(lua_State* L, int metatable_index);
+template<> bool LuaType<ElementFormControl>::is_reference_counted();
+
 //getters
 //getters
 int ElementFormControlGetAttrdisabled(lua_State* L);
 int ElementFormControlGetAttrdisabled(lua_State* L);
 int ElementFormControlGetAttrname(lua_State* L);
 int ElementFormControlGetAttrname(lua_State* L);

+ 1 - 0
Source/Controls/Lua/ElementFormControlDataSelect.h

@@ -20,6 +20,7 @@ namespace Core {
 namespace Lua {
 namespace Lua {
 //inherits from ElementFormControl which inherits from Element
 //inherits from ElementFormControl which inherits from Element
 template<> void LuaType<ElementFormControlDataSelect>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<ElementFormControlDataSelect>::extra_init(lua_State* L, int metatable_index);
+template<> bool LuaType<ElementFormControlDataSelect>::is_reference_counted();
 
 
 //method
 //method
 int ElementFormControlDataSelectSetDataSource(lua_State* L, ElementFormControlDataSelect* obj);
 int ElementFormControlDataSelectSetDataSource(lua_State* L, ElementFormControlDataSelect* obj);

+ 1 - 0
Source/Controls/Lua/ElementFormControlInput.h

@@ -23,6 +23,7 @@ namespace Core {
 namespace Lua {
 namespace Lua {
 //inherits from ElementFormControl which inherits from Element
 //inherits from ElementFormControl which inherits from Element
 template<> void LuaType<ElementFormControlInput>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<ElementFormControlInput>::extra_init(lua_State* L, int metatable_index);
+template<> bool LuaType<ElementFormControlInput>::is_reference_counted();
 
 
 //getters
 //getters
 int ElementFormControlInputGetAttrchecked(lua_State* L);
 int ElementFormControlInputGetAttrchecked(lua_State* L);

+ 1 - 0
Source/Controls/Lua/ElementFormControlSelect.h

@@ -29,6 +29,7 @@ namespace Core {
 namespace Lua {
 namespace Lua {
 //inherits from ElementFormControl which inherits from Element
 //inherits from ElementFormControl which inherits from Element
 template<> void LuaType<ElementFormControlSelect>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<ElementFormControlSelect>::extra_init(lua_State* L, int metatable_index);
+template<> bool LuaType<ElementFormControlSelect>::is_reference_counted();
 
 
 //methods
 //methods
 int ElementFormControlSelectAdd(lua_State* L, ElementFormControlSelect* obj);
 int ElementFormControlSelectAdd(lua_State* L, ElementFormControlSelect* obj);

+ 1 - 0
Source/Controls/Lua/ElementFormControlTextArea.h

@@ -20,6 +20,7 @@ namespace Core {
 namespace Lua {
 namespace Lua {
 //inherits from ElementFormControl which inherits from Element
 //inherits from ElementFormControl which inherits from Element
 template<> void LuaType<ElementFormControlTextArea>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<ElementFormControlTextArea>::extra_init(lua_State* L, int metatable_index);
+template<> bool LuaType<ElementFormControlTextArea>::is_reference_counted();
 
 
 //getters
 //getters
 int ElementFormControlTextAreaGetAttrcols(lua_State* L);
 int ElementFormControlTextAreaGetAttrcols(lua_State* L);

+ 1 - 0
Source/Controls/Lua/ElementTabSet.h

@@ -26,6 +26,7 @@ namespace Core {
 namespace Lua {
 namespace Lua {
 //this will be used to "inherit" from Element
 //this will be used to "inherit" from Element
 template<> void LuaType<ElementTabSet>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<ElementTabSet>::extra_init(lua_State* L, int metatable_index);
+template<> bool LuaType<ElementTabSet>::is_reference_counted();
 
 
 //methods
 //methods
 int ElementTabSetSetPanel(lua_State* L, ElementTabSet* obj);
 int ElementTabSetSetPanel(lua_State* L, ElementTabSet* obj);

+ 1 - 1
Source/Controls/Lua/LuaDataSource.h

@@ -9,7 +9,7 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 
 
-class LuaDataSource : public DataSource
+class LuaDataSource : public Rocket::Controls::DataSource
 {
 {
 public:
 public:
     //default initilialize the lua func references to -1
     //default initilialize the lua func references to -1

+ 1 - 0
Source/Core/Lua/Context.h

@@ -36,6 +36,7 @@
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
+template<> bool LuaType<Context>::is_reference_counted();
 
 
 //methods
 //methods
 int ContextAddEventListener(lua_State* L, Context* obj);
 int ContextAddEventListener(lua_State* L, Context* obj);

+ 1 - 0
Source/Core/Lua/Document.h

@@ -33,6 +33,7 @@ namespace Lua {
 typedef ElementDocument Document;
 typedef ElementDocument Document;
 
 
 template<> void LuaType<Document>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<Document>::extra_init(lua_State* L, int metatable_index);
+template<> bool LuaType<Document>::is_reference_counted();
 
 
 //methods
 //methods
 int DocumentPullToFront(lua_State* L, Document* obj);
 int DocumentPullToFront(lua_State* L, Document* obj);

+ 1 - 1
Source/Core/Lua/Element.h

@@ -89,7 +89,7 @@
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-
+template<> bool LuaType<Element>::is_reference_counted();
 
 
 //methods
 //methods
 int ElementAddEventListener(lua_State* L, Element* obj);
 int ElementAddEventListener(lua_State* L, Element* obj);

+ 1 - 0
Source/Core/Lua/Event.h

@@ -20,6 +20,7 @@
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
+template<> bool LuaType<Event>::is_reference_counted();
 
 
 //method
 //method
 int EventStopPropagation(lua_State* L, Event* obj);
 int EventStopPropagation(lua_State* L, Event* obj);

+ 5 - 1
Source/Core/Lua/Interpreter.cpp

@@ -91,7 +91,7 @@ void Interpreter::Report()
     const char * msg= lua_tostring(_L,-1);
     const char * msg= lua_tostring(_L,-1);
     while(msg)
     while(msg)
     {
     {
-        lua_pop(_L,-1);
+        lua_pop(_L,1);
         Log::Message(Log::LT_WARNING, msg);
         Log::Message(Log::LT_WARNING, msg);
         msg=lua_tostring(_L,-1);
         msg=lua_tostring(_L,-1);
     }
     }
@@ -107,6 +107,10 @@ bool Interpreter::ExecuteCall(int params, int res)
 {
 {
     bool ret = true;
     bool ret = true;
     int top = lua_gettop(_L);
     int top = lua_gettop(_L);
+    //String strtype = lua_typename(_L,top-params);
+    String strtype;
+    for(int i = top; i >= 1; i--)
+        strtype = lua_typename(_L,lua_type(_L,i));
     if(lua_type(_L,top-params) != LUA_TFUNCTION)
     if(lua_type(_L,top-params) != LUA_TFUNCTION)
     {
     {
         ret = false;
         ret = false;

+ 25 - 5
Source/Core/Lua/LuaEventListener.cpp

@@ -15,11 +15,26 @@ LuaEventListener::LuaEventListener(const String& code, Element* element) : Event
     function.Append(" end");
     function.Append(" end");
 
 
     lua_State* L = Interpreter::GetLuaState();
     lua_State* L = Interpreter::GetLuaState();
+    lua_getglobal(L,"EVENTLISTENERFUNCTIONS");
+    if(lua_isnoneornil(L,-1))
+    {
+        lua_newtable(L);
+        lua_setglobal(L,"EVENTLISTENERFUNCTIONS");
+        lua_pop(L,1); //pop the unsucessful getglobal
+        lua_getglobal(L,"EVENTLISTENERFUNCTIONS");
+    }
+    int tbl = lua_gettop(L);
+    strFunc = lua_typename(L,lua_type(L,tbl));
 
 
     luaL_loadstring(L,function.CString()); //pushes the compiled string to the top of the stack
     luaL_loadstring(L,function.CString()); //pushes the compiled string to the top of the stack
-    luaFuncRef = lua_ref(L,true); //creates a reference to the item at the top of the stack
+    if(lua_pcall(L,0,1,0) != 0)
+        Interpreter::Report();
+    strFunc = lua_typename(L,lua_type(L,-1));
+    luaFuncRef = luaL_ref(L,tbl); //creates a reference to the item at the top of the stack in to the table we just created
+    lua_pop(L,1); //pop the EVENTLISTENERFUNCTIONS table
     attached = element;
     attached = element;
     parent = element->GetOwnerDocument();
     parent = element->GetOwnerDocument();
+    strFunc = function;
 }
 }
 
 
 //if it is created from a Lua Element
 //if it is created from a Lua Element
@@ -34,13 +49,18 @@ LuaEventListener::LuaEventListener(int ref, Element* element)
 void LuaEventListener::ProcessEvent(Event& event)
 void LuaEventListener::ProcessEvent(Event& event)
 {
 {
     lua_State* L = Interpreter::GetLuaState();
     lua_State* L = Interpreter::GetLuaState();
+    String strtype;
     int top = lua_gettop(L); 
     int top = lua_gettop(L); 
     //push the arguments
     //push the arguments
-    LuaType<Event>::push(L,&event,false);
-    LuaType<Element>::push(L,attached,false);
-    LuaType<Document>::push(L,parent,false);
+    lua_getglobal(L,"EVENTLISTENERFUNCTIONS");
+    int table = lua_gettop(L); //needed for lua_remove
+    strtype = lua_typename(L,lua_type(L,table));
+    lua_rawgeti(L,table,luaFuncRef);
+    strtype = lua_typename(L,lua_type(L,-1));
+    strtype = lua_typename(L,lua_type(L,LuaType<Event>::push(L,&event,false)));
+    strtype = lua_typename(L,lua_type(L,LuaType<Element>::push(L,attached,false)));
+    strtype = lua_typename(L,lua_type(L,LuaType<Document>::push(L,parent,false)));
     
     
-    lua_getref(L,luaFuncRef);
     Interpreter::ExecuteCall(3,0); //call the function at the top of the stack with 3 arguments
     Interpreter::ExecuteCall(3,0); //call the function at the top of the stack with 3 arguments
 
 
     lua_settop(L,top); //balanced stack makes Lua happy
     lua_settop(L,top); //balanced stack makes Lua happy

+ 2 - 0
Source/Core/Lua/LuaEventListener.h

@@ -1,5 +1,6 @@
 #pragma once
 #pragma once
 #include <Rocket/Core/EventListener.h>
 #include <Rocket/Core/EventListener.h>
+#include <Rocket/Core/String.h>
 #include "lua.hpp"
 #include "lua.hpp"
 
 
 namespace Rocket {
 namespace Rocket {
@@ -25,6 +26,7 @@ private:
     int luaFuncRef;
     int luaFuncRef;
     Element* attached;
     Element* attached;
     ElementDocument* parent;
     ElementDocument* parent;
+    String strFunc; //for debugging purposes
 };
 };
 
 
 }
 }

+ 25 - 2
Source/Core/Lua/LuaType.cpp

@@ -79,11 +79,21 @@ int LuaType<T>::push(lua_State *L, T* obj, bool gc)
             lua_pushboolean(L,1);// ->[4] = true
             lua_pushboolean(L,1);// ->[4] = true
             lua_setfield(L,-2,name); //represents t[k] = v, [-2 = 3] = t -> v = [4], k = <ClassName>; pop [4]
             lua_setfield(L,-2,name); //represents t[k] = v, [-2 = 3] = t -> v = [4], k = <ClassName>; pop [4]
         }
         }
+        else
+        {
+            if(is_reference_counted())
+                ((Rocket::Core::ReferenceCountable*)obj)->AddReference();
+        }
         lua_pop(L,1); // -> pop [3]
         lua_pop(L,1); // -> pop [3]
     }
     }
+    String strtype = lua_typename(L,ud);
+    strtype = lua_typename(L,mt);
     lua_settop(L,ud); //[ud = 2] -> remove everything that is above 2, top = [2]
     lua_settop(L,ud); //[ud = 2] -> remove everything that is above 2, top = [2]
+    strtype = lua_typename(L,-1);
     lua_replace(L, mt); //[mt = 1] -> move [2] to pos [1], and pop previous [1]
     lua_replace(L, mt); //[mt = 1] -> move [2] to pos [1], and pop previous [1]
+    strtype = lua_typename(L,-1);
     lua_settop(L, mt); //remove everything above [1]
     lua_settop(L, mt); //remove everything above [1]
+    strtype = lua_typename(L,-1);
     return mt;  // index of userdata containing pointer to T object
     return mt;  // index of userdata containing pointer to T object
 }
 }
 
 
@@ -134,8 +144,15 @@ int LuaType<T>::gc_T(lua_State* L)
         lua_getfield(L,-1, std::string(name).c_str()); //[-1 = 2] -> [3] = the value returned from if <ClassName> exists in the table to not gc
         lua_getfield(L,-1, std::string(name).c_str()); //[-1 = 2] -> [3] = the value returned from if <ClassName> exists in the table to not gc
         if(lua_isnil(L,-1) ) //[-1 = 3] if it doesn't exist, then we are free to garbage collect c++ side
         if(lua_isnil(L,-1) ) //[-1 = 3] if it doesn't exist, then we are free to garbage collect c++ side
         {
         {
-            delete obj;
-            obj = NULL;
+            if(is_reference_counted())
+            {
+                ((Rocket::Core::ReferenceCountable*)obj)->RemoveReference();
+            }
+            else
+            {
+                delete obj;
+                obj = NULL;
+            }
         }
         }
     }
     }
     lua_pop(L,3); //balance function
     lua_pop(L,3); //balance function
@@ -277,6 +294,12 @@ void LuaType<T>::_regfunctions(lua_State* L, int meta, int methods)
     lua_setfield(L,methods, "__setters"); //[methods = 1], methods.__setters = table, pop table
     lua_setfield(L,methods, "__setters"); //[methods = 1], methods.__setters = table, pop table
 }
 }
 
 
+template<typename T>
+bool LuaType<T>::is_reference_counted()
+{
+    return false;
+}
+
 }
 }
 }
 }
 }
 }

+ 4 - 0
Source/Core/Lua/LuaType.h

@@ -97,6 +97,10 @@ public:
     static  void extra_init(lua_State* L, int metatable_index);
     static  void extra_init(lua_State* L, int metatable_index);
     //Registers methods,getters,and setters to the type
     //Registers methods,getters,and setters to the type
     static void _regfunctions(lua_State* L, int meta, int method);
     static void _regfunctions(lua_State* L, int meta, int method);
+    //Says if it is a reference counted type. If so, then on push and __gc, do reference counting things
+    //rather than regular new/delete. Note that it is still up to the user to pass "true" to the push function's
+    //third parameter to be able to decrease the reference when Lua garbage collects an object
+    static bool is_reference_counted();
 private:
 private:
     LuaType(); //hide constructor
     LuaType(); //hide constructor
 
 

+ 16 - 2
Source/Core/Lua/LuaTypeTemplateSpec.inl

@@ -81,6 +81,22 @@ template class LuaType<ElementTabSet>;
 template class LuaType<DataSource>;
 template class LuaType<DataSource>;
 
 
 
 
+//reference counted types
+template<> bool LuaType<Element>::is_reference_counted() { return true; }
+template<> bool LuaType<Document>::is_reference_counted() { return true; }
+template<> bool LuaType<Event>::is_reference_counted() { return true; }
+template<> bool LuaType<Context>::is_reference_counted() { return true; }
+template<> bool LuaType<ElementForm>::is_reference_counted() { return true; }
+template<> bool LuaType<ElementFormControl>::is_reference_counted() { return true; }
+template<> bool LuaType<ElementFormControlDataSelect>::is_reference_counted() { return true; }
+template<> bool LuaType<ElementFormControlSelect>::is_reference_counted() { return true; }
+template<> bool LuaType<ElementFormControlInput>::is_reference_counted() { return true; }
+template<> bool LuaType<ElementFormControlTextArea>::is_reference_counted() { return true; }
+template<> bool LuaType<ElementDataGrid>::is_reference_counted() { return true; }
+template<> bool LuaType<ElementDataGridRow>::is_reference_counted() { return true; }
+template<> bool LuaType<ElementTabSet>::is_reference_counted() { return true; }
+/////////////////////////
+
 
 
 template<> void LuaType<rocket>::extra_init(lua_State* L, int metatable_index)
 template<> void LuaType<rocket>::extra_init(lua_State* L, int metatable_index)
 {
 {
@@ -206,7 +222,6 @@ template<> void LuaType<Document>::extra_init(lua_State* L, int metatable_index)
     LuaType<Element>::_regfunctions(L,metatable_index,metatable_index - 1);
     LuaType<Element>::_regfunctions(L,metatable_index,metatable_index - 1);
 }
 }
 
 
-
 template<> void LuaType<ElementStyle>::extra_init(lua_State* L, int metatable_index)
 template<> void LuaType<ElementStyle>::extra_init(lua_State* L, int metatable_index)
 {
 {
     lua_pushcfunction(L,ElementStyle__index);
     lua_pushcfunction(L,ElementStyle__index);
@@ -271,7 +286,6 @@ template<> void LuaType<ElementTabSet>::extra_init(lua_State* L, int metatable_i
     LuaType<Element>::_regfunctions(L,metatable_index,metatable_index-1);
     LuaType<Element>::_regfunctions(L,metatable_index,metatable_index-1);
 }
 }
 
 
-
 template<> void LuaType<Log>::extra_init(lua_State* L, int metatable_index)
 template<> void LuaType<Log>::extra_init(lua_State* L, int metatable_index)
 {
 {
     //due to they way that LuaType::Register is made, we know that the method table is at the index
     //due to they way that LuaType::Register is made, we know that the method table is at the index