class_rep.cpp.svn-base

来自「本人找过多个在linux下c++的lua5.1封装库,但很少.luabind已经」· SVN-BASE 代码 · 共 1,676 行 · 第 1/3 页

SVN-BASE
1,676
字号
		// can only be reached if an exception was thrown		lua_error(L);#endif	}	return 0;}int luabind::detail::class_rep::lua_settable_dispatcher(lua_State* L){	class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));	// get first table	crep->get_table(L);	// copy key, value	lua_pushvalue(L, -3);	lua_pushvalue(L, -3);	lua_rawset(L, -3);	// pop table	lua_pop(L, 1);	// get default table	crep->get_default_table(L);	lua_replace(L, 1);	lua_rawset(L, -3);	crep->m_operator_cache = 0; // invalidate cache		return 0;}int luabind::detail::class_rep::construct_lua_class_callback(lua_State* L){	class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));	int args = lua_gettop(L);	// lua stack: crep <arguments>	lua_newtable(L);	detail::lua_reference ref;	ref.set(L);	bool has_bases = !crep->bases().empty();			if (has_bases)	{		lua_pushstring(L, "super");		lua_pushvalue(L, 1); // crep	}	// lua stack: crep <arguments> "super" crep	// or	// lua stack: crep <arguments>	// if we have a baseclass we set the flag to say that the super has not yet been called	// we will use this flag later to check that it actually was called from __init()	int flags = object_rep::lua_class | object_rep::owner | (has_bases ? object_rep::call_super : 0);//	void* obj_ptr = lua_newuserdata(L, sizeof(object_rep));	void* obj_ptr;	void* held_storage;	boost::tie(obj_ptr, held_storage) = crep->allocate(L);	(new(obj_ptr) object_rep(crep, flags, ref))->set_object(held_storage);	detail::getref(L, crep->metatable_ref());	lua_setmetatable(L, -2);	// lua stack: crep <arguments> "super" crep obj_ptr	// or	// lua stack: crep <arguments> obj_ptr	if (has_bases)	lua_pushvalue(L, -1); // obj_ptr	lua_replace(L, 1); // obj_ptr	// lua stack: obj_ptr <arguments> "super" crep obj_ptr	// or	// lua stack: obj_ptr <arguments>	if (has_bases)	{		lua_pushcclosure(L, super_callback, 2);		// lua stack: crep <arguments> "super" function		lua_settable(L, LUA_GLOBALSINDEX);	}	// lua stack: crep <arguments>	lua_pushvalue(L, 1);	lua_insert(L, 1);	crep->get_table(L);	lua_pushstring(L, "__init");	lua_gettable(L, -2);#ifndef LUABIND_NO_ERROR_CHECKING	// TODO: should this be a run-time error?	// maybe the default behavior should be to just call	// the base calss' constructor. We should register	// the super callback funktion as __init	if (!lua_isfunction(L, -1))	{		{			std::string msg = crep->name();			msg += ":__init is not defined";			lua_pushstring(L, msg.c_str());		}		lua_error(L);	}#endif	lua_insert(L, 2); // function first on stack	lua_pop(L, 1);	// TODO: lua_call may invoke longjump! make sure we don't have any memory leaks!	// we don't have any stack objects here	lua_call(L, args, 0);#ifndef LUABIND_NO_ERROR_CHECKING	object_rep* obj = static_cast<object_rep*>(obj_ptr);	if (obj->flags() & object_rep::call_super)	{		lua_pushstring(L, "derived class must call super on base");		lua_error(L);	}#endif	return 1;}// called from the metamethod for __index// obj is the object pointerint luabind::detail::class_rep::lua_class_gettable(lua_State* L){	object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));	class_rep* crep = obj->crep();#ifndef LUABIND_NO_ERROR_CHECKING	if (obj->flags() & object_rep::call_super)	{		lua_pushstring(L, "derived class must call super on base");		lua_error(L);	}#endif	// we have to ignore the first argument since this may point to	// a method that is not present in this class (but in a subclass)	// BUG: This might catch members called "__ok\0foobar"	const char* key = lua_tostring(L, 2);	if (key && !std::strcmp(key, "__ok"))	{		class_rep* crep = obj->crep();		void* p = crep->extractor() ? crep->extractor()(obj->ptr())			: obj->ptr();		lua_pushboolean(L, p != 0);		return 1;	}		// first look in the instance's table	detail::lua_reference const& tbl = obj->get_lua_table();	assert(tbl.is_valid());	tbl.get(L);	lua_pushvalue(L, 2);	lua_gettable(L, -2);	if (!lua_isnil(L, -1)) 	{		lua_remove(L, -2); // remove table		return 1;	}	lua_pop(L, 2);	// then look in the class' table	crep->get_table(L);	lua_pushvalue(L, 2);	lua_gettable(L, -2);	if (!lua_isnil(L, -1)) 	{		lua_remove(L, -2); // more table		return 1;	}	lua_pop(L, 2);	if (lua_isnil(L, 2))	{		lua_pushnil(L);		return 1;	}	std::map<const char*, class_rep::callback, ltstr>::iterator j = crep->m_getters.find(key);	if (j != crep->m_getters.end())	{		// the name is a data member		return j->second.func(L, j->second.pointer_offset);	}	lua_pushnil(L);	return 1;}// called from the metamethod for __newindex// obj is the object pointerint luabind::detail::class_rep::lua_class_settable(lua_State* L){	object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));	class_rep* crep = obj->crep();#ifndef LUABIND_NO_ERROR_CHECKING	if (obj->flags() & object_rep::call_super)	{		// this block makes sure the std::string is destructed		// before lua_error is called		{			std::string msg = "derived class '";			msg += crep->name();			msg += "'must call super on base";			lua_pushstring(L, msg.c_str());		}		lua_error(L);	}#endif	// we have to ignore the first argument since this may point to	// a method that is not present in this class (but in a subclass)	// BUG: This will not work with keys with extra nulls in them	const char* key = lua_tostring(L, 2);	std::map<const char*, class_rep::callback, ltstr>::iterator j = crep->m_setters.find(key);	// if the strlen(key) is not the true length,	// it means that the member-name contains	// extra nulls. luabind does not support such	// names as member names. So, use the lua	// table as fall-back	if (j == crep->m_setters.end()		|| std::strlen(key) != lua_strlen(L, 2))	{		std::map<const char*, class_rep::callback, ltstr>::iterator k = crep->m_getters.find(key);#ifndef LUABIND_NO_ERROR_CHECKING		if (k != crep->m_getters.end())		{			{				std::string msg = "cannot set property '";				msg += crep->name();				msg += ".";				msg += key;				msg += "', because it's read only";				lua_pushstring(L, msg.c_str());			}			lua_error(L);		}#endif		detail::lua_reference const& tbl = obj->get_lua_table();		assert(tbl.is_valid());		tbl.get(L);		lua_replace(L, 1);		lua_settable(L, 1);	}	else	{		// the name is a data member		j->second.func(L, j->second.pointer_offset);	}	return 0;}/*	stack:	1: class_rep	2: member name*/int luabind::detail::class_rep::static_class_gettable(lua_State* L){	class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));	// look in the static function table	crep->get_default_table(L);	lua_pushvalue(L, 2);	lua_gettable(L, -2);	if (!lua_isnil(L, -1)) return 1;	else lua_pop(L, 2);	const char* key = lua_tostring(L, 2);	if (std::strlen(key) != lua_strlen(L, 2))	{		lua_pushnil(L);		return 1;	}	std::map<const char*, int, ltstr>::const_iterator j = crep->m_static_constants.find(key);	if (j != crep->m_static_constants.end())	{		lua_pushnumber(L, j->second);		return 1;	}#ifndef LUABIND_NO_ERROR_CHECKING	{		std::string msg = "no static '";		msg += key;		msg += "' in class '";		msg += crep->name();		msg += "'";		lua_pushstring(L, msg.c_str());	}	lua_error(L);#endif	lua_pushnil(L);	return 1;}bool luabind::detail::is_class_rep(lua_State* L, int index){	if (lua_getmetatable(L, index) == 0) return false;	lua_pushstring(L, "__luabind_classrep");	lua_gettable(L, -2);	if (lua_toboolean(L, -1))	{		lua_pop(L, 2);		return true;	}	lua_pop(L, 2);	return false;}void luabind::detail::finalize(lua_State* L, class_rep* crep){	if (crep->get_class_type() != class_rep::lua_class) return;//	lua_pushvalue(L, -1); // copy the object ref	crep->get_table(L);	lua_pushstring(L, "__finalize");	lua_gettable(L, -2);	lua_remove(L, -2);	if (lua_isnil(L, -1))	{		lua_pop(L, 1);	}	else	{		lua_pushvalue(L, -2);		lua_call(L, 1, 0);	}	for (std::vector<class_rep::base_info>::const_iterator 			i = crep->bases().begin(); i != crep->bases().end(); ++i)	{		if (i->base) finalize(L, i->base);	}}void* luabind::detail::class_rep::convert_to(	LUABIND_TYPE_INFO target_type	, const object_rep* obj	, void* target_memory) const{	// TODO: since this is a member function, we don't have to use the accesor functions for	// the types and the extractor	assert(obj == 0 || obj->crep() == this);	int steps = 0;	int offset = 0;	if (!(LUABIND_TYPE_INFO_EQUAL(holder_type(), target_type))		&& !(LUABIND_TYPE_INFO_EQUAL(const_holder_type(), target_type)))	{		steps = implicit_cast(this, target_type, offset);	}	// should never be called with a type that can't be cast	assert((steps >= 0) && "internal error, please report");	if (LUABIND_TYPE_INFO_EQUAL(target_type, holder_type()))	{		if (obj == 0)		{			// we are trying to convert nil to a holder type			m_default_construct_holder(target_memory);			return target_memory;		}		// if the type we are trying to convert to is the holder_type		// it means that his crep has a holder_type (since it would have		// been invalid otherwise, and T cannot be invalid). It also means		// that we need no conversion, since the holder_type is what the		// object points to.		return obj->ptr();	}	if (LUABIND_TYPE_INFO_EQUAL(target_type, const_holder_type()))	{		if (obj == 0)		{			// we are trying to convert nil to a const holder type			m_default_construct_const_holder(target_memory);			return target_memory;		}		if (obj->flags() & object_rep::constant)		{			// we are holding a constant			return obj->ptr();		}		else		{			// we are holding a non-constant, we need to convert it			// to a const_holder.			m_const_converter(obj->ptr(), target_memory);			return target_memory;		}	}	void* raw_pointer;	if (has_holder())	{		assert(obj);		// this means that we have a holder type where the		// raw-pointer needs to be extracted		raw_pointer = extractor()(obj->ptr());	}	else	{		if (obj == 0) raw_pointer = 0;		else raw_pointer = obj->ptr();	}	return static_cast<char*>(raw_pointer) + offset;}void luabind::detail::class_rep::cache_operators(lua_State* L){	m_operator_cache = 0x1;	for (int i = 0; i < number_of_operators; ++i)	{		get_table(L);		lua_pushstring(L, get_operator_name(i));		lua_rawget(L, -2);		if (lua_isfunction(L, -1)) m_operator_cache |= 1 << (i + 1);		lua_pop(L, 2);	}}bool luabind::detail::class_rep::has_operator_in_lua(lua_State* L, int id){	if ((m_operator_cache & 0x1) == 0)		cache_operators(L);	const int mask = 1 << (id + 1);	return (m_operator_cache & mask) != 0;}// this will merge all overloads of fun into the list of// overloads in this classvoid luabind::detail::class_rep::add_method(luabind::detail::method_rep const& fun){	typedef std::list<detail::method_rep> methods_t;	methods_t::iterator m = std::find_if(		m_methods.begin()		, m_methods.end()		, method_name(fun.name));	if (m == m_methods.end())	{		m_methods.push_back(method_rep());		m = m_methods.end();		std::advance(m, -1);		m->name = fun.name;	}	m->crep = this;	typedef std::vector<detail::overload_rep> overloads_t;    for (overloads_t::const_iterator j = fun.overloads().begin();		j != fun.overloads().end(); ++j)    {        detail::overload_rep o = *j;        m->add_overload(o);    }}// this function will add all the overloads in method rep to// this class' lua tables. If there already are overloads with this// name, thses will simply be appended to the overload listvoid luabind::detail::class_rep::register_methods(lua_State* L){	LUABIND_CHECK_STACK(L);	// insert the function in the normal member table	// and in the default member table	m_default_table.push(L);	m_table.push(L);	// pops the tables	detail::stack_pop pop_tables(L, 2);	for (std::list<method_rep>::const_iterator m = m_methods.begin();		m != m_methods.end(); ++m)	{		// create the function closure in m_table		lua_pushstring(L, m->name);		lua_pushlightuserdata(L, const_cast<void*>((const void*)&(*m)));		lua_pushboolean(L, 0);		lua_pushlightuserdata(L, reinterpret_cast<void*>(0x1337));		lua_pushcclosure(L, function_dispatcher, 3);		lua_settable(L, -3);		// create the function closure in m_default_table		lua_pushstring(L, m->name);		lua_pushlightuserdata(L, const_cast<void*>((const void*)&(*m)));		lua_pushboolean(L, 1);		lua_pushlightuserdata(L, reinterpret_cast<void*>(0x1337));		lua_pushcclosure(L, function_dispatcher, 3);		lua_settable(L, -4);	}}const class_rep::property_map& luabind::detail::class_rep::properties() const{	return m_getters;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?