예제 #1
0
	LuaFunction LuaFunction::createFromCode(lua_State* L, std::string const& code, std::string const& name)
	{
		int err = luaL_loadbuffer(L, code.c_str(), code.length(), name.c_str());

		if (!err)
		{
			LuaFunction func;

			func.setReference(LuaReference::create(L));

			lua_pop(L, 1);

			return func;
		}
		else
		{
			// Get the error message
			size_t len;
			const char* err = lua_tolstring(L, -1, &len);

			lua_pop(L, 1);

			throw LuaException(std::string(err, len));
		}
	}
예제 #2
0
/* method: Call of class  LuaFunction */
static int tolua_LuaFunction_LuaFunction_Call00(lua_State* tolua_S)
{
#ifndef TOLUA_RELEASE
 tolua_Error tolua_err;
 if (
 !tolua_isusertype(tolua_S,1,"LuaFunction",0,&tolua_err) || 
 !tolua_isnoobj(tolua_S,2,&tolua_err)
 )
 goto tolua_lerror;
 else
#endif
 {
  LuaFunction* self = (LuaFunction*)  tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
 if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Call'",NULL);
#endif
 {
  self->Call();
 }
 }
 return 0;
#ifndef TOLUA_RELEASE
 tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'Call'.",&tolua_err);
 return 0;
#endif
}
예제 #3
0
LuaObject LuaGlobalSelector::toLuaObject( void ) const
{
	magicalAssert( !_key.empty(), "key should not be empty!" );
	lua_State* L = _L->cPtr();
	LuaObject lobj;
	lua_getglobal( L, _key.c_str() );

	switch( lua_type( L, -1 ) )
	{
	case LUA_TNIL:
		lobj = nullptr;
		break;
	case LUA_TBOOLEAN:
		lobj = (bool) lua_toboolean( L, -1 );
		break;
	case LUA_TNUMBER:
		lobj = (double) lua_tonumber( L, -1 );
		break;
	case LUA_TSTRING:
		lobj = lua_tostring( L, -1 );
		break;
	case LUA_TUSERDATA:
		{
			int top = lua_gettop( L );
			std::string type = tolua_typename( L, top );
			lua_pop( L, 1 );
			void* userdata = tolua_tousertype( L, top, 0 );
			lobj.set( userdata, type.c_str() );
		}
		break;
	case LUA_TFUNCTION:
		{
			LuaFunction lf;
			int handler = tolua_ext_tofunction( L, lua_gettop( L ), 0 );
			if( handler != 0 )
			{
				lf.bind( _L, handler );
			}
			lobj = lf;
		}
		break;
	case LUA_TTABLE:
		{
			LuaTable lt;
			int handler = tolua_ext_totable( L, lua_gettop( L ), 0 );
			if( handler != 0 )
			{
				lt.bind( _L, handler );
			}
			lobj = lt;
		}
		break;
	default:
		lobj = nullptr;
		break;
	}
	lua_pop( L, 1 );
	return lobj;
}
예제 #4
0
 // - LuaFunction::operator> -------------------------------------------------
 bool LuaFunction::operator> (const LuaFunction& rhs) const
 {
    if (functionType_ > rhs.functionType_)
       return true;
    else if (getSize() > rhs.getSize())
       return true;
    else if (getSize() < rhs.getSize())
       return false;
    else // getSize() == rhs.getSize()
       return memcmp (getData(), rhs.getData(), getSize()) > 0;
 }
예제 #5
0
	LuaFunction LuaFunction::createFromCFunction(lua_State* L, lua_CFunction function)
	{
		LuaFunction func;

		lua_pushcfunction(L, function);

		func.setReference(LuaReference::create(L));

		lua_pop(L, 1);

		return func;
	}
예제 #6
0
TEST_F(LuaFunctionTest, Call) {
	{
		ScopedLuaStackTest stackTest(L);

		// Test execution with failure
		LuaFunction function = LuaFunction::createFromCode(L, "invalid()");

		ASSERT_THROW(function.call(), luacpp::LuaException);
		ASSERT_THROW(function(), luacpp::LuaException);
	}
	{
		ScopedLuaStackTest stackTest(L);

		// Test execution without failure
		LuaFunction function = LuaFunction::createFromCode(L, "local a = 1");

		ASSERT_NO_THROW(function.call());
		ASSERT_NO_THROW(function());
	}
	{
		ScopedLuaStackTest stackTest(L);

		// Test execution without failure
		LuaFunction function = LuaFunction::createFromCode(L, "return 'abc', 5");


		LuaValueList returnValues = function();

		ASSERT_EQ(luacpp::ValueType::STRING, returnValues[0].getValueType());
		ASSERT_EQ(luacpp::ValueType::NUMBER, returnValues[1].getValueType());

		ASSERT_STREQ("abc", returnValues[0].getValue<std::string>().c_str());
		ASSERT_EQ(5, returnValues[1].getValue<int>());
	}
	{
		ScopedLuaStackTest stackTest(L);

		lua_getglobal(L, "type");

		LuaFunction func;
		ASSERT_TRUE(convert::popValue(L, func));

		LuaValue arg = LuaValue::createValue(L, "testString");
		LuaValueList returnVals = func({ arg });

		ASSERT_EQ(1, (int)returnVals.size());
		ASSERT_EQ(ValueType::STRING, returnVals[0].getValueType());
		ASSERT_STREQ("string", returnVals[0].getValue<std::string>().c_str());
	}
}
예제 #7
0
TEST_F(LuaFunctionTest, ErrorFunctionNoReturnValues) {
	ScopedLuaStackTest stackTest(L);

	LuaFunction func = LuaFunction::createFromCode(L, "invalid()");
	func.setErrorFunction(LuaFunction::createFromCFunction(L, &testErrorFunctionNoRetVals));

	try {
		func();
		FAIL();
	}
	catch (const LuaException& err) {
		ASSERT_STREQ("Invalid lua value on stack!", err.what());
	}
}
예제 #8
0
void LuaAiState::onSeeEnemy(IActor *enemy)
{
    LuaType::registerConstant<IBody>(this->script, "body", this->body);

    LuaFunction luaFunction;
    luaFunction.readyToRunFunction(this->script, "OnSeeEnemy");

    this->script->sendToLua<void*>(enemy);

    luaFunction.runFunction(1, 0);
    luaFunction.clearAfterFunction();

    this->script->removeSymbol("body");
}
예제 #9
0
파일: luview.cpp 프로젝트: ghl3/luview
CallbackFunction *CallbackFunction::create_from_stack(lua_State *L, int pos)
{
  if (lua_type(L, pos) == LUA_TUSERDATA) {
    return checkarg<CallbackFunction>(L, pos);
  }
  else if (lua_type(L, pos) == LUA_TNIL) {
    return NULL;
  }
  else {
    LuaFunction *f = create<LuaFunction>(L);
    f->hold(pos, "lua_callback");
    return f;
  }
}
예제 #10
0
void LuaAiState::onTakeDamage(IActor* instigator, float damageValue, Vector2D impulse)
{
    LuaType::registerConstant<IBody>(this->script, "body", this->body);

    LuaFunction luaFunction;
    luaFunction.readyToRunFunction(this->script, "OnTakeDamage");

    this->script->sendToLua<void*>(instigator);
    this->script->sendToLua<double>(damageValue);

    luaFunction.runFunction(2, 0);
    luaFunction.clearAfterFunction();

    this->script->removeSymbol("body");
}
예제 #11
0
LuaFunction LuaFunction::createFromCFunction(lua_State* L, lua_CFunction function, const LuaValueList& upvalues) {
	LuaFunction func;

	for (auto& val : upvalues) {
		val.pushValue();
	}

	lua_pushcclosure(L, function, (int) upvalues.size());

	func.setReference(UniqueLuaReference::create(L));

	lua_pop(L, 1);

	return func;
}
예제 #12
0
LuaFunction LuaGlobalSelector::toLuaFunction( void ) const
{
	magicalAssert( !_key.empty(), "key should not be empty!" );
	lua_State* L = _L->cPtr();
	LuaFunction lf;
	lua_getglobal( L, _key.c_str() );

	int handler = tolua_ext_tofunction( L, lua_gettop( L ), 0 );
	if( handler != 0 )
	{
		lf.bind( _L, handler );
	}
	lua_pop( L, 1 );
	return lf;
}
예제 #13
0
TEST_F(LuaFunctionTest, SetErrorFunction) {
	{
		ScopedLuaStackTest stackTest(L);

		LuaFunction func = LuaFunction::createFromCode(L, "invalid()");
		func.setErrorFunction(LuaFunction::createFromCFunction(L, &testErrorFunction));

		try {
			func();
			FAIL();
		}
		catch (const LuaException& err) {
			ASSERT_STREQ("TestError", err.what());
		}
	}
}
예제 #14
0
 // - LuaState::call ---------------------------------------------------------
 LuaValueList LuaState::call (LuaFunction& func,
                              const LuaValueList& params,
                              const std::string& chunkName)
 {
    func.setReaderFlag (false);
    PushLuaValue (state_, LuaValue (func));
    return Impl::CallFunctionOnTop (state_, params);
 }
예제 #15
0
TEST_F(LuaFunctionTest, SetReference) {
	{
		ScopedLuaStackTest stackTest(L);

		LuaFunction func = LuaFunction::createFromCode(L, "invalid()");

		lua_pushliteral(L, "abc");
		ASSERT_THROW(func.setReference(UniqueLuaReference::create(L)), LuaException);

		lua_pop(L, 1);

		lua_getglobal(L, "type");
		ASSERT_NO_THROW(func.setReference(UniqueLuaReference::create(L)));

		lua_pop(L, 1);
	}
}
예제 #16
0
void LuaScriptEventInvoker::HandleLuaScriptEvent(StringHash eventType, VariantMap& eventData)
{
    LuaFunction* function = static_cast<LuaFunction*>(GetEventHandler()->GetUserData());
    if (!function)
        return;

    // Keep instance alive during invoking
    SharedPtr<LuaScriptInstance> instance(instance_);
    if (instance)
    {
        if (function->BeginCall(instance))
        {
            function->PushUserType(eventType, "StringHash");
            function->PushUserType(eventData, "VariantMap");
            function->EndCall();
        }
    }
    else
    {
        if (function->BeginCall())
        {
            function->PushUserType(eventType, "StringHash");
            function->PushUserType(eventData, "VariantMap");
            function->EndCall();
        }
    }
}
예제 #17
0
LuaFunction LuaTableSelector::toLuaFunction( void ) const
{
	magicalAssert( !_key.empty(), "key should not be empty!" );
	if( !_L || !_handler ) 
		return nullptr;

	LuaFunction lf;
	lua_State* L = _L->cPtr();
	tolua_ext_get_table_by_handler( L, _handler );

	lua_getfield( L, -1, _key.c_str() );
	int handler = tolua_ext_tofunction( L, lua_gettop( L ), 0 );
	if( handler != 0 )
	{
		lf.bind( _L, handler );
	}
	lua_pop( L, 2 );
	return lf;
}
예제 #18
0
TEST_F(LuaFunctionTest, SetEnvironment) {
	{
		ScopedLuaStackTest stackTest(L);

		// Setup environment table
		LuaTable envionment = LuaTable::create(L);
		envionment.addValue("key", "Test");

		LuaFunction func = LuaFunction::createFromCode(L, "return key");

		func.setEnvironment(envionment);

		LuaValueList returnVals = func();

		ASSERT_EQ(1, (int)returnVals.size());
		ASSERT_EQ(ValueType::STRING, returnVals[0].getValueType());

		ASSERT_STREQ("Test", returnVals[0].getValue<std::string>().c_str());
	}
}
예제 #19
0
bool ::luacpp::convert::popValue(lua_State* luaState, LuaFunction& target, int stackposition, bool remove) {
	if (!internal::isValidIndex(luaState, stackposition)) {
		return false;
	}

	if (!lua_isfunction(luaState, stackposition)) {
		return false;
	} else {
		target.setReference(UniqueLuaReference::create(luaState, stackposition));

		if (remove) {
			lua_remove(luaState, stackposition);
		}

		return true;
	}
}
예제 #20
0
 // - LuaFunction::operator== ------------------------------------------------
 bool LuaFunction::operator== (const LuaFunction& rhs) const
 {
    return functionType_ == rhs.functionType_
       && getSize() == rhs.getSize()
       && memcmp (getData(), rhs.getData(), getSize()) == 0;
 }
예제 #21
0
		static int push(lua_State* l, const LuaFunction& ref)
		{
			return ref.push(l);
		}
예제 #22
0
bool LuaScript::ExecuteFunction(const String& functionName)
{
    LuaFunction* function = GetFunction(functionName);
    return function && function->BeginCall() && function->EndCall();
}
/**
  Sets the value of the element as a function value
*/
void LuaTableElement::set(LuaFunction f) {
  type = FUNCTION;
  func_value = f.getFunction();
}
예제 #24
0
void LuaIntegration::CreateScene()
{
    auto* cache = GetSubsystem<ResourceCache>();

    scene_ = new Scene(context_);

    // Create the Octree component to the scene so that drawable objects can be rendered. Use default volume
    // (-1000, -1000, -1000) to (1000, 1000, 1000)
    scene_->CreateComponent<Octree>();

    // Create a Zone component into a child scene node. The Zone controls ambient lighting and fog settings. Like the Octree,
    // it also defines its volume with a bounding box, but can be rotated (so it does not need to be aligned to the world X, Y
    // and Z axes.) Drawable objects "pick up" the zone they belong to and use it when rendering; several zones can exist
    Node* zoneNode = scene_->CreateChild("Zone");
    auto* zone = zoneNode->CreateComponent<Zone>();
    // Set same volume as the Octree, set a close bluish fog and some ambient light
    zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f));
    zone->SetAmbientColor(Color(0.05f, 0.1f, 0.15f));
    zone->SetFogColor(Color(0.1f, 0.2f, 0.3f));
    zone->SetFogStart(10.0f);
    zone->SetFogEnd(100.0f);

    auto* scriptFile = cache->GetResource<LuaFile>("LuaScripts/Utilities/Rotator.lua");
    if (!scriptFile)
        return;

    // Create randomly positioned and oriented box StaticModels in the scene
    const unsigned NUM_OBJECTS = 2000;
    for (unsigned i = 0; i < NUM_OBJECTS; ++i)
    {
        Node* boxNode = scene_->CreateChild("Box");
        boxNode->SetPosition(Vector3(Random(200.0f) - 100.0f, Random(200.0f) - 100.0f, Random(200.0f) - 100.0f));
        // Orient using random pitch, yaw and roll Euler angles
        boxNode->SetRotation(Quaternion(Random(360.0f), Random(360.0f), Random(360.0f)));
        auto* boxObject = boxNode->CreateComponent<StaticModel>();
        boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
        boxObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml"));

        // Add our custom Rotator script object (using the LuaScriptInstance C++ component to instantiate / store it) which will
        // rotate the scene node each frame, when the scene sends its update event
        auto* instance = boxNode->CreateComponent<LuaScriptInstance>();
        instance->CreateObject(scriptFile, "Rotator");

        // Call the script object's "SetRotationSpeed" function.
        LuaFunction* function = instance->GetScriptObjectFunction("SetRotationSpeed");
        if (function && function->BeginCall(instance))
        {
            function->PushUserType(Vector3(10.0f, 20.0f, 30.0f), "Vector3");
            function->EndCall();
        }
    }

    // Create the camera. Let the starting position be at the world origin. As the fog limits maximum visible distance, we can
    // bring the far clip plane closer for more effective culling of distant objects
    cameraNode_ = scene_->CreateChild("Camera");
    auto* camera = cameraNode_->CreateComponent<Camera>();
    camera->SetFarClip(100.0f);

    // Create a point light to the camera scene node
    auto* light = cameraNode_->CreateComponent<Light>();
    light->SetLightType(LIGHT_POINT);
    light->SetRange(30.0f);
}
예제 #25
0
 LuaFunction::LuaFunction (const LuaFunction& other)
    : functionType_(other.functionType_),
      size_(other.getSize()), data_(new char[size_])
 {
    memcpy (data_.get(), other.getData(), getSize());
 }
예제 #26
0
 // - LuaFunction::operator!= ------------------------------------------------
 bool LuaFunction::operator!= (const LuaFunction& rhs) const
 {
    return functionType_ != rhs.functionType_
       || getSize() != rhs.getSize()
       || memcmp (getData(), rhs.getData(), getSize()) != 0;
 }
예제 #27
0
		/**
		 * @brief Sets the function called when an error occurs
		 * This lua_Cfunction will be called by lua if an error occus while executing this function
		 * 
		 * @return void
		 */
		void setErrorFunction(const LuaFunction& errorFunc)
		{
			errorFunction = errorFunc.getReference();
		}