Add coroutine support (WIP)
This commit is contained in:
55
src/Nazara/Lua/LuaCoroutine.cpp
Normal file
55
src/Nazara/Lua/LuaCoroutine.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2017 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Lua scripting module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Lua/LuaCoroutine.hpp>
|
||||
#include <Lua/lauxlib.h>
|
||||
#include <Lua/lua.h>
|
||||
#include <Lua/lualib.h>
|
||||
#include <Nazara/Lua/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
LuaCoroutine::LuaCoroutine(lua_State* internalState, int refIndex) :
|
||||
LuaState(internalState),
|
||||
m_ref(refIndex)
|
||||
{
|
||||
}
|
||||
|
||||
LuaCoroutine::~LuaCoroutine()
|
||||
{
|
||||
if (m_ref >= 0)
|
||||
DestroyReference(m_ref);
|
||||
}
|
||||
|
||||
bool LuaCoroutine::CanResume() const
|
||||
{
|
||||
return lua_status(m_state) == LUA_YIELD;
|
||||
}
|
||||
|
||||
Ternary LuaCoroutine::Resume(unsigned int argCount)
|
||||
{
|
||||
LuaInstance& instance = GetInstance(m_state);
|
||||
if (instance.m_level++ == 0)
|
||||
instance.m_clock.Restart();
|
||||
|
||||
int status = lua_resume(m_state, nullptr, argCount);
|
||||
instance.m_level--;
|
||||
|
||||
if (status == LUA_OK)
|
||||
return Ternary_True;
|
||||
else if (status == LUA_YIELD)
|
||||
return Ternary_Unknown;
|
||||
else
|
||||
{
|
||||
m_lastError = ToString(-1);
|
||||
Pop();
|
||||
return Ternary_False;
|
||||
}
|
||||
}
|
||||
|
||||
bool LuaCoroutine::Run(int argCount, int /*resultCount*/)
|
||||
{
|
||||
return Resume(argCount) != Ternary_False;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ namespace Nz
|
||||
}
|
||||
|
||||
LuaInstance::LuaInstance() :
|
||||
LuaState(this, lua_newstate(MemoryAllocator, this)),
|
||||
LuaState(nullptr),
|
||||
m_memoryLimit(0),
|
||||
m_memoryUsage(0),
|
||||
m_timeLimit(1000),
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <Nazara/Core/MemoryHelper.hpp>
|
||||
#include <Nazara/Core/MemoryView.hpp>
|
||||
#include <Nazara/Core/StringStream.hpp>
|
||||
#include <Nazara/Lua/LuaCoroutine.hpp>
|
||||
#include <Nazara/Lua/LuaInstance.hpp>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
@@ -127,7 +128,6 @@ namespace Nz
|
||||
|
||||
LuaState::LuaState(LuaState&& state) noexcept :
|
||||
m_lastError(state.m_lastError),
|
||||
m_instance(state.m_instance),
|
||||
m_state(state.m_state)
|
||||
{
|
||||
}
|
||||
@@ -570,6 +570,14 @@ namespace Nz
|
||||
lua_xmove(m_state, instance->m_state, n);
|
||||
}
|
||||
|
||||
LuaCoroutine LuaState::NewCoroutine()
|
||||
{
|
||||
lua_State* thread = lua_newthread(m_state);
|
||||
int ref = luaL_ref(m_state, LUA_REGISTRYINDEX);
|
||||
|
||||
return LuaCoroutine(thread, ref);
|
||||
}
|
||||
|
||||
bool LuaState::NewMetatable(const char* str)
|
||||
{
|
||||
return luaL_newmetatable(m_state, str) != 0;
|
||||
@@ -783,7 +791,6 @@ namespace Nz
|
||||
|
||||
LuaState& LuaState::operator=(LuaState&& state) noexcept
|
||||
{
|
||||
m_instance = state.m_instance;
|
||||
m_lastError = std::move(state.m_lastError);
|
||||
m_state = state.m_state;
|
||||
|
||||
@@ -792,12 +799,14 @@ namespace Nz
|
||||
|
||||
bool LuaState::Run(int argCount, int resultCount)
|
||||
{
|
||||
if (m_instance->m_level++ == 0)
|
||||
m_instance->m_clock.Restart();
|
||||
LuaInstance& instance = GetInstance(m_state);
|
||||
|
||||
if (instance.m_level++ == 0)
|
||||
instance.m_clock.Restart();
|
||||
|
||||
int status = lua_pcall(m_state, argCount, resultCount, 0);
|
||||
|
||||
m_instance->m_level--;
|
||||
instance.m_level--;
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
@@ -815,12 +824,12 @@ namespace Nz
|
||||
return lua_upvalueindex(upValue);
|
||||
}
|
||||
|
||||
LuaState LuaState::GetState(lua_State* internalState)
|
||||
LuaInstance& LuaState::GetInstance(lua_State* internalState)
|
||||
{
|
||||
LuaInstance* instance;
|
||||
lua_getallocf(internalState, reinterpret_cast<void**>(&instance));
|
||||
|
||||
return LuaState(instance, internalState);
|
||||
return *instance;
|
||||
}
|
||||
|
||||
int LuaState::ProxyFunc(lua_State* internalState)
|
||||
|
||||
Reference in New Issue
Block a user