예제 #1
0
		LuaRef registerClass(lua_State* state)const
		{
			util::ScopedSavedStack save(state);
			if (class_userdata::newmetatable<class_type>(state))
			{
				LuaTable metatable(state, StackTop());
				metatable.push();
				registerMember(state);

				if (!traits::is_same<base_class_type, void>::value || !property_map_.empty())//if base class has property and derived class hasnt property. need property access metamethod
				{
					for (PropMapType::const_iterator it = property_map_.begin(); it != property_map_.end(); ++it)
					{
						int count = lua_type_traits<FunctorType>::push(state, it->second);
						if (count > 1)
						{
							lua_pop(state, count - 1);
							count = 1;
						}
						if (count == 1)
						{
							lua_setfield(state, -2, ("_prop_" + it->first).c_str());
						}
					}
					LuaFunction indexfun = kaguya::LuaFunction::loadstring(state, "local arg = {...};local metatable = arg[1];"
						"return function(table, index)"
//						" if type(table) == 'userdata' then "
						" local propfun = metatable['_prop_'..index];"
						" if propfun then return propfun(table) end "
//						" end "
						" return metatable[index]"
						" end")(metatable);

					metatable.setField("__index", indexfun);

					LuaFunction newindexfn = LuaFunction::loadstring(state, "local arg = {...};local metatable = arg[1];"
						" return function(table, index, value) "
						" if type(table) == 'userdata' then "
						" local propfun = metatable['_prop_'..index];"
						" if propfun then return propfun(table,value) end "
						" end "
						" rawset(table,index,value) "
						" end")(metatable);
					metatable.setField("__newindex", newindexfn);
				}
				else
				{
					metatable.setField("__index", metatable);
				}

				set_base_metatable(state, metatable, types::typetag<base_class_type>());

				return metatable;
			}
			else
			{
				except::OtherError(state, typeid(class_type*).name() + std::string(" is already registered"));
			}
			return LuaRef(state);
		}
예제 #2
0
		LuaTable createMatatable(lua_State* state)const
		{
			util::ScopedSavedStack save(state);
			if (!class_userdata::newmetatable<class_type>(state))
			{
				except::OtherError(state, typeid(class_type*).name() + std::string(" is already registered"));
				return LuaTable();
			}
			int metatable_index = lua_gettop(state);
			Metatable::setMembers(state, metatable_index,member_map_,property_map_);

			if (!traits::is_same<base_class_type, void>::value || !property_map_.empty())//if base class has property and derived class hasnt property. need property access metamethod
			{
				if (member_map_.count("__index") == 0)
				{
					Metatable::setPropertyIndexMetamethod(state, metatable_index);
				}

				if (member_map_.count("__newindex") == 0)
				{
					Metatable::setPropertyNewIndexMetamethod(state, metatable_index);
				}
			}
			else
			{
				if (member_map_.count("__index") == 0)
				{
					lua_pushstring(state, "__index");
					lua_pushvalue(state, metatable_index);
					lua_rawset(state, metatable_index);
				}
			}

			set_base_metatable(state, metatable_index, types::typetag<base_class_type>());

			if (lua_getmetatable(state, metatable_index))//get base_metatable
			{
				lua_pushstring(state, "__call");
				lua_pushcfunction(state, &Metatable::call_constructor_function);
				lua_rawset(state,-3);//base_metatable["__call"] = Metatable::call_constructor_function
			}
			else
			{
				Metatable::get_call_constructor_metatable(state);
				lua_setmetatable(state, metatable_index);
			}

			return LuaStackRef(state, metatable_index);
		}
예제 #3
0
		LuaTable createMatatable(lua_State* state)const
		{
			util::ScopedSavedStack save(state);
			if (class_userdata::newmetatable<class_type>(state))
			{
				LuaStackRef metatable(state, -1);
				registerMember(state);

				if (!traits::is_same<base_class_type, void>::value || !property_map_.empty())//if base class has property and derived class hasnt property. need property access metamethod
				{
					LuaFunction indexfun = kaguya::LuaFunction::loadstring(state, "local arg = {...};local metatable = arg[1];"
						"return function(table, index)"
						//						" if type(table) == 'userdata' then "
						" local propfun = metatable['_prop_'..index];"
						" if propfun then return propfun(table) end "
						//						" end "
						" return metatable[index]"
						" end")(metatable);

					metatable.setField("__index", indexfun);

					LuaFunction newindexfn = LuaFunction::loadstring(state, "local arg = {...};local metatable = arg[1];"
						" return function(table, index, value) "
						" if type(table) == 'userdata' then "
						" local propfun = metatable['_prop_'..index];"
						" if propfun then return propfun(table,value) end "
						" end "
						" rawset(table,index,value) "
						" end")(metatable);
					metatable.setField("__newindex", newindexfn);
				}
				else
				{
					metatable.setField("__index", metatable);
				}

				set_base_metatable(state, metatable, types::typetag<base_class_type>());

				return metatable;
			}
			else
			{
				except::OtherError(state, typeid(class_type*).name() + std::string(" is already registered"));
			}
			return LuaTable();
		}