예제 #1
0
UniqueLuaReference::UniqueLuaReference(lua_State* state, int reference) : _luaState(state), _reference(reference) {
	if (state == nullptr) {
		throw LuaException("Need a valid lua state!");
	}

	if (reference < 0) {
		throw LuaException("Reference must be greater than or equal to zero!");
	}
}
예제 #2
0
    static void initialize(LuaStack& stack, rainback::protocol::AbstractLine& ptl)
    {
        lua::push(stack, lua::value::table);
        auto methods = stack.saveAndPop();

        methods["listen"] = std::function<void(LuaStack&)>(
            [](LuaStack& stack) {
                rainback::protocol::AbstractLine& ptl = stack.as<rainback::protocol::AbstractLine&>(1);
                auto socket = stack.as<QAbstractSocket*>(2);
                if (!socket) {
                    throw LuaException("A socket or other IO device must be provided");
                }

                // Introduce a reference visible from Lua to ensure the socket doesn't get prematurely GC'd
                auto worker = stack.lua()(""
                    "return function(proto, socket)\n"
                    "    proto.__extra.io = socket;\n"
                    "end;"
                );
                lua::push(stack, worker);
                stack.insert(1);
                stack.pushedInvoke(2);

                ptl.listen(socket);
                stack.clear();
            }
        );

        methods["write"] = std::function<void(rainback::protocol::AbstractLine&, const QString&)>(
            [](rainback::protocol::AbstractLine& ptl, const QString& data) {
                if (!ptl.io()) {
                    throw LuaException("Write must have a socket or IO device to write to");
                }
                auto io = ptl.io();
                if (!io->isOpen()) {
                    throw LuaException("Write cannot write to a closed socket or IO device");
                }
                if (qobject_cast<QAbstractSocket*>(io)) {
                    auto socket = qobject_cast<QAbstractSocket*>(io);
                    if (socket->state() != QAbstractSocket::ConnectedState) {
                        std::stringstream str;
                        str << "Write cannot write to an unconnected socket. Current state was ";
                        str << rainback::proxy::getSocketStateName(socket->state());
                        throw LuaException(str.str());
                    }
                }
                ptl.write(data);
            }
        );

        rainback::proxy::wrapQObject(stack, ptl, methods);
        rainback::proxy::observeToDestroy(stack, ptl, true);
    }
예제 #3
0
std::string Lua::CallFunction(std::string functionName, LuaFunctionArguments arguments)
{
    if(!m_isLoaded)
        throw LuaException("Lua engine not loaded, use Load() first.");

    lua_getglobal(m_lua, functionName.c_str());

    //If function not found return empty string
    if(!lua_isfunction(m_lua, -1))
    {
        return "";
    }

    //Pass all arguments to function
    for(size_t argc=0; argc<arguments.Count(); argc++)
    {
        switch(arguments[argc].type)
        {
            case BOOL:
                lua_pushboolean(m_lua, arguments[argc].value.BVAL);
                break;

            case INTEGER:
                lua_pushinteger(m_lua, arguments[argc].value.IVAL);
                break;

            case STRING:
                lua_pushstring(m_lua, arguments[argc].value.SVAL);
                break;

            case DOUBLE:
                lua_pushnumber(m_lua, arguments[argc].value.DVAL);
                break;
        }
    }

    /* do the call (arguments count, 1 result) */
    if (lua_pcall(m_lua, arguments.Count(), 1, 0) != 0) {

        std::string errorMessage = "Error on function: ";
        errorMessage += functionName;
        errorMessage += "()";

        throw LuaException(errorMessage);
    }

    return lua_tostring(m_lua, -1);
}
예제 #4
0
//~~<<luaengine_die
void LuaGameEngine::dieIfFail(int state) const
{
    if (state) {
        const char *err = lua_tostring(L, -1);
        throw LuaException(err);
    }
}
예제 #5
0
void pushValue(lua_State* luaState, const LuaValue& value) {
	if (luaState != value.getLuaState()) {
		throw LuaException("Lua state mismatch!");
	}

	value.pushValue();
}
예제 #6
0
void LuaInterface::loadBuffer(const std::string& buffer, const std::string& source)
{
    // loads lua buffer
    int ret = luaL_loadbuffer(L, buffer.c_str(), buffer.length(), source.c_str());
    if(ret != 0)
        throw LuaException(popString(), 0);
}
예제 #7
0
int LuaInterface::safeCall(int numArgs, int numRets)
{
    assert(hasIndex(-numArgs-1));

    // saves the current stack size for calculating the number of results later
    int previousStackSize = stackSize();

    // pushes error function
    int errorFuncIndex = previousStackSize - numArgs;
    pushCFunction(&LuaInterface::luaErrorHandler);
    insert(errorFuncIndex);

    // calls the function in protected mode (means errors will be caught)
    int ret = pcall(numArgs, LUA_MULTRET, errorFuncIndex);

    remove(errorFuncIndex); // remove error func

     // if there was an error throw an exception
    if(ret != 0)
        throw LuaException(popString());

    int rets = (stackSize() + numArgs + 1) - previousStackSize;
    while(numRets != -1 && rets != numRets) {
        if(rets < numRets) {
            pushNil();
            rets++;
        } else {
            pop();
            rets--;
        }
    }

    // returns the number of results
    return rets;
}
예제 #8
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));
		}
	}
예제 #9
0
	void Interpreter::pushUserType(void *data, const std::string& type)
	{
		int top = getTop();
		tolua_pushusertype(luastate,data,type.c_str());
		if (getTop() == top)
			throw LuaException(std::string("Failed to push user type ") + type);
	}
예제 #10
0
    T getTableField(lua_State* L, std::string const& name)
    {
        std::string::size_type startPos = 0;
        std::string::size_type endPos = name.find(".", startPos);
        std::size_t stackCount = 0;

        T ret;

        if (std::string::npos == endPos) {
            lua_getglobal(L, name.c_str());

            ret = getFromStack<T>(L);
            lua_pop(L, 1);
            return ret;
        }

        lua_getglobal(L, name.substr(startPos, endPos - startPos).c_str());
        startPos = endPos + 1;
        ++stackCount;

        while (std::string::npos != (endPos = name.find(".", startPos))) {
            std::string tableName = name.substr(startPos, endPos - startPos);

            if (!lua_istable(L, -1)) {
                lua_pop(L, stackCount);
                throw LuaException("Invalid variable " + name);
            }

            lua_getfield(L, -1, tableName.c_str());
            ++stackCount;
            startPos = endPos + 1;
        }

        if (!lua_istable(L, -1)) {
            lua_pop(L, stackCount);
            throw LuaException("Invalid variable " + name);
        }

        lua_getfield(L, -1, name.substr(startPos).c_str());
        ++stackCount;

        ret = getFromStack<T>(L);

        lua_pop(L, stackCount);
        return ret;
    }
예제 #11
0
	void Interpreter::pop(const int num)
	{
		if (num > getTop()) {
			std::cout << "woah... num " << num << " top " << getTop() << ", stack:\n" << getStack();
			throw LuaException("Attempt to pop more than what is on the stack\n" + getStack());
		}
		lua_pop(luastate, num);
	}
예제 #12
0
파일: LuaWrapper.cpp 프로젝트: fimad/RPG
void LuaWrapper::doString(const string& lua){
  if( !script )
    raise(LuaException,"Lua not initialized!");
  try{
    script->doString(lua.c_str());
  }catch(exception& e){
    throw LuaException(e.what());
  }
}
예제 #13
0
파일: LuaWrapper.cpp 프로젝트: fimad/RPG
void LuaWrapper::doFile(const string& fileName){
  if( !script )
    raise(LuaException,"Lua not initialized!");
  try{
    script->doFile(fileName.c_str());
  }catch(exception& e){
    throw LuaException(e.what());
  }
}
예제 #14
0
LuaReference UniqueLuaReference::create(lua_State* state, int position) {
	if (state == nullptr) {
		throw LuaException("Need a valid lua state!");
	}

	lua_pushvalue(state, position);

	LuaReference ref(new UniqueLuaReference(state, luaL_ref(state, LUA_REGISTRYINDEX)));

	return ref;
}
예제 #15
0
void Context::runLuaScript( const std::string &str )
{
	
    if(luaL_dostring(mState->getLuaState(), str.c_str()) != 0){
        throw LuaException( lua_tostring(mState->getLuaState(), -1) );
    }
    
    ///collect garbage
    lua_gc(mState->getLuaState(), LUA_GCCOLLECT, 0);
    
}
예제 #16
0
State::State( Context* context_name ):mContext(context_name){
    
    mState = luaL_newstate();
    if(!mState){
		throw LuaException( "Error creating state for context: " + mContext->getName() );
    }
    luaL_openlibs( mState );
    luabind::open( mState );
    lua_atpanic(mState, &State::panic);
	luabind::set_pcall_callback(&defaultLuabindErrorHandler);
}
예제 #17
0
    T getFromStack(lua_State* L)
    {
        std::string ret;
        if (!lua_isnil(L, -1)) {
            ret = lua_tostring(L, -1);
        } else {
            throw LuaException("Value on the stack is nil");
        }

        return ret;
    }
예제 #18
0
파일: Lua.cpp 프로젝트: matthewbot/Kube
void Lua::pcallWrapper(int nargs, int nresults, const char *name) {
    int result = lua_pcall(L, nargs, nresults, 0);
    if (result != 0) {
        std::stringstream buf;
        if (result == LUA_ERRRUN) {
            buf << "Error while calling " << name << std::endl << lua_tostring(L, -1);
        } else {
            buf << "Out of memory or unknown error while calling " << name;
        }
        throw LuaException(buf.str().c_str());
    }
}
예제 #19
0
파일: Socket.cpp 프로젝트: Thonik/rainback
void validatePort(const int port) {
    if (port > 0 && port <= USHRT_MAX) {
        return;
    }
    std::stringstream str;
    if (port < 0) {
        str << "Port must be greater than zero, but was given " << port;
    } else if (port > USHRT_MAX) {
        str << "Port must be less than " << USHRT_MAX << ", but was given " << port;
    }
    throw LuaException(str.str());
}
예제 #20
0
void LuaTable::setReference(const LuaReference& ref) {
	ref->pushValue();

	lua_State* L = ref->getState();

	if (lua_type(L, -1) != LUA_TTABLE) {
		lua_pop(L, 1);
		throw LuaException("Reference does not refere to a table!");
	} else {
		lua_pop(L, 1);
		LuaValue::setReference(ref);
	}
}
예제 #21
0
void LuaFunction::setReference(LuaReference ref) {
	ref->pushValue();

	lua_State* L = ref->getState();

	if (lua_type(L, -1) != LUA_TFUNCTION) {
		lua_pop(L, 1);
		throw LuaException("Reference does not refere to a function!");
	} else {
		lua_pop(L, 1);
		LuaValue::setReference(ref);
	}
}
예제 #22
0
bool LuaTable::setMetatable(const LuaTable& table) {
	if (!table.getReference()->isValid()) {
		throw LuaException("Meta table reference is not valid!");
	}

	this->pushValue();
	table.pushValue();

	lua_setmetatable(_luaState, -2);

	lua_pop(_luaState, 1);

	return true;
}
예제 #23
0
bool LuaFunction::setEnvironment(const LuaTable& table) {
	if (!table.getReference()->isValid()) {
		throw LuaException("Table reference is not valid!");
	}

	this->pushValue();
	table.pushValue();

	bool ret = lua_setfenv(_luaState, -2) != 0;

	// Pop the function again
	lua_pop(_luaState, 1);

	return ret;
}
예제 #24
0
void Lua::Load(const std::string& file)
{
    if(m_isLoaded)
        Unload();

    m_lua = luaL_newstate();

    if(m_lua == NULL)
    {
        throw LuaException("Not enough resources to initialize the Lua engine.");
        return;
    }

    m_isLoaded = true;
    luaL_openlibs(m_lua);

    if (luaL_loadfile(m_lua, file.c_str()) || lua_pcall(m_lua, 0, 0, 0)) {
        std::string errorMessage = "The file '";
        errorMessage += file;
        errorMessage += "' was not found or could not be loaded.";

        throw LuaException(errorMessage.c_str());
    }
}
예제 #25
0
void LuaInterface::loadScript(const std::string& fileName)
{
    // resolve file full path
    std::string filePath = fileName;
    if(!boost::starts_with(fileName, "/"))
        filePath = getCurrentSourcePath() + "/" + filePath;

    try {
        std::string buffer = g_resources.loadFile(filePath);
        std::string source = "@" + filePath;
        loadBuffer(buffer, source);
    } catch(Exception& e) {
        throw LuaException(e.what());
    }
}
예제 #26
0
파일: Lua.cpp 프로젝트: matthewbot/Kube
void Lua::checkLoadResult(int result, const char *name) {
    if (result == 0) {
        return;
    }

    std::stringstream buf;
    if (result == LUA_ERRFILE) {
        buf << "Failed to open " << name;
    } else if (result == LUA_ERRSYNTAX) {
        buf << "Syntax error in " << name;
        buf << std::endl << lua_tostring(L, -1);
    } else {
        buf << "Out of memory or other error while loading " << name;
    }
    throw LuaException(buf.str().c_str());
}
예제 #27
0
//-------------------------------------------------------------------------------------------------
void LuaWorker::on_checkFile(const IFile *pFile)
{
    if (m_pConsole==NULL || pFile==NULL)
        return;

    try
    {
        Q_ASSERT(pFile!=NULL);
        Locker lock(pFile);

        if (m_luaState==NULL)
            throw LuaException(QString("Can't execute Lua code fragment \"%1\": Lua state is not initialized").arg(pFile->getName()));

    //    qDebug() << "syntaxCheck(" << pFile->getName() << ")";

        const QVector<QString> &vLines = pFile->getLines();
        QString sScript;
        for (int i=0; i<vLines.size(); ++i)
        {
            const QString &sLine = vLines[i];
            sScript += sLine;
        }

        syntaxCheck(sScript, pFile->getName());
        emit syntaxCheckSuccess(pFile);
    }
    catch(LuaException &exc)
    {
        exc.setFile(pFile);

        QString sMsg = QString("%1 in Line %2").arg(exc.getMessage())
                                               .arg(exc.getLine());
        emit syntaxCheckFail(pFile, sMsg, (int)exc.getLine());
    }
    catch(Exception &exc)
    {
        emit syntaxCheckFail(pFile, exc.getMessage(), -1);
    }
    catch(std::exception &exc)
    {
        emit syntaxCheckFail(pFile, exc.what(), -1);
    }
    catch(...)
    {
        emit syntaxCheckFail(pFile, "Internal error: FrmConsole::executeCommand", -1);
    }
}
예제 #28
0
	/// @return non-zero on errors, and a description is available through getError()
	int Interpreter::doString(const std::string& str, const std::string& identifier) {
		errstr = "";
		status = luaL_loadbuffer(luastate, str.c_str(), str.length(), identifier.c_str());
		if (status != 0 && getTop() > 0) {
			if (lua_tostring(luastate, -1))
				errstr = lua_tostring(luastate, -1);
			else {
				std::stringstream ss;
				ss << "doString returned " << status << " and top of stack is not string, stack:\n" << getStack();
				throw LuaException(ss.str());
			}
			lua_pop(luastate,1);
			return status;
		}
		// Run it
		return pCall(0,1,0,1);
	}
예제 #29
0
//-------------------------------------------------------------------------------------------------
void LuaWorker::on_doFile(IFile *pFile)
{
    if (m_pConsole==NULL || pFile==NULL)
        return;

    qDebug("on_doFile(%s); thread id: %d",
           pFile->getName().toStdString().c_str(),
           reinterpret_cast<int>(QThread::currentThreadId()));

    try
    {
        QVector<QString> vLines = pFile->getLines();
        QString sScript;
        for (int i=0; i<vLines.size(); ++i)
        {
            sScript += vLines[i];
        }

        if (m_luaState==NULL)
            throw LuaException(QString("Can't execute Lua code fragment \"%1\": Lua state is not initialized").arg(sScript));

        doString(sScript, pFile->getName());
        emit finished();
    }
    catch(LuaException &exc)
    {
        exc.setFile(pFile);

        QString sMsg = QString("%1 in Line %2").arg(exc.getMessage())
                                               .arg(exc.getLine());
        emit error(sMsg);
    }
    catch(Exception &exc)
    {
        emit error(exc.getMessage());
    }
    catch(std::exception &exc)
    {
        emit error(exc.what());
    }
    catch(...)
    {
        emit error("Internal error: FrmConsole::executeCommand");
    }
}
예제 #30
0
	/// @return non-zero on errors, and a description is available through getError()
	int Interpreter::doFile(const std::string& filename) {
		errstr = "";
		// Load the data
		status = luaL_loadfile(luastate, filename.c_str());
		if (status != 0 && getTop() > 0) {
			if (lua_tostring(luastate, -1))
				errstr = lua_tostring(luastate, -1);
			else {
				std::stringstream ss;
				ss << "doFile returned " << status << " and top of stack is not string, stack:\n" << getStack();
				throw LuaException(ss.str());
			}
			lua_pop(luastate,1);
			return status;
		}
		// Run it
		return pCall(0,1,0,1);
	}