Example #1
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;
	}
Example #2
0
 int Table::__eq(lua_State *L)
 {
   SLB_DEBUG_CALL;
   SLB_DEBUG_STACK(10,L,"Table::__eq (%p)",this);
   luaL_error(L, "__eq metamethod called but no implementation was given");
   return 0;
 }
Example #3
0
 int Table::__garbageCollector(lua_State *L)
 {
   SLB_DEBUG_CALL;
   SLB_DEBUG_STACK(10,L,"Table::__GC (%p)",this);
   luaL_error(L, "(%p) __gc metamethod not implemented", (void*)this);
   return 0;
 }
Example #4
0
 int Table::__call(lua_State *L)
 {
   SLB_DEBUG_CALL;
   SLB_DEBUG_STACK(10,L,"Table::__call (%p)",this);
   luaL_error(L, "(%p)__call metamethod not implemented", (void*)this);
   return 0;
 }
Example #5
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;
	}
Example #6
0
 void Table::getCache(lua_State *L)
 {
   SLB_DEBUG_CALL;
   SLB_DEBUG_CLEAN_STACK(L,0);
   SLB_DEBUG_STACK(8, L, "Table(%p) :: getCache BEGIN ", this);
   int top = lua_gettop(L);
   if (top < 1 ) luaL_error(L, "Not enough elements to perform Table::getCache");
   push(L); // [+1] push ::Table 
   if (!luaL_getmetafield(L,-1, "__indexCache")) // [+1]
   {
     luaL_error(L, "Invalid setCache;  %s:%d", __FILE__, __LINE__ );
   }
   lua_pushvalue(L, top); // [+1] copy value
   lua_rawget(L, -2); // [-2]
   SLB_DEBUG_STACK(8, L, "Table(%p) :: getCache END (result is at top) top was = %d", this, top);
   lua_replace(L, top); // [-1,+1] as result
   lua_settop(L, top);
 }
Example #7
0
 void Table::setCache(lua_State *L)
 {
   SLB_DEBUG_CALL;
   SLB_DEBUG_CLEAN_STACK(L,-2);
   SLB_DEBUG_STACK(8, L, "Table(%p) :: setCache BEGIN ", this);
   int top = lua_gettop(L);
   if (top < 2 ) luaL_error(L, "Not enough elements to perform Table::setCache");
   push(L); // push ::Table
   if (luaL_getmetafield(L,-1, "__indexCache"))
   {
     lua_insert(L, top - 1); // move the metatable above key,value
     lua_settop(L, top + 1); // remove everything else
     lua_rawset(L,-3);
   }
   else
   {
     luaL_error(L, "Invalid setCache;  %s:%d", __FILE__, __LINE__ );
   }
   SLB_DEBUG_STACK(8, L, "Table(%p) :: setCache END original top = %d", this, top);
   lua_settop(L, top - 2);
 }
Example #8
0
  int Table::__meta(lua_State *L)
  {
    SLB_DEBUG_CALL;
    SLB_DEBUG_STACK(10,L,"Table::__meta (static method)");
    // upvalue(1) is the cache table...
    void *table_raw = lua_touserdata(L, lua_upvalueindex(2));
    void *table_member_raw = lua_touserdata(L, lua_upvalueindex(3));
    Table *table = reinterpret_cast<Table*>(table_raw);
    TableMember member = *reinterpret_cast<TableMember*>(table_member_raw);

    return (table->*member)(L);
  }
Example #9
0
 int Table::__tostring(lua_State *L)
 {
   SLB_DEBUG_CALL;
   SLB_DEBUG_STACK(10,L,"Table::__tostring (%p)",this);
   int top = lua_gettop(L);
   lua_pushfstring(L, "Table(%p) [%s] with keys:", this, typeInfo().name());
   for(Elements::iterator i = _elements.begin(); i != _elements.end(); ++i)
   {
     lua_pushfstring(L, "\n\t%s -> %p [%s]",i->first.c_str(), i->second.get(), i->second->typeInfo().name());
   }
   lua_concat(L, lua_gettop(L) - top);
   return 1;
 }
Example #10
0
	int HybridBase::call_lua_method(lua_State *L)
	{
		SLB_DEBUG_CALL;
		const HybridBase *hb = get_hybrid( L, 1 );
		if (hb->_L == 0) luaL_error(L, "Instance(%p) not attached to any lua_State...", hb);
		if (hb->_L != L) luaL_error(L, "This instance(%p) is attached to another lua_State(%p)", hb, hb->_L);
		// get the real function to call
		lua_pushvalue(L, lua_upvalueindex(1));
		// get the environment (from object) and set it
		lua_rawgeti(L, LUA_REGISTRYINDEX, hb->_global_environment);
		lua_setfenv(L,-2);
		lua_insert(L,1); //put the target function at 1
		SLB_DEBUG_STACK(10, L, "Hybrid(%p)::call_lua_method ...", hb);
		lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
		return lua_gettop(L);
	}
Example #11
0
		int __newindex(lua_State *L)
		{
			SLB_DEBUG_CALL;
			SLB_DEBUG_CLEAN_STACK(L,-2);
			SLB_DEBUG_STACK(6,L, "Call InternalHybridSubclass(%p)::__nexindex", this);
			//1 = table
			//2 = string
			//3 = function
			luaL_checkstring(L,2);
			if (lua_type(L,3) != LUA_TFUNCTION)
			{
				luaL_error(L, "Only functions can be added to hybrid classes"
					" (invalid %s of type %s)", lua_tostring(L,2), lua_typename(L, 3));
			}
			SLB_DEBUG(4, "Added method to an hybrid-subclass:%s", lua_tostring(L,2));
			lua_pushcclosure(L, HybridBase::call_lua_method, 1); // replaces 
			setCache(L);
			return 0;
		}
Example #12
0
 int Table::__indexProxy(lua_State *L)
 {
   SLB_DEBUG_CALL;
   SLB_DEBUG(9, "---> __index search");
   SLB_DEBUG_STACK(10,L,"Table::__indexProxy (%p)",this);
   int result = __index(L);
   
   if (result < 0)
   {
     SLB_DEBUG(9, "Nothing found....");
     /* TODO Change the result behaviour, resturn 0 when nothing is found
      * and quit using result = -1 */
     lua_pushnil(L);
     result = 1;
   }
   SLB_DEBUG(9, "<--- __index result = %d", result);
   assert(result == 1 && "Result must be 1 when it gets here");
   return result;
 }
Example #13
0
		int __call(lua_State *L)
		{
			SLB_DEBUG_CALL;
			SLB_DEBUG_STACK(6,L, "Call InternalHybridSubclass(%p)::__call", this);
			// create new instance:
			ref_ptr<FuncCall> fc = _CI->getConstructor();
			assert("Invalid Constructor!" && fc.valid());
			fc->push(L);
			lua_replace(L,1); // table of metamethod __call
			lua_call(L, lua_gettop(L) -1 , LUA_MULTRET);
			{
				SLB_DEBUG_CLEAN_STACK(L,0);
				// at 1 we should have an HybridBase instance...
				HybridBase *obj = SLB::get<HybridBase*>(L,1);
				if (obj == 0) luaL_error(L, "Output(1) of constructor should be an HybridBase instance");
				// now our table... to find methods
				obj->_subclassMethods = this;
			}
			return lua_gettop(L);
		}
Example #14
0
  int Table::__index(lua_State *L)
  {
    SLB_DEBUG_CALL;
    SLB_DEBUG_STACK(10,L,"Table::__index (%p)",this);
    int result = -1;
    
    { // Always tries to look in the cache first
      lua_pushvalue(L,2);
      lua_rawget(L, cacheTableIndex());
      if (lua_isnil(L,-1)) lua_pop(L,1); // remove nil
      else
      {
        SLB_DEBUG(10, "Access Table(%p) (In CACHE)", this);
        result = 1; // we found it
      }
    }

    if (result < 0)
    {
      if (lua_type(L, 2) == LUA_TSTRING)
      {
        Object *obj = get(lua_tostring(L,2));
        if (obj)
        {
          result = 1;
          obj->push(L);
          if (_cacheable)
          {
            // store in the cache...
            SLB_DEBUG(10, "L(%p) table(%p) key %s (->to cache)", L, this, lua_tostring(L,2));
            lua_pushvalue(L,2); // key
            lua_pushvalue(L,-2); // returned value
            lua_rawset(L, cacheTableIndex() ); // table
          }
        }
      }
    }

    return result;
  }