Add coroutine support (WIP)
This commit is contained in:
parent
a8129b218b
commit
01edc4fb21
|
|
@ -0,0 +1,44 @@
|
|||
// 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_LUACOROUTINE_HPP
|
||||
#define NAZARA_LUACOROUTINE_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Lua/LuaState.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_LUA_API LuaCoroutine : public LuaState
|
||||
{
|
||||
friend class LuaState;
|
||||
|
||||
public:
|
||||
LuaCoroutine(const LuaCoroutine&) = delete;
|
||||
inline LuaCoroutine(LuaCoroutine&& instance);
|
||||
~LuaCoroutine();
|
||||
|
||||
bool CanResume() const;
|
||||
|
||||
Ternary Resume(unsigned int argCount = 0);
|
||||
|
||||
LuaCoroutine& operator=(const LuaCoroutine&) = delete;
|
||||
inline LuaCoroutine& operator=(LuaCoroutine&& instance);
|
||||
|
||||
private:
|
||||
LuaCoroutine(lua_State* internalState, int refIndex);
|
||||
|
||||
bool Run(int argCount, int resultCount) override;
|
||||
|
||||
int m_ref;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Lua/LuaInstance.inl>
|
||||
|
||||
#endif // NAZARA_LUACOROUTINE_HPP
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// 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>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline LuaCoroutine::LuaCoroutine(LuaCoroutine&& instance) :
|
||||
LuaState(std::move(instance)),
|
||||
m_ref(instance.m_ref)
|
||||
{
|
||||
instance.m_ref = -1;
|
||||
}
|
||||
|
||||
inline LuaCoroutine& LuaCoroutine::operator=(LuaCoroutine&& instance)
|
||||
{
|
||||
LuaState::operator=(std::move(instance));
|
||||
|
||||
m_ref = instance.m_ref;
|
||||
instance.m_ref = -1;
|
||||
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ namespace Nz
|
|||
{
|
||||
class NAZARA_LUA_API LuaInstance : public LuaState
|
||||
{
|
||||
friend class LuaCoroutine;
|
||||
friend class LuaState;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ struct lua_State;
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
class LuaCoroutine;
|
||||
class LuaInstance;
|
||||
class LuaState;
|
||||
|
||||
|
|
@ -115,6 +116,7 @@ namespace Nz
|
|||
|
||||
void MoveTo(LuaState* instance, int n) const;
|
||||
|
||||
LuaCoroutine NewCoroutine();
|
||||
bool NewMetatable(const char* str);
|
||||
bool NewMetatable(const String& str);
|
||||
bool Next(int index = -2) const;
|
||||
|
|
@ -158,10 +160,8 @@ namespace Nz
|
|||
void SetMetatable(const char* tname) const;
|
||||
void SetMetatable(const String& tname) const;
|
||||
void SetMetatable(int index) const;
|
||||
void SetMemoryLimit(std::size_t memoryLimit);
|
||||
void SetTable(int index = -3) const;
|
||||
void SetTableRaw(int index = -3) const;
|
||||
void SetTimeLimit(UInt32 timeLimit);
|
||||
|
||||
bool ToBoolean(int index) const;
|
||||
long long ToInteger(int index, bool* succeeded = nullptr) const;
|
||||
|
|
@ -176,18 +176,18 @@ namespace Nz
|
|||
LuaState& operator=(LuaState&& instance) noexcept;
|
||||
|
||||
static int GetIndexOfUpValue(int upValue);
|
||||
static LuaState GetState(lua_State* internalState);
|
||||
static LuaInstance& GetInstance(lua_State* internalState);
|
||||
static inline LuaState GetState(lua_State* internalState);
|
||||
|
||||
protected:
|
||||
LuaState(LuaInstance* instance, lua_State* internalState);
|
||||
LuaState(lua_State* internalState);
|
||||
|
||||
template<typename T> T CheckBounds(int index, long long value) const;
|
||||
bool Run(int argCount, int resultCount);
|
||||
virtual bool Run(int argCount, int resultCount);
|
||||
|
||||
static int ProxyFunc(lua_State* internalState);
|
||||
|
||||
String m_lastError;
|
||||
LuaInstance* m_instance;
|
||||
lua_State* m_state;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline LuaState::LuaState(LuaInstance* instance, lua_State* internalState) :
|
||||
m_instance(instance),
|
||||
inline LuaState::LuaState(lua_State* internalState) :
|
||||
m_state(internalState)
|
||||
{
|
||||
}
|
||||
|
|
@ -785,4 +784,9 @@ namespace Nz
|
|||
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
inline LuaState LuaState::GetState(lua_State* internalState)
|
||||
{
|
||||
return LuaState(internalState);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue