示例#1
0
	bool HybridBase::getMethod(const char *name) const
	{
		SLB_DEBUG_CALL;
		if (_L == 0) throw std::runtime_error("Hybrid instance not attached");\
		SLB_DEBUG_STACK(5,_L, "HybridBase(%p)::getMethod '%s' (_L = %p)", this, name, _L); 
		int top = lua_gettop(_L);

		// first try to find in _subclassMethods
		if (_subclassMethods.valid())
		{
			//TODO: NEED DEBUG...
			// ---- why not:
			// Object *m = obj->_subclassMethods->get(key);
			// if (m)
			// {
			// 	SLB_DEBUG(5, "Hybrid subclassed instance, looking for '%s' method [OK]", key);
			// 	m->push(L);
			// 	return 1;
			// }
			// else SLB_DEBUG(5, "Hybrid subclassed instance, looking for '%s' method [FAIL!]", key);
			// ---- instead of: (even though this is quicker) but code above should work
			lua_pushstring(_L,name); // [+1]
			_subclassMethods->getCache(_L); // [-1, +1] will pop key's copy and return the cache 
			if (!lua_isnil(_L,-1))
			{
				assert("Invalid Stack" && (lua_gettop(_L) == top+1));
				return true;
			}
			lua_pop(_L,1); // [-1] remove nil
			assert("Invalid Stack" && (lua_gettop(_L) == top));
			//end TODO-------------------------------------------------------------------------------
		}

		ClassInfo *ci = getClassInfo();
		ci->push(_L);
		lua_getmetatable(_L,-1);
		lua_getfield(_L,-1, "__hybrid");
		if (!lua_isnil(_L,-1))
		{
			lua_pushstring(_L,name);
			lua_rawget(_L,-2);
			if (!lua_isnil(_L,-1))
			{
				lua_replace(_L,top+1);
				lua_settop(_L,top+1);
				SLB_DEBUG(6, "HybridBase(%p-%s)::getMethod '%s' (_L = %p) -> FOUND",
						this, ci->getName().c_str(),name, _L); 
				assert("Invalid Stack" && (lua_gettop(_L) == top+1));
				return true;
			}
			else SLB_DEBUG(6, "HybridBase(%p-%s)::getMethod '%s' (_L = %p) -> *NOT* FOUND",
				this,ci->getName().c_str(), name, _L); 
		}
		else SLB_DEBUG(4, "HybridBase(%p-%s) do not have any hybrid methods", this, ci->getName().c_str());

		// anyway... if not found:
		lua_settop(_L,top);
		return false;
	}
示例#2
0
	int HybridBase::class__index(lua_State *L)
	{
		SLB_DEBUG_CALL;
		SLB_DEBUG_CLEAN_STACK(L,+1);
		SLB_DEBUG_STACK(6, L, "Call class__index");
		// trying to traverse the class... create a new InternalHybridSubclass
		ClassInfo *ci = Manager::getInstance().getClass(L,1);
		if (ci == 0) luaL_error(L, "Expected a valid class.");
		luaL_checkstring(L,2); // only valid with strings
		if (!ci->hasConstructor())
		{
			luaL_error(L, "Hybrid Class(%s) doesn't have constructor."
				" You can not subclass(%s) from it", ci->getName().c_str(),
				lua_tostring(L,2));
		}

		ref_ptr<InternalHybridSubclass> subc = new InternalHybridSubclass(ci);
		subc->push(L);

		// -- set cache...
		lua_pushvalue(L,2);  // [+1] key
		lua_pushvalue(L,-2); // [+1] copy of new InternalHybrid...
		ci->setCache(L);     // [-2] keep a copy in the cache
		// -- set cache done

		return 1;
	}
示例#3
0
	const HybridBase* get_hybrid(lua_State *L, int pos)
	{
		SLB_DEBUG_CALL;
		//TODO: Generalize this to be used in all SLB
		const HybridBase *obj = get<const HybridBase*>(L,pos);
		if (!obj)
		{
			if (lua_type(L,pos) == LUA_TUSERDATA)
			{
				void *dir = lua_touserdata(L,pos);
				// try to get the class info:
				ClassInfo *ci = Manager::getInstance().getClass(L,pos);
				if (ci == 0)
				{
					luaL_error(L, "Invalid Hybrid object (index=%d) "
					"'%s' %p", pos, ci->getName().c_str(), dir);
				}
				else
				{
					luaL_error(L, "Invalid Hybrid object (index=%d) "
					"userdata (NOT REGISTERED WITH SLB) %p", pos, dir);
				}
			}
			else
			{
				luaL_error(L, "Invalid Hybrid object (index=%d) found %s", pos, luaL_typename(L,pos));
			}
		}
		return obj;
	}
示例#4
0
	/*--- Invalid Method (exception) ----------------------------------------------*/
 	InvalidMethod::InvalidMethod(const HybridBase *obj, const char *c)
	{
		SLB_DEBUG_CALL;
		lua_State  *L = obj->getLuaState();
		const ClassInfo  *CI = obj->getClassInfo();
		std::ostringstream out;
		lua_Debug debug;

		out << "Invalid Method '" << CI->getName() << "::" <<
			c << "' NOT FOUND!" << std::endl;
		out << "TraceBack:" << std::endl;
		for ( int level = 0; lua_getstack(L, level, &debug ); level++)
		{
			if (lua_getinfo(L, "Sln", &debug) )
			{
				//TODO use debug.name and debug.namewhat
				//make this more friendly
				out << "\t [ " << level << " (" << debug.what << ") ] ";
				if (debug.currentline > 0 )
				{
					out << debug.short_src << ":" << debug.currentline; 
					if (debug.name)
						out << " @ " << debug.name << "(" << debug.namewhat << ")";
				}
				out << std::endl;
			}
			else
			{
				out << "[ERROR using Lua DEBUG INTERFACE]" << std::endl;
			}
		}
		out << "Current Stack:" << std::endl;
		for(int i = 1; i < lua_gettop(L); ++i)
		{
			out << "\t ["<<i<<"] " << lua_typename(L, lua_type(L,i))
				<< " : "<< lua_tostring(L,i) ;
			ClassInfo *ci = Manager::getInstance().getClass(L,i);
			if (ci) out << "->" << ci->getName();
			out << std::endl;
		}
		
		_what = out.str();
	}