Added Lua module
Former-commit-id: 3f96b9aef8afffb5e8daf460480df2f3b8c37da7
This commit is contained in:
parent
3ac0338285
commit
1e256bdf35
|
|
@ -0,0 +1,38 @@
|
|||
// This file was automatically generated on 24 Apr 2013 at 11:49:37
|
||||
|
||||
/*
|
||||
Nazara Engine - Lua scripting module
|
||||
|
||||
Copyright (C) 2013 Jérôme Leclercq (lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GLOBAL_LUA_HPP
|
||||
#define NAZARA_GLOBAL_LUA_HPP
|
||||
|
||||
#include <Nazara/Lua/Config.hpp>
|
||||
#include <Nazara/Lua/Enums.hpp>
|
||||
#include <Nazara/Lua/Lua.hpp>
|
||||
#include <Nazara/Lua/LuaClass.hpp>
|
||||
#include <Nazara/Lua/LuaInstance.hpp>
|
||||
|
||||
#endif // NAZARA_GLOBAL_LUA_HPP
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Nazara Engine - Lua scripting module
|
||||
|
||||
Copyright (C) 2013 Jérôme Leclercq (lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CONFIG_LUA_HPP
|
||||
#define NAZARA_CONFIG_LUA_HPP
|
||||
|
||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||
|
||||
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
||||
#define NAZARA_LUA_MEMORYLEAKTRACKER 0
|
||||
|
||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||
#define NAZARA_LUA_SAFE 1
|
||||
|
||||
#endif // NAZARA_CONFIG_LUA_HPP
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (C) 2013 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/Config.hpp>
|
||||
#if NAZARA_LUA_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG)
|
||||
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
|
||||
|
||||
#define delete NzMemoryManager::NextFree(__FILE__, __LINE__), delete
|
||||
#define new new(__FILE__, __LINE__)
|
||||
#endif
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (C) 2013 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
|
||||
|
||||
#if NAZARA_LUA_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG)
|
||||
#undef delete
|
||||
#undef new
|
||||
#endif
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (C) 2013 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_ENUMS_LUA_HPP
|
||||
#define NAZARA_ENUMS_LUA_HPP
|
||||
|
||||
enum nzLuaComparison
|
||||
{
|
||||
nzLuaComparison_Equality,
|
||||
nzLuaComparison_Less,
|
||||
nzLuaComparison_LessOrEqual,
|
||||
|
||||
nzLuaComparison_Max = nzLuaComparison_LessOrEqual
|
||||
};
|
||||
|
||||
enum nzLuaOperation
|
||||
{
|
||||
nzLuaOperation_Addition,
|
||||
nzLuaOperation_Division,
|
||||
nzLuaOperation_Exponentiation,
|
||||
nzLuaOperation_Modulo,
|
||||
nzLuaOperation_Multiplication,
|
||||
nzLuaOperation_Negation,
|
||||
nzLuaOperation_Substraction,
|
||||
|
||||
nzLuaOperation_Max = nzLuaOperation_Substraction
|
||||
};
|
||||
|
||||
enum nzLuaType
|
||||
{
|
||||
nzLuaType_Boolean,
|
||||
nzLuaType_Function,
|
||||
nzLuaType_LightUserdata,
|
||||
nzLuaType_Nil,
|
||||
nzLuaType_Number,
|
||||
nzLuaType_None,
|
||||
nzLuaType_String,
|
||||
nzLuaType_Table,
|
||||
nzLuaType_Thread,
|
||||
nzLuaType_Userdata,
|
||||
|
||||
nzLuaType_Max = nzLuaType_Userdata
|
||||
};
|
||||
|
||||
#endif // NAZARA_ENUMS_LUA_HPP
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright (C) 2013 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_LUACLASS_HPP
|
||||
#define NAZARA_LUACLASS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Lua/LuaInstance.hpp>
|
||||
#include <map>
|
||||
|
||||
template<class T>
|
||||
class NzLuaClass : public NzLuaClassImpl
|
||||
{
|
||||
public:
|
||||
using ClassFunc = int (*)(NzLuaInstance& lua, T& instance);
|
||||
using ClassIndexFunc = bool (*)(NzLuaInstance& lua, T& instance);
|
||||
using ConstructorFunc = T* (*)(NzLuaInstance& lua);
|
||||
using FinalizerFunc = bool (*)(NzLuaInstance& lua, T& instance);
|
||||
|
||||
NzLuaClass(const NzString& name);
|
||||
|
||||
//template<class U> void Inherit(NzLuaClass<U>& parent);
|
||||
|
||||
void Register(NzLuaInstance& lua);
|
||||
|
||||
void SetConstructor(ConstructorFunc constructor);
|
||||
void SetFinalizer(FinalizerFunc finalizer);
|
||||
void SetGetter(ClassIndexFunc getter);
|
||||
void SetMethod(const NzString& name, ClassFunc method);
|
||||
void SetSetter(ClassIndexFunc setter);
|
||||
|
||||
private:
|
||||
static int ConstructorProxy(lua_State* state);
|
||||
static int FinalizerProxy(lua_State* state);
|
||||
static int GetterProxy(lua_State* state);
|
||||
static int MethodProxy(lua_State* state);
|
||||
static int SetterProxy(lua_State* state);
|
||||
|
||||
std::map<NzString, ClassFunc> m_methods;
|
||||
ClassIndexFunc m_getter;
|
||||
ClassIndexFunc m_setter;
|
||||
ConstructorFunc m_constructor;
|
||||
FinalizerFunc m_finalizer;
|
||||
NzString m_name;
|
||||
};
|
||||
|
||||
#include <Nazara/Lua/LuaClass.inl>
|
||||
|
||||
#endif // NAZARA_LUACLASS_HPP
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
// Copyright (C) 2013 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/Debug.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
|
||||
template<class T>
|
||||
NzLuaClass<T>::NzLuaClass(const NzString& name) :
|
||||
m_getter(nullptr),
|
||||
m_setter(nullptr),
|
||||
m_constructor(nullptr),
|
||||
m_finalizer(nullptr),
|
||||
m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void NzLuaClass<T>::Register(NzLuaInstance& lua)
|
||||
{
|
||||
if (!lua.NewMetatable(m_name))
|
||||
NazaraWarning("Class \"" + m_name + "\" already registred in this instance");
|
||||
{
|
||||
FinalizerFunc* finalizer = static_cast<FinalizerFunc*>(lua.PushUserdata(sizeof(FinalizerFunc)));
|
||||
*finalizer = m_finalizer;
|
||||
lua.PushString(m_name);
|
||||
|
||||
lua.PushCFunction(FinalizerProxy, 2);
|
||||
lua.SetField("__gc");
|
||||
|
||||
if (m_getter)
|
||||
{
|
||||
ClassIndexFunc* getter = static_cast<ClassIndexFunc*>(lua.PushUserdata(sizeof(ClassIndexFunc)));
|
||||
*getter = m_getter;
|
||||
lua.PushString(m_name);
|
||||
|
||||
lua.PushCFunction(GetterProxy, 2);
|
||||
}
|
||||
else
|
||||
lua.PushValue(-1);
|
||||
|
||||
lua.SetField("__index");
|
||||
|
||||
if (m_setter)
|
||||
{
|
||||
ClassIndexFunc* setter = static_cast<ClassIndexFunc*>(lua.PushUserdata(sizeof(ClassIndexFunc)));
|
||||
*setter = m_setter;
|
||||
lua.PushString(m_name);
|
||||
|
||||
lua.PushCFunction(SetterProxy, 2);
|
||||
lua.SetField("__newindex");
|
||||
}
|
||||
|
||||
for (auto it = m_methods.begin(); it != m_methods.end(); ++it)
|
||||
{
|
||||
ClassFunc* method = static_cast<ClassFunc*>(lua.PushUserdata(sizeof(ClassFunc)));
|
||||
*method = it->second;
|
||||
lua.PushString(m_name);
|
||||
|
||||
lua.PushCFunction(MethodProxy, 2);
|
||||
lua.SetField(it->first);
|
||||
}
|
||||
|
||||
}
|
||||
lua.Pop();
|
||||
|
||||
if (m_constructor)
|
||||
{
|
||||
ConstructorFunc* ptr = static_cast<ConstructorFunc*>(lua.PushUserdata(sizeof(ConstructorFunc)));
|
||||
*ptr = m_constructor;
|
||||
lua.PushString(m_name);
|
||||
|
||||
lua.PushCFunction(ConstructorProxy, 2);
|
||||
lua.SetGlobal(m_name);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void NzLuaClass<T>::SetConstructor(ConstructorFunc constructor)
|
||||
{
|
||||
m_constructor = constructor;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void NzLuaClass<T>::SetFinalizer(FinalizerFunc finalizer)
|
||||
{
|
||||
m_finalizer = finalizer;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void NzLuaClass<T>::SetGetter(ClassIndexFunc getter)
|
||||
{
|
||||
m_getter = getter;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void NzLuaClass<T>::SetMethod(const NzString& name, ClassFunc method)
|
||||
{
|
||||
m_methods[name] = method;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void NzLuaClass<T>::SetSetter(ClassIndexFunc setter)
|
||||
{
|
||||
m_setter = setter;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int NzLuaClass<T>::ConstructorProxy(lua_State* state)
|
||||
{
|
||||
NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);
|
||||
|
||||
ConstructorFunc func = *static_cast<ConstructorFunc*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
|
||||
const char* className = lua.ToString(lua.GetIndexOfUpValue(2));
|
||||
|
||||
T* instance = func(lua);
|
||||
if (!instance)
|
||||
{
|
||||
lua.Error("Constructor failed");
|
||||
return 0; // Normalement pas nécessaire
|
||||
}
|
||||
|
||||
T** ud = static_cast<T**>(lua.PushUserdata(sizeof(T*)));
|
||||
lua.SetMetatable(className);
|
||||
*ud = instance;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int NzLuaClass<T>::FinalizerProxy(lua_State* state)
|
||||
{
|
||||
NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);
|
||||
|
||||
FinalizerFunc func = *static_cast<FinalizerFunc*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
|
||||
const char* className = lua.ToString(lua.GetIndexOfUpValue(2));
|
||||
|
||||
T* instance = *static_cast<T**>(lua.CheckUserdata(1, className));
|
||||
lua.Remove(1);
|
||||
|
||||
if (!func || func(lua, *instance))
|
||||
delete instance;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int NzLuaClass<T>::GetterProxy(lua_State* state)
|
||||
{
|
||||
NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);
|
||||
|
||||
ClassIndexFunc func = *static_cast<ClassIndexFunc*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
|
||||
const char* className = lua.ToString(lua.GetIndexOfUpValue(2));
|
||||
|
||||
T& instance = *(*static_cast<T**>(lua.CheckUserdata(1, className)));
|
||||
lua.Remove(1);
|
||||
|
||||
if (!func(lua, instance))
|
||||
{
|
||||
// On accède alors à la table
|
||||
lua.PushMetatable(className);
|
||||
lua.PushValue(1);
|
||||
lua.GetTable();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int NzLuaClass<T>::MethodProxy(lua_State* state)
|
||||
{
|
||||
NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);
|
||||
|
||||
ClassFunc func = *static_cast<ClassFunc*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
|
||||
const char* className = lua.ToString(lua.GetIndexOfUpValue(2));
|
||||
|
||||
T& instance = *(*static_cast<T**>(lua.CheckUserdata(1, className)));
|
||||
lua.Remove(1);
|
||||
|
||||
return (*func)(lua, instance);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int NzLuaClass<T>::SetterProxy(lua_State* state)
|
||||
{
|
||||
NzLuaInstance& lua = *NzLuaInstance::GetInstance(state);
|
||||
|
||||
ClassIndexFunc func = *static_cast<ClassIndexFunc*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
|
||||
const char* className = lua.ToString(lua.GetIndexOfUpValue(2));
|
||||
|
||||
T& instance = *(*static_cast<T**>(lua.CheckUserdata(1, className)));
|
||||
lua.Remove(1);
|
||||
|
||||
if (!func(lua, instance))
|
||||
lua.Error("Field not found");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include <Nazara/Lua/DebugOff.hpp>
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
// Copyright (C) 2013 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_LUASTATE_HPP
|
||||
#define NAZARA_LUASTATE_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Clock.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Lua/Enums.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
struct lua_Debug;
|
||||
struct lua_State;
|
||||
|
||||
class NzLuaInstance;
|
||||
|
||||
using NzLuaCFunction = int (*)(lua_State* state);
|
||||
using NzLuaFunction = int (*)(NzLuaInstance& instance);
|
||||
|
||||
class NAZARA_API NzLuaInstance : NzNonCopyable
|
||||
{
|
||||
public:
|
||||
NzLuaInstance();
|
||||
~NzLuaInstance();
|
||||
|
||||
void CheckAny(int index) const;
|
||||
int CheckInteger(int index) const;
|
||||
int CheckInteger(int index, int defValue) const;
|
||||
double CheckNumber(int index) const;
|
||||
double CheckNumber(int index, double defValue) const;
|
||||
void CheckStack(int space, const char* error = nullptr) const;
|
||||
void CheckStack(int space, const NzString& error) const;
|
||||
const char* CheckString(int index, std::size_t* length = nullptr) const;
|
||||
const char* CheckString(int index, const char* defValue, std::size_t* length = nullptr) const;
|
||||
void CheckType(int index, nzLuaType type) const;
|
||||
unsigned int CheckUnsigned(int index) const;
|
||||
unsigned int CheckUnsigned(int index, unsigned int defValue) const;
|
||||
void* CheckUserdata(int index, const char* tname) const;
|
||||
void* CheckUserdata(int index, const NzString& tname) const;
|
||||
|
||||
bool Compare(int index1, int index2, nzLuaComparison comparison) const;
|
||||
void Compute(nzLuaOperation operation);
|
||||
|
||||
void Concatenate(int count);
|
||||
|
||||
void Error(const char* message);
|
||||
void Error(const NzString& message);
|
||||
|
||||
bool Execute(const NzString& code);
|
||||
bool ExecuteFromFile(const NzString& filePath);
|
||||
bool ExecuteFromMemory(const void* data, unsigned int size);
|
||||
bool ExecuteFromStream(NzInputStream& stream);
|
||||
|
||||
int GetAbsIndex(int index) const;
|
||||
void GetField(const char* fieldName, int index = -1) const;
|
||||
void GetField(const NzString& fieldName, int index = -1) const;
|
||||
void GetGlobal(const char* name) const;
|
||||
void GetGlobal(const NzString& name) const;
|
||||
lua_State* GetInternalState() const;
|
||||
NzString GetLastError() const;
|
||||
nzUInt32 GetMemoryLimit() const;
|
||||
nzUInt32 GetMemoryUsage() const;
|
||||
void GetMetatable(const char* tname) const;
|
||||
void GetMetatable(const NzString& tname) const;
|
||||
bool GetMetatable(int index) const;
|
||||
unsigned int GetStackTop() const;
|
||||
void GetTable(int index = -2) const;
|
||||
nzUInt32 GetTimeLimit() const;
|
||||
nzLuaType GetType(int index) const;
|
||||
const char* GetTypeName(nzLuaType type) const;
|
||||
|
||||
void Insert(int index);
|
||||
|
||||
bool IsOfType(int index, nzLuaType type) const;
|
||||
bool IsOfType(int index, const char* tname) const;
|
||||
bool IsOfType(int index, const NzString& tname) const;
|
||||
bool IsValid(int index) const;
|
||||
|
||||
unsigned int Length(int index) const;
|
||||
|
||||
void MoveTo(NzLuaInstance* instance, int n);
|
||||
|
||||
bool NewMetatable(const char* str);
|
||||
bool NewMetatable(const NzString& str);
|
||||
bool Next(int index = -2);
|
||||
|
||||
void Pop(unsigned int n = 1U);
|
||||
|
||||
void PushBoolean(bool value);
|
||||
void PushCFunction(NzLuaCFunction func, int valueCount = 0);
|
||||
void PushFunction(NzLuaFunction func);
|
||||
void PushInteger(int value);
|
||||
void PushLightUserdata(void* value);
|
||||
void PushMetatable(const char* str);
|
||||
void PushMetatable(const NzString& str);
|
||||
void PushNil();
|
||||
void PushNumber(double value);
|
||||
void PushString(const char* str);
|
||||
void PushString(const NzString& str);
|
||||
void PushTable(unsigned int sequenceElementCount = 0, unsigned int arrayElementCount = 0);
|
||||
void PushUnsigned(unsigned int value);
|
||||
void* PushUserdata(unsigned int size);
|
||||
void PushValue(int index);
|
||||
|
||||
void Remove(int index);
|
||||
void Replace(int index);
|
||||
|
||||
void SetField(const char* name, int index = -2);
|
||||
void SetField(const NzString& name, int index = -2);
|
||||
void SetGlobal(const char* name);
|
||||
void SetGlobal(const NzString& name);
|
||||
void SetMetatable(const char* tname);
|
||||
void SetMetatable(const NzString& tname);
|
||||
void SetMetatable(int index);
|
||||
void SetMemoryLimit(nzUInt32 memoryLimit);
|
||||
void SetTable(int index = -3);
|
||||
void SetTimeLimit(nzUInt32 timeLimit);
|
||||
|
||||
bool ToBoolean(int index) const;
|
||||
int ToInteger(int index, bool* succeeded = nullptr) const;
|
||||
double ToNumber(int index, bool* succeeded = nullptr) const;
|
||||
const char* ToString(int index, std::size_t* length = nullptr) const;
|
||||
unsigned int ToUnsigned(int index, bool* succeeded = nullptr) const;
|
||||
void* ToUserdata(int index) const;
|
||||
void* ToUserdata(int index, const char* tname) const;
|
||||
void* ToUserdata(int index, const NzString& tname) const;
|
||||
|
||||
static int GetIndexOfUpValue(int upValue);
|
||||
static NzLuaInstance* GetInstance(lua_State* state);
|
||||
|
||||
private:
|
||||
bool Run();
|
||||
|
||||
static void* MemoryAllocator(void *ud, void *ptr, std::size_t osize, std::size_t nsize);
|
||||
static int ProxyFunc(lua_State* state);
|
||||
static void TimeLimiter(lua_State* state, lua_Debug* debug);
|
||||
|
||||
nzUInt32 m_memoryLimit;
|
||||
nzUInt32 m_memoryUsage;
|
||||
nzUInt32 m_timeLimit;
|
||||
NzClock m_clock;
|
||||
NzString m_lastError;
|
||||
lua_State* m_state;
|
||||
unsigned int m_level;
|
||||
};
|
||||
|
||||
#endif // NAZARA_LUASTATE_HPP
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (C) 2013 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/Config.hpp>
|
||||
#if NAZARA_LUA_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG)
|
||||
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
|
||||
#include <new>
|
||||
|
||||
void* operator new(std::size_t size)
|
||||
{
|
||||
return NzMemoryManager::Allocate(size, false);
|
||||
}
|
||||
|
||||
void* operator new[](std::size_t size)
|
||||
{
|
||||
return NzMemoryManager::Allocate(size, true);
|
||||
}
|
||||
|
||||
void operator delete(void* pointer) noexcept
|
||||
{
|
||||
NzMemoryManager::Free(pointer, false);
|
||||
}
|
||||
|
||||
void operator delete[](void* pointer) noexcept
|
||||
{
|
||||
NzMemoryManager::Free(pointer, true);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (C) 2013 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/Lua.hpp>
|
||||
#include <Nazara/Core/Core.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Lua/Config.hpp>
|
||||
#include <Nazara/Lua/Debug.hpp>
|
||||
|
||||
bool NzLua::Initialize()
|
||||
{
|
||||
if (s_moduleReferenceCounter++ != 0)
|
||||
return true; // Déjà initialisé
|
||||
|
||||
// Initialisation des dépendances
|
||||
if (!NzCore::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize core module");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialisation du module
|
||||
|
||||
NazaraNotice("Initialized: Lua module");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzLua::IsInitialized()
|
||||
{
|
||||
return s_moduleReferenceCounter != 0;
|
||||
}
|
||||
|
||||
void NzLua::Uninitialize()
|
||||
{
|
||||
if (s_moduleReferenceCounter != 1)
|
||||
{
|
||||
// Le module est soit encore utilisé, soit pas initialisé
|
||||
if (s_moduleReferenceCounter > 1)
|
||||
s_moduleReferenceCounter--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Libération du module
|
||||
s_moduleReferenceCounter = 0;
|
||||
|
||||
NazaraNotice("Uninitialized: Lua module");
|
||||
|
||||
// Libération des dépendances
|
||||
NzCore::Uninitialize();
|
||||
}
|
||||
|
||||
unsigned int NzLua::s_moduleReferenceCounter = 0;
|
||||
|
|
@ -0,0 +1,790 @@
|
|||
// Copyright (C) 2013 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/LuaInstance.hpp>
|
||||
#include <Lua/lauxlib.h>
|
||||
#include <Lua/lua.h>
|
||||
#include <Lua/lualib.h>
|
||||
#include <Nazara/Core/Clock.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Core/MemoryStream.hpp>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
#include <Nazara/Lua/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct StreamData
|
||||
{
|
||||
NzInputStream* stream;
|
||||
char buffer[NAZARA_CORE_FILE_BUFFERSIZE];
|
||||
};
|
||||
|
||||
int AtPanic(lua_State* state)
|
||||
{
|
||||
NazaraUnused(state);
|
||||
|
||||
throw std::runtime_error("Lua panic !");
|
||||
}
|
||||
|
||||
const char* StreamReader(lua_State* state, void* data, std::size_t* size)
|
||||
{
|
||||
NazaraUnused(state);
|
||||
|
||||
StreamData* streamData = static_cast<StreamData*>(data);
|
||||
|
||||
if (streamData->stream->EndOfStream())
|
||||
return nullptr;
|
||||
else
|
||||
{
|
||||
*size = streamData->stream->Read(streamData->buffer, NAZARA_CORE_FILE_BUFFERSIZE);
|
||||
return streamData->buffer;
|
||||
}
|
||||
}
|
||||
|
||||
int s_comparisons[nzLuaComparison_Max+1] = {
|
||||
LUA_OPEQ, // nzLuaComparison_Equality
|
||||
LUA_OPLT, // nzLuaComparison_Less
|
||||
LUA_OPLE // nzLuaComparison_LessOrEqual
|
||||
};
|
||||
|
||||
int s_operations[nzLuaOperation_Max+1] = {
|
||||
LUA_OPADD, // nzLuaOperation_Addition
|
||||
LUA_OPDIV, // nzLuaOperation_Division
|
||||
LUA_OPPOW, // nzLuaOperation_Exponentiation
|
||||
LUA_OPMOD, // nzLuaOperation_Modulo
|
||||
LUA_OPMUL, // nzLuaOperation_Multiplication
|
||||
LUA_OPUNM, // nzLuaOperation_Negation
|
||||
LUA_OPSUB // nzLuaOperation_Substraction
|
||||
};
|
||||
|
||||
int s_types[nzLuaType_Max+1] = {
|
||||
LUA_TBOOLEAN, // nzLuaType_Boolean
|
||||
LUA_TFUNCTION, // nzLuaType_Function
|
||||
LUA_TLIGHTUSERDATA, // nzLuaType_LightUserdata
|
||||
LUA_TNIL, // nzLuaType_Nil
|
||||
LUA_TNUMBER, // nzLuaType_Number
|
||||
LUA_TNONE, // nzLuaType_None
|
||||
LUA_TSTRING, // nzLuaType_String
|
||||
LUA_TTABLE, // nzLuaType_Table
|
||||
LUA_TTHREAD, // nzLuaType_Thread
|
||||
LUA_TUSERDATA // nzLuaType_Userdata
|
||||
};
|
||||
}
|
||||
|
||||
NzLuaInstance::NzLuaInstance() :
|
||||
m_memoryLimit(0),
|
||||
m_memoryUsage(0),
|
||||
m_timeLimit(1000),
|
||||
m_level(0)
|
||||
{
|
||||
m_state = lua_newstate(MemoryAllocator, this);
|
||||
lua_atpanic(m_state, AtPanic);
|
||||
lua_sethook(m_state, TimeLimiter, LUA_MASKCOUNT, 1000);
|
||||
luaL_openlibs(m_state);
|
||||
}
|
||||
|
||||
NzLuaInstance::~NzLuaInstance()
|
||||
{
|
||||
lua_close(m_state);
|
||||
}
|
||||
|
||||
void NzLuaInstance::CheckAny(int index) const
|
||||
{
|
||||
luaL_checkany(m_state, index);
|
||||
}
|
||||
|
||||
int NzLuaInstance::CheckInteger(int index) const
|
||||
{
|
||||
return luaL_checkint(m_state, index);
|
||||
}
|
||||
|
||||
int NzLuaInstance::CheckInteger(int index, int defValue) const
|
||||
{
|
||||
return luaL_optint(m_state, index, defValue);
|
||||
}
|
||||
|
||||
double NzLuaInstance::CheckNumber(int index) const
|
||||
{
|
||||
return luaL_checknumber(m_state, index);
|
||||
}
|
||||
|
||||
double NzLuaInstance::CheckNumber(int index, double defValue) const
|
||||
{
|
||||
return luaL_optnumber(m_state, index, defValue);
|
||||
}
|
||||
|
||||
void NzLuaInstance::CheckStack(int space, const char* error) const
|
||||
{
|
||||
luaL_checkstack(m_state, space, error);
|
||||
}
|
||||
|
||||
void NzLuaInstance::CheckStack(int space, const NzString& error) const
|
||||
{
|
||||
CheckStack(space, error.GetConstBuffer());
|
||||
}
|
||||
|
||||
const char* NzLuaInstance::CheckString(int index, std::size_t* length) const
|
||||
{
|
||||
return luaL_checklstring(m_state, index, length);
|
||||
}
|
||||
|
||||
const char* NzLuaInstance::CheckString(int index, const char* defValue, std::size_t* length) const
|
||||
{
|
||||
return luaL_optlstring(m_state, index, defValue, length);
|
||||
}
|
||||
|
||||
void NzLuaInstance::CheckType(int index, nzLuaType type) const
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (type > nzLuaType_Max)
|
||||
{
|
||||
NazaraError("Lua type out of enum");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
luaL_checktype(m_state, index, s_types[type]);
|
||||
}
|
||||
|
||||
unsigned int NzLuaInstance::CheckUnsigned(int index) const
|
||||
{
|
||||
return luaL_checkunsigned(m_state, index);
|
||||
}
|
||||
|
||||
unsigned int NzLuaInstance::CheckUnsigned(int index, unsigned int defValue) const
|
||||
{
|
||||
return luaL_optunsigned(m_state, index, defValue);
|
||||
}
|
||||
|
||||
void* NzLuaInstance::CheckUserdata(int index, const char* tname) const
|
||||
{
|
||||
return luaL_checkudata(m_state, index, tname);
|
||||
}
|
||||
|
||||
void* NzLuaInstance::CheckUserdata(int index, const NzString& tname) const
|
||||
{
|
||||
return luaL_checkudata(m_state, index, tname.GetConstBuffer());
|
||||
}
|
||||
|
||||
bool NzLuaInstance::Compare(int index1, int index2, nzLuaComparison comparison) const
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (comparison > nzLuaComparison_Max)
|
||||
{
|
||||
NazaraError("Lua comparison out of enum");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return lua_compare(m_state, index1, index2, s_comparisons[comparison]);
|
||||
}
|
||||
|
||||
void NzLuaInstance::Compute(nzLuaOperation operation)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (operation > nzLuaOperation_Max)
|
||||
{
|
||||
NazaraError("Lua operation out of enum");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
lua_arith(m_state, s_operations[operation]);
|
||||
}
|
||||
|
||||
void NzLuaInstance::Concatenate(int count)
|
||||
{
|
||||
lua_concat(m_state, count);
|
||||
}
|
||||
|
||||
void NzLuaInstance::Error(const char* message)
|
||||
{
|
||||
luaL_error(m_state, message);
|
||||
}
|
||||
|
||||
void NzLuaInstance::Error(const NzString& message)
|
||||
{
|
||||
luaL_error(m_state, message.GetConstBuffer());
|
||||
}
|
||||
|
||||
bool NzLuaInstance::Execute(const NzString& code)
|
||||
{
|
||||
if (code.IsEmpty())
|
||||
return true;
|
||||
|
||||
if (luaL_loadstring(m_state, code.GetConstBuffer()) != 0)
|
||||
{
|
||||
m_lastError = lua_tostring(m_state, -1);
|
||||
lua_pop(m_state, 1);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_level++ == 0)
|
||||
m_clock.Restart();
|
||||
|
||||
int status = lua_pcall(m_state, 0, LUA_MULTRET, 0);
|
||||
|
||||
m_level--;
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
m_lastError = lua_tostring(m_state, -1);
|
||||
lua_pop(m_state, 1);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzLuaInstance::ExecuteFromFile(const NzString& filePath)
|
||||
{
|
||||
NzFile file(filePath);
|
||||
if (!file.Open(NzFile::ReadOnly | NzFile::Text))
|
||||
{
|
||||
NazaraError("Failed to open file");
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int length = file.GetSize();
|
||||
|
||||
NzString source;
|
||||
source.Resize(length);
|
||||
|
||||
if (file.Read(&source[0], length) != length)
|
||||
{
|
||||
NazaraError("Failed to read file");
|
||||
return false;
|
||||
}
|
||||
|
||||
file.Close();
|
||||
|
||||
return Execute(source);
|
||||
}
|
||||
|
||||
bool NzLuaInstance::ExecuteFromMemory(const void* data, unsigned int size)
|
||||
{
|
||||
NzMemoryStream stream(data, size);
|
||||
return ExecuteFromStream(stream);
|
||||
}
|
||||
|
||||
bool NzLuaInstance::ExecuteFromStream(NzInputStream& stream)
|
||||
{
|
||||
StreamData data;
|
||||
data.stream = &stream;
|
||||
|
||||
if (lua_load(m_state, StreamReader, &data, "C", nullptr) != 0)
|
||||
{
|
||||
m_lastError = lua_tostring(m_state, -1);
|
||||
lua_pop(m_state, 1);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return Run();
|
||||
}
|
||||
|
||||
int NzLuaInstance::GetAbsIndex(int index) const
|
||||
{
|
||||
return lua_absindex(m_state, index);
|
||||
}
|
||||
|
||||
void NzLuaInstance::GetField(const char* fieldName, int index) const
|
||||
{
|
||||
lua_getfield(m_state, index, fieldName);
|
||||
}
|
||||
|
||||
void NzLuaInstance::GetField(const NzString& fieldName, int index) const
|
||||
{
|
||||
lua_getfield(m_state, index, fieldName.GetConstBuffer());
|
||||
}
|
||||
|
||||
void NzLuaInstance::GetGlobal(const char* name) const
|
||||
{
|
||||
lua_getglobal(m_state, name);
|
||||
}
|
||||
|
||||
void NzLuaInstance::GetGlobal(const NzString& name) const
|
||||
{
|
||||
lua_getglobal(m_state, name.GetConstBuffer());
|
||||
}
|
||||
|
||||
lua_State* NzLuaInstance::GetInternalState() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
NzString NzLuaInstance::GetLastError() const
|
||||
{
|
||||
return m_lastError;
|
||||
}
|
||||
|
||||
nzUInt32 NzLuaInstance::GetMemoryLimit() const
|
||||
{
|
||||
return m_memoryLimit;
|
||||
}
|
||||
|
||||
nzUInt32 NzLuaInstance::GetMemoryUsage() const
|
||||
{
|
||||
return m_memoryUsage;
|
||||
}
|
||||
|
||||
void NzLuaInstance::GetMetatable(const char* tname) const
|
||||
{
|
||||
luaL_getmetatable(m_state, tname);
|
||||
}
|
||||
|
||||
void NzLuaInstance::GetMetatable(const NzString& tname) const
|
||||
{
|
||||
luaL_getmetatable(m_state, tname.GetConstBuffer());
|
||||
}
|
||||
|
||||
bool NzLuaInstance::GetMetatable(int index) const
|
||||
{
|
||||
return lua_getmetatable(m_state, index);
|
||||
}
|
||||
|
||||
unsigned int NzLuaInstance::GetStackTop() const
|
||||
{
|
||||
return lua_gettop(m_state);
|
||||
}
|
||||
|
||||
void NzLuaInstance::GetTable(int index) const
|
||||
{
|
||||
lua_gettable(m_state, index);
|
||||
}
|
||||
|
||||
nzUInt32 NzLuaInstance::GetTimeLimit() const
|
||||
{
|
||||
return m_timeLimit;
|
||||
}
|
||||
|
||||
nzLuaType NzLuaInstance::GetType(int index) const
|
||||
{
|
||||
switch (lua_type(m_state, index))
|
||||
{
|
||||
case LUA_TBOOLEAN:
|
||||
return nzLuaType_Boolean;
|
||||
|
||||
case LUA_TFUNCTION:
|
||||
return nzLuaType_Function;
|
||||
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
return nzLuaType_LightUserdata;
|
||||
|
||||
case LUA_TNIL:
|
||||
return nzLuaType_Nil;
|
||||
|
||||
case LUA_TNONE:
|
||||
return nzLuaType_None;
|
||||
|
||||
case LUA_TNUMBER:
|
||||
return nzLuaType_Number;
|
||||
|
||||
case LUA_TSTRING:
|
||||
return nzLuaType_String;
|
||||
|
||||
case LUA_TTABLE:
|
||||
return nzLuaType_Table;
|
||||
|
||||
case LUA_TTHREAD:
|
||||
return nzLuaType_Thread;
|
||||
|
||||
case LUA_TUSERDATA:
|
||||
return nzLuaType_Userdata;
|
||||
|
||||
default:
|
||||
return nzLuaType_None;
|
||||
}
|
||||
}
|
||||
|
||||
const char* NzLuaInstance::GetTypeName(nzLuaType type) const
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (type > nzLuaType_Max)
|
||||
{
|
||||
NazaraError("Lua type out of enum");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return lua_typename(m_state, s_types[type]);
|
||||
}
|
||||
|
||||
void NzLuaInstance::Insert(int index)
|
||||
{
|
||||
lua_insert(m_state, index);
|
||||
}
|
||||
|
||||
bool NzLuaInstance::IsOfType(int index, nzLuaType type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case nzLuaType_Boolean:
|
||||
return lua_isboolean(m_state, index);
|
||||
|
||||
case nzLuaType_Function:
|
||||
return lua_isfunction(m_state, index);
|
||||
|
||||
case nzLuaType_LightUserdata:
|
||||
return lua_islightuserdata(m_state, index);
|
||||
|
||||
case nzLuaType_Nil:
|
||||
return lua_isnil(m_state, index);
|
||||
|
||||
case nzLuaType_None:
|
||||
return lua_isnone(m_state, index);
|
||||
|
||||
case nzLuaType_Number:
|
||||
return lua_isnumber(m_state, index);
|
||||
|
||||
case nzLuaType_String:
|
||||
return lua_isstring(m_state, index);
|
||||
|
||||
case nzLuaType_Table:
|
||||
return lua_istable(m_state, index);
|
||||
|
||||
case nzLuaType_Thread:
|
||||
return lua_isthread(m_state, index);
|
||||
|
||||
case nzLuaType_Userdata:
|
||||
return lua_isuserdata(m_state, index);
|
||||
}
|
||||
|
||||
NazaraError("Lua type unhandled (0x" + NzString::Number(type, 16) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NzLuaInstance::IsOfType(int index, const char* tname) const
|
||||
{
|
||||
void* ud = luaL_testudata(m_state, index, tname);
|
||||
return ud != nullptr;
|
||||
}
|
||||
|
||||
bool NzLuaInstance::IsOfType(int index, const NzString& tname) const
|
||||
{
|
||||
return IsOfType(index, tname.GetConstBuffer());
|
||||
}
|
||||
|
||||
bool NzLuaInstance::IsValid(int index) const
|
||||
{
|
||||
return !lua_isnoneornil(m_state, index);
|
||||
}
|
||||
|
||||
unsigned int NzLuaInstance::Length(int index) const
|
||||
{
|
||||
return luaL_len(m_state, index);
|
||||
}
|
||||
|
||||
void NzLuaInstance::MoveTo(NzLuaInstance* instance, int n)
|
||||
{
|
||||
lua_xmove(m_state, instance->m_state, n);
|
||||
}
|
||||
|
||||
bool NzLuaInstance::NewMetatable(const char* str)
|
||||
{
|
||||
return luaL_newmetatable(m_state, str);
|
||||
}
|
||||
|
||||
bool NzLuaInstance::NewMetatable(const NzString& str)
|
||||
{
|
||||
return luaL_newmetatable(m_state, str.GetConstBuffer());
|
||||
}
|
||||
|
||||
bool NzLuaInstance::Next(int index)
|
||||
{
|
||||
return lua_next(m_state, index);
|
||||
}
|
||||
|
||||
void NzLuaInstance::Pop(unsigned int n)
|
||||
{
|
||||
lua_pop(m_state, n);
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushBoolean(bool value)
|
||||
{
|
||||
lua_pushboolean(m_state, value);
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushCFunction(NzLuaCFunction func, int valueCount)
|
||||
{
|
||||
lua_pushcclosure(m_state, func, valueCount);
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushFunction(NzLuaFunction func)
|
||||
{
|
||||
NzLuaFunction* luaFunc = reinterpret_cast<NzLuaFunction*>(lua_newuserdata(m_state, sizeof(NzLuaFunction)));
|
||||
*luaFunc = func;
|
||||
|
||||
lua_pushcclosure(m_state, ProxyFunc, 1);
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushInteger(int value)
|
||||
{
|
||||
lua_pushinteger(m_state, value);
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushLightUserdata(void* value)
|
||||
{
|
||||
lua_pushlightuserdata(m_state, value);
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushMetatable(const char* str)
|
||||
{
|
||||
luaL_getmetatable(m_state, str);
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushMetatable(const NzString& str)
|
||||
{
|
||||
luaL_getmetatable(m_state, str.GetConstBuffer());
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushNil()
|
||||
{
|
||||
lua_pushnil(m_state);
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushNumber(double value)
|
||||
{
|
||||
lua_pushnumber(m_state, value);
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushString(const char* str)
|
||||
{
|
||||
lua_pushstring(m_state, str);
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushString(const NzString& str)
|
||||
{
|
||||
lua_pushlstring(m_state, str.GetConstBuffer(), str.GetSize());
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushTable(unsigned int sequenceElementCount, unsigned int arrayElementCount)
|
||||
{
|
||||
lua_createtable(m_state, sequenceElementCount, arrayElementCount);
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushUnsigned(unsigned int value)
|
||||
{
|
||||
lua_pushunsigned(m_state, value);
|
||||
}
|
||||
|
||||
void* NzLuaInstance::PushUserdata(unsigned int size)
|
||||
{
|
||||
return lua_newuserdata(m_state, size);
|
||||
}
|
||||
|
||||
void NzLuaInstance::PushValue(int index)
|
||||
{
|
||||
lua_pushvalue(m_state, index);
|
||||
}
|
||||
|
||||
void NzLuaInstance::Remove(int index)
|
||||
{
|
||||
lua_remove(m_state, index);
|
||||
}
|
||||
|
||||
void NzLuaInstance::Replace(int index)
|
||||
{
|
||||
lua_replace(m_state, index);
|
||||
}
|
||||
|
||||
void NzLuaInstance::SetField(const char* name, int index)
|
||||
{
|
||||
lua_setfield(m_state, index, name);
|
||||
}
|
||||
|
||||
void NzLuaInstance::SetField(const NzString& name, int index)
|
||||
{
|
||||
lua_setfield(m_state, index, name.GetConstBuffer());
|
||||
}
|
||||
|
||||
void NzLuaInstance::SetGlobal(const char* name)
|
||||
{
|
||||
lua_setglobal(m_state, name);
|
||||
}
|
||||
|
||||
void NzLuaInstance::SetGlobal(const NzString& name)
|
||||
{
|
||||
lua_setglobal(m_state, name.GetConstBuffer());
|
||||
}
|
||||
|
||||
void NzLuaInstance::SetMetatable(const char* tname)
|
||||
{
|
||||
luaL_setmetatable(m_state, tname);
|
||||
}
|
||||
|
||||
void NzLuaInstance::SetMetatable(const NzString& tname)
|
||||
{
|
||||
luaL_setmetatable(m_state, tname.GetConstBuffer());
|
||||
}
|
||||
|
||||
void NzLuaInstance::SetMetatable(int index)
|
||||
{
|
||||
lua_setmetatable(m_state, index);
|
||||
}
|
||||
|
||||
void NzLuaInstance::SetMemoryLimit(nzUInt32 memoryLimit)
|
||||
{
|
||||
m_memoryLimit = memoryLimit;
|
||||
}
|
||||
|
||||
void NzLuaInstance::SetTable(int index)
|
||||
{
|
||||
lua_settable(m_state, index);
|
||||
}
|
||||
|
||||
void NzLuaInstance::SetTimeLimit(nzUInt32 timeLimit)
|
||||
{
|
||||
if (m_timeLimit != timeLimit)
|
||||
{
|
||||
if (m_timeLimit == 0)
|
||||
lua_sethook(m_state, TimeLimiter, LUA_MASKCOUNT, 1000);
|
||||
else if (timeLimit == 0)
|
||||
lua_sethook(m_state, TimeLimiter, 0, 1000);
|
||||
|
||||
m_timeLimit = timeLimit;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzLuaInstance::ToBoolean(int index) const
|
||||
{
|
||||
return lua_toboolean(m_state, index);
|
||||
}
|
||||
|
||||
int NzLuaInstance::ToInteger(int index, bool* succeeded) const
|
||||
{
|
||||
int success;
|
||||
int result = lua_tointegerx(m_state, index, &success);
|
||||
|
||||
if (succeeded)
|
||||
*succeeded = success;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double NzLuaInstance::ToNumber(int index, bool* succeeded) const
|
||||
{
|
||||
int success;
|
||||
double result = lua_tonumberx(m_state, index, &success);
|
||||
|
||||
if (succeeded)
|
||||
*succeeded = success;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* NzLuaInstance::ToString(int index, std::size_t* length) const
|
||||
{
|
||||
return lua_tolstring(m_state, index, length);
|
||||
}
|
||||
|
||||
unsigned int NzLuaInstance::ToUnsigned(int index, bool* succeeded) const
|
||||
{
|
||||
int success;
|
||||
unsigned int result = lua_tounsignedx(m_state, index, &success);
|
||||
|
||||
if (succeeded)
|
||||
*succeeded = success;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void* NzLuaInstance::ToUserdata(int index) const
|
||||
{
|
||||
return lua_touserdata(m_state, index);
|
||||
}
|
||||
|
||||
void* NzLuaInstance::ToUserdata(int index, const char* tname) const
|
||||
{
|
||||
return luaL_testudata(m_state, index, tname);
|
||||
}
|
||||
|
||||
void* NzLuaInstance::ToUserdata(int index, const NzString& tname) const
|
||||
{
|
||||
return luaL_testudata(m_state, index, tname.GetConstBuffer());
|
||||
}
|
||||
|
||||
int NzLuaInstance::GetIndexOfUpValue(int upValue)
|
||||
{
|
||||
return lua_upvalueindex(upValue);
|
||||
}
|
||||
|
||||
NzLuaInstance* NzLuaInstance::GetInstance(lua_State* state)
|
||||
{
|
||||
NzLuaInstance* instance;
|
||||
lua_getallocf(state, reinterpret_cast<void**>(&instance));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool NzLuaInstance::Run()
|
||||
{
|
||||
if (m_level++ == 0)
|
||||
m_clock.Restart();
|
||||
|
||||
int status = lua_pcall(m_state, 0, 0, 0);
|
||||
|
||||
m_level--;
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
m_lastError = lua_tostring(m_state, -1);
|
||||
lua_pop(m_state, 1);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void* NzLuaInstance::MemoryAllocator(void* ud, void* ptr, std::size_t osize, std::size_t nsize)
|
||||
{
|
||||
NzLuaInstance* instance = static_cast<NzLuaInstance*>(ud);
|
||||
nzUInt32& memoryLimit = instance->m_memoryLimit;
|
||||
nzUInt32& memoryUsage = instance->m_memoryUsage;
|
||||
|
||||
if (nsize == 0)
|
||||
{
|
||||
memoryUsage -= osize;
|
||||
std::free(ptr);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
nzUInt32 usage = memoryUsage + nsize;
|
||||
if (ptr)
|
||||
usage -= osize;
|
||||
|
||||
if (memoryLimit != 0 && usage > memoryLimit)
|
||||
{
|
||||
NazaraError("Lua memory usage is over memory limit (" + NzString::Number(usage) + " > " + NzString::Number(memoryLimit) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
memoryUsage = usage;
|
||||
|
||||
return std::realloc(ptr, nsize);
|
||||
}
|
||||
}
|
||||
|
||||
int NzLuaInstance::ProxyFunc(lua_State* state)
|
||||
{
|
||||
NzLuaFunction* func = static_cast<NzLuaFunction*>(lua_touserdata(state, lua_upvalueindex(1)));
|
||||
return (*func)(*GetInstance(state));
|
||||
}
|
||||
|
||||
void NzLuaInstance::TimeLimiter(lua_State* state, lua_Debug* debug)
|
||||
{
|
||||
NazaraUnused(debug);
|
||||
|
||||
NzLuaInstance* instance = GetInstance(state);
|
||||
if (instance->m_clock.GetMilliseconds() > instance->m_timeLimit)
|
||||
luaL_error(state, "maximum execution time exceeded");
|
||||
}
|
||||
Loading…
Reference in New Issue