Added Lua module

Former-commit-id: 3f96b9aef8afffb5e8daf460480df2f3b8c37da7
This commit is contained in:
Lynix
2013-04-24 11:51:06 +02:00
parent 3ac0338285
commit 1e256bdf35
11 changed files with 1423 additions and 0 deletions

38
include/Nazara/Lua.hpp Normal file
View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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