Browse Source

Changed all of the __call metamethods to type:new functions due to some metamethod black magic not happening.

Implemented a DataSource type for Lua.
Nate Starkey 13 years ago
parent
commit
7a17a2d32f

+ 16 - 0
Build/RocketLua.vcproj

@@ -180,6 +180,14 @@
 		<Filter
 			Name="Controls"
 			>
+			<File
+				RelativePath="..\Source\Controls\Lua\DataSource.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\Source\Controls\Lua\DataSource.h"
+				>
+			</File>
 			<File
 				RelativePath="..\Source\Controls\Lua\ElementDataGrid.cpp"
 				>
@@ -204,6 +212,14 @@
 				RelativePath="..\Source\Controls\Lua\ElementTabSet.h"
 				>
 			</File>
+			<File
+				RelativePath="..\Source\Controls\Lua\LuaDataSource.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\Source\Controls\Lua\LuaDataSource.h"
+				>
+			</File>
 			<Filter
 				Name="Forms"
 				>

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

@@ -39,7 +39,7 @@ namespace Lua {
     template<> luaL_reg* GetAttrTable<type>() { return type##Getters; } \
     template<> luaL_reg* SetAttrTable<type>() { return type##Setters; } \
 
-//put this in the type.h file
+//put this in the type.h file  NOT USED at this moment
 #define LUATYPEDECLARE(type) \
     template<> const char* GetTClassName<type>(); \
     template<> RegType<type>* GetMethodTable<type>(); \

+ 98 - 0
Source/Controls/Lua/DataSource.cpp

@@ -0,0 +1,98 @@
+#include "precompiled.h"
+#include "DataSource.h"
+#include <Rocket/Core/Log.h>
+
+namespace Rocket {
+namespace Core {
+namespace Lua {
+typedef LuaDataSource DataSource;
+
+int DataSourceNotifyRowAdd(lua_State* L, DataSource* obj)
+{
+    LUACHECKOBJ(obj);
+    const char* table_name = luaL_checkstring(L,1);
+    int first_row_added = luaL_checkint(L,2);
+    int num_rows_added = luaL_checkint(L,3);
+    obj->NotifyRowAdd(table_name,first_row_added,num_rows_added);
+    return 0;
+}
+
+int DataSourceNotifyRowRemove(lua_State* L, DataSource* obj)
+{
+    LUACHECKOBJ(obj);
+    const char* table_name = luaL_checkstring(L,1);
+    int first_row_removed = luaL_checkint(L,2);
+    int num_rows_removed = luaL_checkint(L,3);
+    obj->NotifyRowRemove(table_name,first_row_removed,num_rows_removed);
+    return 0;
+}
+
+int DataSourceNotifyRowChange(lua_State* L, DataSource* obj)
+{
+    LUACHECKOBJ(obj);
+    const char* table_name = luaL_checkstring(L,1);
+    if(lua_gettop(L) < 2)
+    {
+        obj->NotifyRowChange(table_name);
+    }
+    else
+    {
+        int first_row_changed = luaL_checkint(L,2);
+        int num_rows_changed = luaL_checkint(L,3);
+        obj->NotifyRowChange(table_name,first_row_changed,num_rows_changed);
+    }
+    return 0;
+}
+
+int DataSourceSetAttrGetNumRows(lua_State* L)
+{
+    DataSource* obj = LuaType<DataSource>::check(L,1);
+    LUACHECKOBJ(obj);
+    if(lua_type(L,2) == LUA_TFUNCTION)
+    {
+        lua_pushvalue(L,2); //copy of the function, so it is for sure at the top of the stack
+        obj->getNumRowsRef = lua_ref(L,true);
+    }
+    else
+        Log::Message(Log::LT_WARNING, "Lua: Must assign DataSource.GetNumRows as a function, value received was of %s type", lua_typename(L,2));
+    return 0;
+}
+
+int DataSourceSetAttrGetRow(lua_State* L)
+{
+    DataSource* obj = LuaType<DataSource>::check(L,1);
+    LUACHECKOBJ(obj);
+    if(lua_type(L,2) == LUA_TFUNCTION)
+    {
+        lua_pushvalue(L,2); //copy of the functions, so it is for sure at the top of the stack
+        obj->getRowRef = lua_ref(L,true);
+    }
+    else
+        Log::Message(Log::LT_WARNING, "Lua: Must assign DataSource.GetRow as a function, value received was of %s type", lua_typename(L,2));
+    return 0;
+}
+
+
+RegType<DataSource> DataSourceMethods[] =
+{
+    LUAMETHOD(DataSource,NotifyRowAdd)
+    LUAMETHOD(DataSource,NotifyRowRemove)
+    LUAMETHOD(DataSource,NotifyRowChange)
+    { NULL, NULL },
+};
+
+luaL_reg DataSourceGetters[] =
+{
+    { NULL, NULL },
+};
+
+luaL_reg DataSourceSetters[] =
+{
+    LUASETTER(DataSource,GetNumRows)
+    LUASETTER(DataSource,GetRow)
+    { NULL, NULL },
+};
+
+}
+}
+}

+ 41 - 0
Source/Controls/Lua/DataSource.h

@@ -0,0 +1,41 @@
+#pragma once
+
+/*
+    This defines the DataSource type in the Lua global namespace
+    
+    //methods
+    noreturn DataSource:NotifyRowAdd(string tablename, int firstadded, int numadded)
+    noreturn DataSource:NotifyRemove(string tablename, int firstremoved, int numremoved)
+    noreturn DataSource:NotifyRowChange(string tablename, int firstchanged, int numchanged)
+    noreturn DataSource:NotifyRowChange(string tablename) --the same as above, but for all rows
+    
+    when you get an instance of this, you MUST set two functions:
+    DataSource.GetNumRows = function(tablename) ....... end --returns an int
+    DataSource.GetRow = function(tablename,index,columns) ......end
+    --where columns is a numerically indexed table of strings, and the function needs to
+    --return a table of numerically indexed strings
+*/
+
+#include <Rocket/Core/Lua/LuaType.h>
+#include <Rocket/Core/Lua/lua.hpp>
+#include "LuaDataSource.h"
+
+namespace Rocket {
+namespace Core {
+namespace Lua {
+typedef LuaDataSource DataSource;
+
+int DataSourceNotifyRowAdd(lua_State* L, DataSource* obj);
+int DataSourceNotifyRowRemove(lua_State* L, DataSource* obj);
+int DataSourceNotifyRowChange(lua_State* L, DataSource* obj);
+
+int DataSourceSetAttrGetNumRows(lua_State* L);
+int DataSourceSetAttrGetRow(lua_State* L);
+
+RegType<DataSource> DataSourceMethods[];
+luaL_reg DataSourceGetters[];
+luaL_reg DataSourceSetters[];
+
+}
+}
+}

+ 82 - 0
Source/Controls/Lua/LuaDataSource.cpp

@@ -0,0 +1,82 @@
+#include "precompiled.h"
+#include "LuaDataSource.h"
+#include <Rocket/Core/Lua/Interpreter.h>
+#include <Rocket/Core/Log.h>
+
+namespace Rocket {
+namespace Core {
+namespace Lua {
+
+LuaDataSource::LuaDataSource(const String& name) : DataSource(name), getRowRef(LUA_NOREF), getNumRowsRef(LUA_NOREF)
+{
+}
+
+/// Fetches the contents of one row of a table within the data source.
+/// @param[out] row The list of values in the table.
+/// @param[in] table The name of the table to query.
+/// @param[in] row_index The index of the desired row.
+/// @param[in] columns The list of desired columns within the row.
+void LuaDataSource::GetRow(Rocket::Core::StringList& row, const Rocket::Core::String& table, int row_index, const Rocket::Core::StringList& columns)
+{
+    if(getRowRef == LUA_NOREF || getRowRef == LUA_REFNIL) return;
+
+    //setup the call
+    Interpreter::BeginCall(getRowRef);
+    lua_State* L = Interpreter::GetLuaState();
+    lua_pushstring(L,table.CString());
+    lua_pushinteger(L,row_index);
+    lua_newtable(L);
+    int index = 0;
+    for(StringList::const_iterator itr = columns.begin(); itr != columns.end(); ++itr)
+    {
+        lua_pushstring(L,itr->CString());
+        lua_rawseti(L,-2,index++);
+    }
+    Interpreter::ExecuteCall(3,1); //3 parameters, 1 return. After here, the top of the stack contains the return value
+
+    int res = lua_gettop(L);
+    if(lua_type(L,res) == LUA_TTABLE)
+    {
+        lua_pushnil(L);
+        while(lua_next(L,res) != 0)
+        {
+            //key at -2, value at -1
+            row.push_back(luaL_checkstring(L,-1));
+            lua_pop(L,1); //pops value, leaves key for next iteration
+        }
+        lua_pop(L,1); //pop key
+    }
+    else
+        Log::Message(Log::LT_WARNING, "Lua: DataSource.GetRow must return a table, the function it called returned a %s", lua_typename(L,res));
+
+    Interpreter::EndCall(1);
+}
+
+/// Fetches the number of rows within one of this data source's tables.
+/// @param[in] table The name of the table to query.
+/// @return The number of rows within the specified table. Returns -1 in case of an incorrect Lua function.
+int LuaDataSource::GetNumRows(const Rocket::Core::String& table)
+{
+    if(getNumRowsRef == LUA_NOREF || getNumRowsRef == LUA_REFNIL) return -1;
+
+    lua_State* L = Interpreter::GetLuaState();
+    Interpreter::BeginCall(getNumRowsRef);
+    lua_pushstring(L,table.CString());
+    Interpreter::ExecuteCall(1,1); //1 parameter, 1 return. After this, the top of the stack contains the return value
+
+    int res = lua_gettop(L);
+    if(lua_type(L,res) == LUA_TNUMBER)
+    {
+        return luaL_checkint(L,res);
+    }
+    else
+    {
+        Log::Message(Log::LT_WARNING, "Lua: DataSource.GetNumRows must return an integer, the function it called returned a %s", lua_typename(L,res));
+        return -1;
+    }
+
+}
+
+}
+}
+}

+ 42 - 0
Source/Controls/Lua/LuaDataSource.h

@@ -0,0 +1,42 @@
+#pragma once
+
+#include <Rocket/Core/Lua/LuaType.h>
+#include <Rocket/Core/Lua/lua.hpp>
+#include <Rocket/Controls/DataSource.h>
+
+using Rocket::Controls::DataSource;
+namespace Rocket {
+namespace Core {
+namespace Lua {
+
+class LuaDataSource : public DataSource
+{
+public:
+    //default initilialize the lua func references to -1
+    LuaDataSource(const String& name = "");
+
+	/// Fetches the contents of one row of a table within the data source.
+	/// @param[out] row The list of values in the table.
+	/// @param[in] table The name of the table to query.
+	/// @param[in] row_index The index of the desired row.
+	/// @param[in] columns The list of desired columns within the row.
+	virtual void GetRow(Rocket::Core::StringList& row, const Rocket::Core::String& table, int row_index, const Rocket::Core::StringList& columns);
+	/// Fetches the number of rows within one of this data source's tables.
+	/// @param[in] table The name of the table to query.
+	/// @return The number of rows within the specified table. Returns -1 in case of an incorrect Lua function.
+	virtual int GetNumRows(const Rocket::Core::String& table);
+
+    //make the protected members of DataSource public
+    using DataSource::NotifyRowAdd;
+    using DataSource::NotifyRowRemove;
+    using DataSource::NotifyRowChange;
+
+    //lua reference to DataSource.GetRow
+    int getRowRef;
+    //lua reference to DataSource.GetNumRows
+    int getNumRowsRef;
+};
+
+}
+}
+}

+ 1 - 1
Source/Core/Lua/Colourb.cpp

@@ -5,7 +5,7 @@
 namespace Rocket {
 namespace Core {
 namespace Lua {
-int Colourb__call(lua_State* L)
+int Colourbnew(lua_State* L)
 {
     byte red = (byte)luaL_checkint(L,1);
     byte green = (byte)luaL_checkint(L,2);

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

@@ -35,7 +35,7 @@ namespace Rocket {
 namespace Core {
 namespace Lua {
 template<> void LuaType<Colourb>::extra_init(lua_State* L, int metatable_index);
-int Colourb__call(lua_State* L);
+int Colourbnew(lua_State* L);
 int Colourb__eq(lua_State* L);
 int Colourb__add(lua_State* L);
 int Colourb__mul(lua_State* L);

+ 1 - 1
Source/Core/Lua/Colourf.cpp

@@ -9,7 +9,7 @@ namespace Lua {
 //metamethods
 
 
-int Colourf__call(lua_State* L)
+int Colourfnew(lua_State* L)
 {
     float red = (float)luaL_checknumber(L,1);
     float green = (float)luaL_checknumber(L,2);

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

@@ -33,7 +33,7 @@ namespace Core {
 namespace Lua {
 template<> void LuaType<Colourf>::extra_init(lua_State* L, int metatable_index);
 //metamethods
-int Colourf__call(lua_State* L);
+int Colourfnew(lua_State* L);
 int Colourf__eq(lua_State* L);
 
 //getters

+ 1 - 1
Source/Core/Lua/LuaDocument.cpp

@@ -22,7 +22,7 @@ void LuaDocument::LoadScript(Stream* stream, const String& source_name)
     else
     {
         String buffer = "";
-        stream.Read(buffer,stream.Length()); //just do the whole thing
+        stream->Read(buffer,stream->Length()); //just do the whole thing
         Interpreter::DoString(buffer);
     }
 }

+ 12 - 9
Source/Core/Lua/LuaTypeTemplateSpec.inl

@@ -1,6 +1,6 @@
 /*
     Because all of the template specializations have to be compiled in the same translation unit, they have to 
-    exist in this file. It is included by LuaType.inl
+    exist in this file. It is included by LuaType.cpp
 */
 #include "precompiled.h"
 #include <Rocket/Core/Core.h>
@@ -26,6 +26,7 @@
 #include "ElementDataGrid.h"
 #include "ElementDataGridRow.h"
 #include "ElementTabSet.h"
+#include "DataSource.h"
 
 
 
@@ -54,6 +55,7 @@ LUATYPEDEFINE(ElementFormControlTextArea)
 LUATYPEDEFINE(ElementDataGrid)
 LUATYPEDEFINE(ElementDataGridRow)
 LUATYPEDEFINE(ElementTabSet)
+LUATYPEDEFINE(DataSource)
 
 
 template class LuaType<Colourb>;
@@ -76,6 +78,7 @@ template class LuaType<ElementFormControlTextArea>;
 template class LuaType<ElementDataGrid>;
 template class LuaType<ElementDataGridRow>;
 template class LuaType<ElementTabSet>;
+template class LuaType<DataSource>;
 
 
 
@@ -111,8 +114,8 @@ template<> void LuaType<rocket>::extra_init(lua_State* L, int metatable_index)
 
 template<> void LuaType<Colourb>::extra_init(lua_State* L, int metatable_index)
 {
-    lua_pushcfunction(L,Colourb__call);
-    lua_setfield(L,metatable_index,"__call");
+    lua_pushcfunction(L,Colourbnew);
+    lua_setfield(L,metatable_index-1,"new");
 
     lua_pushcfunction(L,Colourb__eq);
     lua_setfield(L,metatable_index,"__eq");
@@ -129,8 +132,8 @@ template<> void LuaType<Colourb>::extra_init(lua_State* L, int metatable_index)
 
 template<> void LuaType<Colourf>::extra_init(lua_State* L, int metatable_index)
 {
-    lua_pushcfunction(L,Colourf__call);
-    lua_setfield(L,metatable_index,"__call");
+    lua_pushcfunction(L,Colourfnew);
+    lua_setfield(L,metatable_index-1,"new");
 
     lua_pushcfunction(L,Colourf__eq);
     lua_setfield(L,metatable_index,"__eq");
@@ -142,8 +145,8 @@ template<> void LuaType<Colourf>::extra_init(lua_State* L, int metatable_index)
 template<> 
 void LuaType<Vector2f>::extra_init(lua_State* L, int metatable_index)
 {
-    lua_pushcfunction(L,Vector2f__call);
-    lua_setfield(L,metatable_index,"__call");
+    lua_pushcfunction(L,Vector2fnew);
+    lua_setfield(L,metatable_index-1,"new");
 
     lua_pushcfunction(L,Vector2f__mul);
     lua_setfield(L,metatable_index,"__mul");
@@ -167,8 +170,8 @@ void LuaType<Vector2f>::extra_init(lua_State* L, int metatable_index)
 template<> 
 void LuaType<Vector2i>::extra_init(lua_State* L, int metatable_index)
 {
-    lua_pushcfunction(L,Vector2i__call);
-    lua_setfield(L,metatable_index,"__call");
+    lua_pushcfunction(L,Vector2inew);
+    lua_setfield(L,metatable_index-1,"new");
 
     lua_pushcfunction(L,Vector2i__mul);
     lua_setfield(L,metatable_index,"__mul");

+ 1 - 1
Source/Core/Lua/Vector2f.cpp

@@ -8,7 +8,7 @@ namespace Lua {
 
 
 
-int Vector2f__call(lua_State* L)
+int Vector2fnew(lua_State* L)
 {
     float x = (float)luaL_checknumber(L,1);
     float y = (float)luaL_checknumber(L,2);

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

@@ -35,7 +35,7 @@ namespace Rocket {
 namespace Core {
 namespace Lua {
 template<> void LuaType<Vector2f>::extra_init(lua_State* L, int metatable_index);
-int Vector2f__call(lua_State* L);
+int Vector2fnew(lua_State* L);
 int Vector2f__mul(lua_State* L);
 int Vector2f__div(lua_State* L);
 int Vector2f__add(lua_State* L);

+ 1 - 1
Source/Core/Lua/Vector2i.cpp

@@ -7,7 +7,7 @@ namespace Core {
 namespace Lua {
 
 
-int Vector2i__call(lua_State* L)
+int Vector2inew(lua_State* L)
 {
     int x = luaL_checkint(L,1);
     int y = luaL_checkint(L,2);

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

@@ -28,7 +28,7 @@ namespace Rocket {
 namespace Core {
 namespace Lua {
 template<> void LuaType<Vector2i>::extra_init(lua_State* L, int metatable_index);
-int Vector2i__call(lua_State* L);
+int Vector2inew(lua_State* L);
 int Vector2i__mul(lua_State* L);
 int Vector2i__div(lua_State* L);
 int Vector2i__add(lua_State* L);