Merge remote-tracking branch 'refs/remotes/origin/master' into reflection-mapping

This commit is contained in:
Lynix 2017-06-10 22:33:03 +02:00
commit 487bd64bcf
93 changed files with 7350 additions and 2961 deletions

View File

@ -23,7 +23,6 @@ namespace Ndk
using Factory = std::function<BaseComponent*()>;
BaseComponent(ComponentIndex componentIndex);
BaseComponent(const BaseComponent&) = default;
BaseComponent(BaseComponent&&) = default;
virtual ~BaseComponent();
@ -34,10 +33,12 @@ namespace Ndk
inline static ComponentIndex GetMaxComponentIndex();
BaseComponent& operator=(const BaseComponent&) = default;
BaseComponent& operator=(const BaseComponent&) = delete;
BaseComponent& operator=(BaseComponent&&) = default;
protected:
BaseComponent(const BaseComponent&) = default;
ComponentIndex m_componentIndex;
EntityHandle m_entity;

View File

@ -19,7 +19,7 @@
namespace Nz
{
class LuaInstance;
class LuaState;
}
namespace Ndk
@ -32,7 +32,7 @@ namespace Ndk
class NDK_API Console : public Nz::Node, public Nz::HandledObject<Console>
{
public:
Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance);
Console(World& world, const Nz::Vector2f& size, Nz::LuaState& state);
Console(const Console& console) = delete;
Console(Console&& console) = default;
~Console() = default;
@ -83,7 +83,7 @@ namespace Ndk
EntityOwner m_input;
EntityOwner m_inputBackground;
Nz::FontRef m_defaultFont;
Nz::LuaInstance& m_instance;
Nz::LuaState& m_state;
Nz::SpriteRef m_historyBackgroundSprite;
Nz::SpriteRef m_inputBackgroundSprite;
Nz::SimpleTextDrawer m_historyDrawer;

View File

@ -17,14 +17,17 @@
namespace Ndk
{
class BaseComponent;
class BaseSystem;
class Entity;
class EntityList;
class World;
using EntityHandle = Nz::ObjectHandle<Entity>;
class NDK_API Entity : public Nz::HandledObject<Entity>
{
friend class BaseSystem;
friend BaseSystem;
friend EntityList;
friend World;
public:
@ -78,13 +81,16 @@ namespace Ndk
inline Nz::Bitset<>& GetRemovedComponentBits();
inline void RegisterEntityList(EntityList* list);
inline void RegisterSystem(SystemIndex index);
inline void SetWorld(World* world) noexcept;
inline void UnregisterEntityList(EntityList* list);
inline void UnregisterSystem(SystemIndex index);
std::vector<std::unique_ptr<BaseComponent>> m_components;
std::vector<EntityList*> m_containedInLists;
Nz::Bitset<> m_componentBits;
Nz::Bitset<> m_removedComponentBits;
Nz::Bitset<> m_systemBits;

View File

@ -6,6 +6,7 @@
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <algorithm>
#include <cassert>
#include <type_traits>
#include <utility>
@ -257,11 +258,10 @@ namespace Ndk
return m_removedComponentBits;
}
/*!
* \brief Registers a system for the entity
*
* \param index Index of the system
*/
inline void Entity::RegisterEntityList(EntityList* list)
{
m_containedInLists.push_back(list);
}
inline void Entity::RegisterSystem(SystemIndex index)
{
@ -289,6 +289,16 @@ namespace Ndk
* \param index Index of the system
*/
inline void Entity::UnregisterEntityList(EntityList* list)
{
auto it = std::find(m_containedInLists.begin(), m_containedInLists.end(), list);
assert(it != m_containedInLists.end());
// Swap and pop idiom
*it = m_containedInLists.back();
m_containedInLists.pop_back();
}
inline void Entity::UnregisterSystem(SystemIndex index)
{
m_systemBits.UnboundedReset(index);

View File

@ -15,6 +15,8 @@ namespace Ndk
{
class NDK_API EntityList
{
friend Entity;
public:
class iterator;
friend iterator;
@ -23,7 +25,7 @@ namespace Ndk
inline EntityList();
inline EntityList(const EntityList& entityList);
inline EntityList(EntityList&& entityList) noexcept;
~EntityList() = default;
inline ~EntityList();
inline void Clear();
@ -46,6 +48,7 @@ namespace Ndk
private:
inline std::size_t FindNext(std::size_t currentId) const;
inline World* GetWorld() const;
inline void NotifyEntityDestruction(const Entity* entity);
Nz::Bitset<Nz::UInt64> m_entityBits;
World* m_world;
@ -56,11 +59,11 @@ namespace Ndk
friend EntityList;
public:
inline iterator(const iterator& iterator);
inline iterator(const iterator& it);
const EntityHandle& operator*() const;
inline iterator& operator=(const iterator& iterator);
inline iterator& operator=(const iterator& it);
inline iterator& operator++();
inline iterator operator++(int);

View File

@ -5,7 +5,6 @@
#include <NDK/EntityList.hpp>
#include <Nazara/Core/Error.hpp>
#include <algorithm>
#include "EntityList.hpp"
namespace Ndk
{
@ -30,6 +29,8 @@ namespace Ndk
m_entityBits(entityList.m_entityBits),
m_world(entityList.m_world)
{
for (const Ndk::EntityHandle& entity : *this)
entity->RegisterEntityList(this);
}
/*!
@ -39,6 +40,17 @@ namespace Ndk
m_entityBits(std::move(entityList.m_entityBits)),
m_world(entityList.m_world)
{
for (const Ndk::EntityHandle& entity : *this)
{
entity->UnregisterEntityList(&entityList);
entity->RegisterEntityList(this);
}
}
inline EntityList::~EntityList()
{
for (const Ndk::EntityHandle& entity : *this)
entity->UnregisterEntityList(this);
}
@ -49,6 +61,9 @@ namespace Ndk
*/
inline void EntityList::Clear()
{
for (const Ndk::EntityHandle& entity : *this)
entity->UnregisterEntityList(this);
m_entityBits.Clear();
m_world = nullptr;
}
@ -88,15 +103,18 @@ namespace Ndk
*
* \remark If entity is already contained, no action is performed
* \remark If any entity has been inserted since construction (or last Clear call), the entity must belong to the same world as the previously inserted entities
* \remark It's up to the programmer to remove an entity from this list before its deletion
*/
inline void EntityList::Insert(Entity* entity)
{
NazaraAssert(entity, "Invalid entity");
NazaraAssert(!m_world || entity->GetWorld() == m_world, "Incompatible world");
m_entityBits.UnboundedSet(entity->GetId(), true);
m_world = entity->GetWorld();
if (!Has(entity))
{
entity->RegisterEntityList(this);
m_entityBits.UnboundedSet(entity->GetId(), true);
m_world = entity->GetWorld();
}
}
/*!
@ -111,7 +129,12 @@ namespace Ndk
*/
inline void EntityList::Remove(Entity* entity)
{
m_entityBits.UnboundedSet(entity->GetId(), false);
if (Has(entity))
{
m_entityBits.Reset(entity->GetId());
entity->UnregisterEntityList(this);
}
}
// STL Interface
@ -140,14 +163,23 @@ namespace Ndk
m_entityBits = entityList.m_entityBits;
m_world = entityList.m_world;
for (const Ndk::EntityHandle& entity : *this)
entity->RegisterEntityList(this);
return *this;
}
inline EntityList& EntityList::operator=(EntityList && entityList) noexcept
inline EntityList& EntityList::operator=(EntityList&& entityList) noexcept
{
m_entityBits = std::move(entityList.m_entityBits);
m_world = entityList.m_world;
for (const Ndk::EntityHandle& entity : *this)
{
entity->UnregisterEntityList(&entityList);
entity->RegisterEntityList(this);
}
return *this;
}
@ -161,6 +193,13 @@ namespace Ndk
return m_world;
}
inline void EntityList::NotifyEntityDestruction(const Entity* entity)
{
assert(Has(entity));
m_entityBits.Reset(entity->GetId());
}
inline EntityList::iterator::iterator(const EntityList* list, std::size_t nextId) :
m_nextEntityId(nextId),
@ -168,16 +207,16 @@ namespace Ndk
{
}
inline EntityList::iterator::iterator(const iterator& iterator) :
m_nextEntityId(iterator.m_nextEntityId),
m_list(iterator.m_list)
inline EntityList::iterator::iterator(const iterator& it) :
m_nextEntityId(it.m_nextEntityId),
m_list(it.m_list)
{
}
inline EntityList::iterator& EntityList::iterator::operator=(const iterator& iterator)
inline EntityList::iterator& EntityList::iterator::operator=(const iterator& it)
{
m_nextEntityId = iterator.m_nextEntityId;
m_list = iterator.m_list;
m_nextEntityId = it.m_nextEntityId;
m_list = it.m_list;
return *this;
}
@ -216,6 +255,6 @@ namespace Ndk
using std::swap;
std::swap(lhs.m_nextEntityId, rhs.m_nextEntityId);
swap(lhs.m_nextEntityId, rhs.m_nextEntityId);
}
}

View File

@ -24,7 +24,7 @@ namespace Ndk
template<typename T> void BindComponent(const Nz::String& name);
void RegisterClasses(Nz::LuaInstance& instance);
void RegisterClasses(Nz::LuaState& state);
std::unique_ptr<LuaBinding_Base> core;
std::unique_ptr<LuaBinding_Base> math;
@ -40,13 +40,13 @@ namespace Ndk
private:
template<typename T>
static int AddComponentOfType(Nz::LuaInstance& lua, EntityHandle& handle);
static int AddComponentOfType(Nz::LuaState& lua, EntityHandle& handle);
template<typename T>
static int PushComponentOfType(Nz::LuaInstance& lua, BaseComponent& component);
static int PushComponentOfType(Nz::LuaState& lua, BaseComponent& component);
using AddComponentFunc = int(*)(Nz::LuaInstance&, EntityHandle&);
using GetComponentFunc = int(*)(Nz::LuaInstance&, BaseComponent&);
using AddComponentFunc = int(*)(Nz::LuaState&, EntityHandle&);
using GetComponentFunc = int(*)(Nz::LuaState&, BaseComponent&);
struct ComponentBinding
{
@ -56,7 +56,7 @@ namespace Ndk
Nz::String name;
};
ComponentBinding* QueryComponentIndex(Nz::LuaInstance& lua, int argIndex = 2);
ComponentBinding* QueryComponentIndex(Nz::LuaState& lua, int argIndex = 2);
std::vector<ComponentBinding> m_componentBinding;
std::unordered_map<Nz::String, ComponentIndex> m_componentBindingByName;

View File

@ -33,7 +33,7 @@ namespace Ndk
}
template<typename T>
int LuaBinding::AddComponentOfType(Nz::LuaInstance& lua, EntityHandle& handle)
int LuaBinding::AddComponentOfType(Nz::LuaState& lua, EntityHandle& handle)
{
static_assert(std::is_base_of<BaseComponent, T>::value, "ComponentType must inherit BaseComponent");
@ -43,7 +43,7 @@ namespace Ndk
}
template<typename T>
int LuaBinding::PushComponentOfType(Nz::LuaInstance& lua, BaseComponent& component)
int LuaBinding::PushComponentOfType(Nz::LuaState& lua, BaseComponent& component)
{
static_assert(std::is_base_of<BaseComponent, T>::value, "ComponentType must inherit BaseComponent");

View File

@ -21,7 +21,7 @@ namespace Ndk
LuaBinding_Audio(LuaBinding& binding);
~LuaBinding_Audio() = default;
void Register(Nz::LuaInstance& instance) override;
void Register(Nz::LuaState& state) override;
Nz::LuaClass<Nz::Music> music;
Nz::LuaClass<Nz::Sound> sound;

View File

@ -30,7 +30,7 @@ namespace Ndk
LuaBinding_Base(LuaBinding& binding);
virtual ~LuaBinding_Base();
virtual void Register(Nz::LuaInstance& instance) = 0;
virtual void Register(Nz::LuaState& state) = 0;
// Implementation lies in the respective .cpp files (still searching for a cleaner way..)
static std::unique_ptr<LuaBinding_Base> BindCore(LuaBinding& binding);

View File

@ -21,7 +21,7 @@ namespace Ndk
LuaBinding_Core(LuaBinding& binding);
~LuaBinding_Core() = default;
void Register(Nz::LuaInstance& instance) override;
void Register(Nz::LuaState& state) override;
Nz::LuaClass<Nz::Clock> clock;
Nz::LuaClass<Nz::Directory> directory;

View File

@ -22,7 +22,7 @@ namespace Ndk
LuaBinding_Graphics(LuaBinding& binding);
~LuaBinding_Graphics() = default;
void Register(Nz::LuaInstance& instance) override;
void Register(Nz::LuaState& state) override;
Nz::LuaClass<Nz::AbstractViewer> abstractViewer;
Nz::LuaClass<Nz::InstancedRenderableRef> instancedRenderable;

View File

@ -23,7 +23,7 @@ namespace Ndk
LuaBinding_Math(LuaBinding& binding);
~LuaBinding_Math() = default;
void Register(Nz::LuaInstance& instance) override;
void Register(Nz::LuaState& state) override;
Nz::LuaClass<Nz::EulerAnglesd> eulerAngles;
Nz::LuaClass<Nz::Matrix4d> matrix4d;

View File

@ -9,6 +9,7 @@
#include <Nazara/Network/AbstractSocket.hpp>
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Network/UdpSocket.hpp>
#include <NDK/Lua/LuaBinding_Base.hpp>
namespace Ndk
@ -19,10 +20,11 @@ namespace Ndk
LuaBinding_Network(LuaBinding& binding);
~LuaBinding_Network() = default;
void Register(Nz::LuaInstance& instance) override;
void Register(Nz::LuaState& state) override;
Nz::LuaClass<Nz::AbstractSocket> abstractSocket;
Nz::LuaClass<Nz::IpAddress> ipAddress;
Nz::LuaClass<Nz::UdpSocket> udpSocket;
};
}

View File

@ -18,7 +18,7 @@ namespace Ndk
LuaBinding_Renderer(LuaBinding& binding);
~LuaBinding_Renderer() = default;
void Register(Nz::LuaInstance& instance) override;
void Register(Nz::LuaState& state) override;
Nz::LuaClass<Nz::TextureRef> texture;
Nz::LuaClass<Nz::TextureLibrary> textureLibrary;

View File

@ -22,7 +22,7 @@ namespace Ndk
LuaBinding_SDK(LuaBinding& binding);
~LuaBinding_SDK() = default;
void Register(Nz::LuaInstance& instance) override;
void Register(Nz::LuaState& state) override;
Nz::LuaClass<Application*> application;
Nz::LuaClass<EntityHandle> entity;

View File

@ -21,7 +21,7 @@ namespace Ndk
LuaBinding_Utility(LuaBinding& binding);
~LuaBinding_Utility() = default;
void Register(Nz::LuaInstance& instance) override;
void Register(Nz::LuaState& state) override;
// Utility
Nz::LuaClass<Nz::AbstractImageRef> abstractImage;

View File

@ -11,7 +11,7 @@
namespace Nz
{
class LuaInstance;
class LuaState;
}
namespace Ndk
@ -28,7 +28,7 @@ namespace Ndk
static bool Initialize();
static void RegisterClasses(Nz::LuaInstance& instance);
static void RegisterClasses(Nz::LuaState& state);
static void Uninitialize();

View File

@ -4,7 +4,7 @@
#include <NDK/LuaAPI.hpp>
#include <Nazara/Core/Color.hpp>
#include <Nazara/Lua/LuaInstance.hpp>
#include <Nazara/Lua/LuaState.hpp>
#include <Nazara/Math/EulerAngles.hpp>
#include <Nazara/Math/Quaternion.hpp>
#include <Nazara/Math/Vector3.hpp>
@ -28,103 +28,103 @@
namespace Nz
{
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Color* color, TypeTag<Color>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Color* color, TypeTag<Color>)
{
instance.CheckType(index, Nz::LuaType_Table);
state.CheckType(index, Nz::LuaType_Table);
color->r = instance.CheckField<UInt8>("r", index);
color->g = instance.CheckField<UInt8>("g", index);
color->b = instance.CheckField<UInt8>("b", index);
color->a = instance.CheckField<UInt8>("a", 255, index);
color->r = state.CheckField<UInt8>("r", index);
color->g = state.CheckField<UInt8>("g", index);
color->b = state.CheckField<UInt8>("b", index);
color->a = state.CheckField<UInt8>("a", 255, index);
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesd* angles, TypeTag<EulerAnglesd>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, EulerAnglesd* angles, TypeTag<EulerAnglesd>)
{
switch (instance.GetType(index))
switch (state.GetType(index))
{
case Nz::LuaType_Table:
angles->Set(instance.CheckField<double>("pitch", index), instance.CheckField<double>("yaw", index), instance.CheckField<double>("roll", index));
angles->Set(state.CheckField<double>("pitch", index), state.CheckField<double>("yaw", index), state.CheckField<double>("roll", index));
return 1;
default:
{
if (instance.IsOfType(index, "EulerAngles"))
angles->Set(*static_cast<EulerAnglesd*>(instance.ToUserdata(index)));
if (state.IsOfType(index, "EulerAngles"))
angles->Set(*static_cast<EulerAnglesd*>(state.ToUserdata(index)));
else
angles->Set(*static_cast<Quaterniond*>(instance.CheckUserdata(index, "Quaternion")));
angles->Set(*static_cast<Quaterniond*>(state.CheckUserdata(index, "Quaternion")));
return 1;
}
}
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, EulerAnglesf* angles, TypeTag<EulerAnglesf>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, EulerAnglesf* angles, TypeTag<EulerAnglesf>)
{
EulerAnglesd anglesDouble;
unsigned int ret = LuaImplQueryArg(instance, index, &anglesDouble, TypeTag<EulerAnglesd>());
unsigned int ret = LuaImplQueryArg(state, index, &anglesDouble, TypeTag<EulerAnglesd>());
angles->Set(anglesDouble);
return ret;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, FontRef* fontRef, TypeTag<FontRef>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, FontRef* fontRef, TypeTag<FontRef>)
{
*fontRef = *static_cast<FontRef*>(instance.CheckUserdata(index, "Font"));
*fontRef = *static_cast<FontRef*>(state.CheckUserdata(index, "Font"));
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, FontParams* params, TypeTag<FontParams>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, FontParams* params, TypeTag<FontParams>)
{
NazaraUnused(params);
instance.CheckType(index, Nz::LuaType_Table);
state.CheckType(index, Nz::LuaType_Table);
// Structure is empty for now
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, ImageParams* params, TypeTag<ImageParams>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, ImageParams* params, TypeTag<ImageParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
state.CheckType(index, Nz::LuaType_Table);
params->levelCount = instance.CheckField<Nz::UInt8>("LevelCount");
params->loadFormat = instance.CheckField<Nz::PixelFormatType>("LoadFormat");
params->levelCount = state.CheckField<Nz::UInt8>("LevelCount");
params->loadFormat = state.CheckField<Nz::PixelFormatType>("LoadFormat");
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, IpAddress* address, TypeTag<IpAddress>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, IpAddress* address, TypeTag<IpAddress>)
{
switch (instance.GetType(index))
switch (state.GetType(index))
{
case Nz::LuaType_String:
address->BuildFromAddress(instance.CheckString(index));
address->BuildFromAddress(state.CheckString(index));
return 1;
default:
*address = *static_cast<IpAddress*>(instance.CheckUserdata(index, "IpAddress"));
*address = *static_cast<IpAddress*>(state.CheckUserdata(index, "IpAddress"));
return 1;
}
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Matrix4d* mat, TypeTag<Matrix4d>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Matrix4d* mat, TypeTag<Matrix4d>)
{
switch (instance.GetType(index))
switch (state.GetType(index))
{
case Nz::LuaType_Table:
{
double values[16];
for (std::size_t i = 0; i < 16; ++i)
{
instance.PushInteger(i + 1);
instance.GetTable();
state.PushInteger(i + 1);
state.GetTable();
values[i] = instance.CheckNumber(-1);
instance.Pop();
values[i] = state.CheckNumber(-1);
state.Pop();
}
mat->Set(values);
@ -133,500 +133,500 @@ namespace Nz
default:
{
if (instance.IsOfType(index, "Matrix4"))
mat->Set(*static_cast<Matrix4d*>(instance.ToUserdata(index)));
if (state.IsOfType(index, "Matrix4"))
mat->Set(*static_cast<Matrix4d*>(state.ToUserdata(index)));
return 1;
}
}
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Matrix4f* mat, TypeTag<Matrix4f>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Matrix4f* mat, TypeTag<Matrix4f>)
{
Matrix4d matDouble = Matrix4d::Identity();
unsigned int ret = LuaImplQueryArg(instance, index, &matDouble, TypeTag<Matrix4d>());
unsigned int ret = LuaImplQueryArg(state, index, &matDouble, TypeTag<Matrix4d>());
mat->Set(matDouble);
return ret;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MeshParams* params, TypeTag<MeshParams>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, MeshParams* params, TypeTag<MeshParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
state.CheckType(index, Nz::LuaType_Table);
params->animated = instance.CheckField<bool>("Animated", params->animated);
params->center = instance.CheckField<bool>("Center", params->center);
params->matrix = instance.CheckField<Matrix4f>("Matrix", params->matrix);
params->optimizeIndexBuffers = instance.CheckField<bool>("OptimizeIndexBuffers", params->optimizeIndexBuffers);
params->texCoordOffset = instance.CheckField<Vector2f>("TexCoordOffset", params->texCoordOffset);
params->texCoordScale = instance.CheckField<Vector2f>("TexCoordScale", params->texCoordScale);
params->animated = state.CheckField<bool>("Animated", params->animated);
params->center = state.CheckField<bool>("Center", params->center);
params->matrix = state.CheckField<Matrix4f>("Matrix", params->matrix);
params->optimizeIndexBuffers = state.CheckField<bool>("OptimizeIndexBuffers", params->optimizeIndexBuffers);
params->texCoordOffset = state.CheckField<Vector2f>("TexCoordOffset", params->texCoordOffset);
params->texCoordScale = state.CheckField<Vector2f>("TexCoordScale", params->texCoordScale);
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Quaterniond* quat, TypeTag<Quaterniond>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Quaterniond* quat, TypeTag<Quaterniond>)
{
switch (instance.GetType(index))
switch (state.GetType(index))
{
case Nz::LuaType_Table:
quat->Set(instance.CheckField<double>("w", index), instance.CheckField<double>("x", index), instance.CheckField<double>("y", index), instance.CheckField<double>("z", index));
quat->Set(state.CheckField<double>("w", index), state.CheckField<double>("x", index), state.CheckField<double>("y", index), state.CheckField<double>("z", index));
return 1;
default:
{
if (instance.IsOfType(index, "EulerAngles"))
quat->Set(*static_cast<EulerAnglesd*>(instance.ToUserdata(index)));
if (state.IsOfType(index, "EulerAngles"))
quat->Set(*static_cast<EulerAnglesd*>(state.ToUserdata(index)));
else
quat->Set(*static_cast<Quaterniond*>(instance.CheckUserdata(index, "Quaternion")));
quat->Set(*static_cast<Quaterniond*>(state.CheckUserdata(index, "Quaternion")));
return 1;
}
}
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Quaternionf* quat, TypeTag<Quaternionf>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Quaternionf* quat, TypeTag<Quaternionf>)
{
Quaterniond quatDouble;
unsigned int ret = LuaImplQueryArg(instance, index, &quatDouble, TypeTag<Quaterniond>());
unsigned int ret = LuaImplQueryArg(state, index, &quatDouble, TypeTag<Quaterniond>());
quat->Set(quatDouble);
return ret;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Rectd* rect, TypeTag<Rectd>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Rectd* rect, TypeTag<Rectd>)
{
instance.CheckType(index, LuaType_Table);
state.CheckType(index, LuaType_Table);
rect->x = instance.CheckField<double>("x", index);
rect->y = instance.CheckField<double>("y", index);
rect->width = instance.CheckField<double>("width", index);
rect->height = instance.CheckField<double>("height", index);
rect->x = state.CheckField<double>("x", index);
rect->y = state.CheckField<double>("y", index);
rect->width = state.CheckField<double>("width", index);
rect->height = state.CheckField<double>("height", index);
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Rectf* rect, TypeTag<Rectf>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Rectf* rect, TypeTag<Rectf>)
{
Rectd rectDouble;
unsigned int ret = LuaImplQueryArg(instance, index, &rectDouble, TypeTag<Rectd>());
unsigned int ret = LuaImplQueryArg(state, index, &rectDouble, TypeTag<Rectd>());
rect->Set(rectDouble);
return ret;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Recti* rect, TypeTag<Recti>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Recti* rect, TypeTag<Recti>)
{
Rectd rectDouble;
unsigned int ret = LuaImplQueryArg(instance, index, &rectDouble, TypeTag<Rectd>());
unsigned int ret = LuaImplQueryArg(state, index, &rectDouble, TypeTag<Rectd>());
rect->Set(rectDouble);
return ret;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Rectui* rect, TypeTag<Rectui>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Rectui* rect, TypeTag<Rectui>)
{
Rectd rectDouble;
unsigned int ret = LuaImplQueryArg(instance, index, &rectDouble, TypeTag<Rectd>());
unsigned int ret = LuaImplQueryArg(state, index, &rectDouble, TypeTag<Rectd>());
rect->Set(rectDouble);
return ret;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2d* vec, TypeTag<Vector2d>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Vector2d* vec, TypeTag<Vector2d>)
{
switch (instance.GetType(index))
switch (state.GetType(index))
{
case Nz::LuaType_Number:
if (index < 0 && index > -2)
instance.Error("Vector2 expected, two numbers are required to convert it");
state.Error("Vector2 expected, two numbers are required to convert it");
vec->Set(instance.CheckNumber(index), instance.CheckNumber(index + 1));
vec->Set(state.CheckNumber(index), state.CheckNumber(index + 1));
return 2;
case Nz::LuaType_Table:
vec->Set(instance.CheckField<double>("x", index), instance.CheckField<double>("y", index));
vec->Set(state.CheckField<double>("x", index), state.CheckField<double>("y", index));
return 1;
default:
vec->Set(*static_cast<Vector2d*>(instance.CheckUserdata(index, "Vector2")));
vec->Set(*static_cast<Vector2d*>(state.CheckUserdata(index, "Vector2")));
return 1;
}
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2f* vec, TypeTag<Vector2f>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Vector2f* vec, TypeTag<Vector2f>)
{
Vector2d vecDouble;
unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag<Vector2d>());
unsigned int ret = LuaImplQueryArg(state, index, &vecDouble, TypeTag<Vector2d>());
vec->Set(vecDouble);
return ret;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector2ui* vec, TypeTag<Vector2ui>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Vector2ui* vec, TypeTag<Vector2ui>)
{
Vector2d vecDouble;
unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag<Vector2d>());
unsigned int ret = LuaImplQueryArg(state, index, &vecDouble, TypeTag<Vector2d>());
vec->Set(vecDouble);
return ret;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3d* vec, TypeTag<Vector3d>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Vector3d* vec, TypeTag<Vector3d>)
{
switch (instance.GetType(index))
switch (state.GetType(index))
{
case Nz::LuaType_Number:
if (index < 0 && index > -3)
instance.Error("Vector3 expected, three numbers are required to convert it");
state.Error("Vector3 expected, three numbers are required to convert it");
vec->Set(instance.CheckNumber(index), instance.CheckNumber(index + 1), instance.CheckNumber(index + 2, 0.0));
vec->Set(state.CheckNumber(index), state.CheckNumber(index + 1), state.CheckNumber(index + 2, 0.0));
return 3;
case Nz::LuaType_Table:
vec->Set(instance.CheckField<double>("x", index), instance.CheckField<double>("y", index), instance.CheckField<double>("z", 0.0, index));
vec->Set(state.CheckField<double>("x", index), state.CheckField<double>("y", index), state.CheckField<double>("z", 0.0, index));
return 1;
default:
vec->Set(*static_cast<Vector3d*>(instance.CheckUserdata(index, "Vector3")));
vec->Set(*static_cast<Vector3d*>(state.CheckUserdata(index, "Vector3")));
return 1;
}
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3f* vec, TypeTag<Vector3f>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Vector3f* vec, TypeTag<Vector3f>)
{
Vector3d vecDouble;
unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag<Vector3d>());
unsigned int ret = LuaImplQueryArg(state, index, &vecDouble, TypeTag<Vector3d>());
vec->Set(vecDouble);
return ret;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Vector3ui* vec, TypeTag<Vector3ui>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Vector3ui* vec, TypeTag<Vector3ui>)
{
Vector3d vecDouble;
unsigned int ret = LuaImplQueryArg(instance, index, &vecDouble, TypeTag<Vector3d>());
unsigned int ret = LuaImplQueryArg(state, index, &vecDouble, TypeTag<Vector3d>());
vec->Set(vecDouble);
return ret;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::EntityHandle* handle, TypeTag<Ndk::EntityHandle>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Ndk::EntityHandle* handle, TypeTag<Ndk::EntityHandle>)
{
*handle = *static_cast<Ndk::EntityHandle*>(instance.CheckUserdata(index, "Entity"));
*handle = *static_cast<Ndk::EntityHandle*>(state.CheckUserdata(index, "Entity"));
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::WorldHandle* handle, TypeTag<Ndk::WorldHandle>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, Ndk::WorldHandle* handle, TypeTag<Ndk::WorldHandle>)
{
*handle = *static_cast<Ndk::WorldHandle*>(instance.CheckUserdata(index, "World"));
*handle = *static_cast<Ndk::WorldHandle*>(state.CheckUserdata(index, "World"));
return 1;
}
#ifndef NDK_SERVER
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, InstancedRenderableRef* renderable, TypeTag<InstancedRenderableRef>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, InstancedRenderableRef* renderable, TypeTag<InstancedRenderableRef>)
{
if (instance.IsOfType(index, "InstancedRenderable") ||
instance.IsOfType(index, "Model") ||
instance.IsOfType(index, "Sprite"))
if (state.IsOfType(index, "InstancedRenderable") ||
state.IsOfType(index, "Model") ||
state.IsOfType(index, "Sprite"))
{
*renderable = *static_cast<InstancedRenderableRef*>(instance.ToUserdata(index));
*renderable = *static_cast<InstancedRenderableRef*>(state.ToUserdata(index));
}
else
instance.ArgError(index, "is not a InstancedRenderable instance");
state.ArgError(index, "is not a InstancedRenderable instance");
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MaterialRef* materialRef, TypeTag<MaterialRef>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, MaterialRef* materialRef, TypeTag<MaterialRef>)
{
*materialRef = *static_cast<MaterialRef*>(instance.CheckUserdata(index, "Material"));
*materialRef = *static_cast<MaterialRef*>(state.CheckUserdata(index, "Material"));
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MaterialParams* params, TypeTag<MaterialParams>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, MaterialParams* params, TypeTag<MaterialParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
state.CheckType(index, Nz::LuaType_Table);
params->loadAlphaMap = instance.CheckField<bool>("LoadAlphaMap", params->loadAlphaMap);
params->loadDiffuseMap = instance.CheckField<bool>("LoadDiffuseMap", params->loadDiffuseMap);
params->loadEmissiveMap = instance.CheckField<bool>("LoadEmissiveMap", params->loadEmissiveMap);
params->loadHeightMap = instance.CheckField<bool>("LoadHeightMap", params->loadHeightMap);
params->loadNormalMap = instance.CheckField<bool>("LoadNormalMap", params->loadNormalMap);
params->loadSpecularMap = instance.CheckField<bool>("LoadSpecularMap", params->loadSpecularMap);
params->shaderName = instance.CheckField<String>("ShaderName", params->shaderName);
params->loadAlphaMap = state.CheckField<bool>("LoadAlphaMap", params->loadAlphaMap);
params->loadDiffuseMap = state.CheckField<bool>("LoadDiffuseMap", params->loadDiffuseMap);
params->loadEmissiveMap = state.CheckField<bool>("LoadEmissiveMap", params->loadEmissiveMap);
params->loadHeightMap = state.CheckField<bool>("LoadHeightMap", params->loadHeightMap);
params->loadNormalMap = state.CheckField<bool>("LoadNormalMap", params->loadNormalMap);
params->loadSpecularMap = state.CheckField<bool>("LoadSpecularMap", params->loadSpecularMap);
params->shaderName = state.CheckField<String>("ShaderName", params->shaderName);
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, ModelParameters* params, TypeTag<ModelParameters>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, ModelParameters* params, TypeTag<ModelParameters>)
{
instance.CheckType(index, Nz::LuaType_Table);
state.CheckType(index, Nz::LuaType_Table);
params->loadMaterials = instance.CheckField<bool>("LoadMaterials", params->loadMaterials);
params->loadMaterials = state.CheckField<bool>("LoadMaterials", params->loadMaterials);
LuaImplQueryArg(instance, -1, &params->material, TypeTag<MaterialParams>());
LuaImplQueryArg(instance, -1, &params->mesh, TypeTag<MeshParams>());
LuaImplQueryArg(state, -1, &params->material, TypeTag<MaterialParams>());
LuaImplQueryArg(state, -1, &params->mesh, TypeTag<MeshParams>());
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, MusicParams* params, TypeTag<MusicParams>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, MusicParams* params, TypeTag<MusicParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
state.CheckType(index, Nz::LuaType_Table);
params->forceMono = instance.CheckField<bool>("ForceMono", params->forceMono);
params->forceMono = state.CheckField<bool>("ForceMono", params->forceMono);
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, SoundBufferParams* params, TypeTag<SoundBufferParams>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, SoundBufferParams* params, TypeTag<SoundBufferParams>)
{
instance.CheckType(index, Nz::LuaType_Table);
state.CheckType(index, Nz::LuaType_Table);
params->forceMono = instance.CheckField<bool>("ForceMono", params->forceMono);
params->forceMono = state.CheckField<bool>("ForceMono", params->forceMono);
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, SpriteRef* spriteRef, TypeTag<SpriteRef>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, SpriteRef* spriteRef, TypeTag<SpriteRef>)
{
*spriteRef = *static_cast<SpriteRef*>(instance.CheckUserdata(index, "Sprite"));
*spriteRef = *static_cast<SpriteRef*>(state.CheckUserdata(index, "Sprite"));
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, TextureRef* textureRef, TypeTag<TextureRef>)
inline unsigned int LuaImplQueryArg(const LuaState& state, int index, TextureRef* textureRef, TypeTag<TextureRef>)
{
*textureRef = *static_cast<TextureRef*>(instance.CheckUserdata(index, "Texture"));
*textureRef = *static_cast<TextureRef*>(state.CheckUserdata(index, "Texture"));
return 1;
}
#endif
inline int LuaImplReplyVal(const LuaInstance& instance, Color&& val, TypeTag<Color>)
inline int LuaImplReplyVal(const LuaState& state, Color&& val, TypeTag<Color>)
{
instance.PushTable();
instance.PushField("r", val.r);
instance.PushField("g", val.g);
instance.PushField("b", val.b);
instance.PushField("a", val.a);
state.PushTable();
state.PushField("r", val.r);
state.PushField("g", val.g);
state.PushField("b", val.b);
state.PushField("a", val.a);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, EulerAnglesd&& val, TypeTag<EulerAnglesd>)
inline int LuaImplReplyVal(const LuaState& state, EulerAnglesd&& val, TypeTag<EulerAnglesd>)
{
instance.PushInstance<EulerAnglesd>("EulerAngles", val);
state.PushInstance<EulerAnglesd>("EulerAngles", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, EulerAnglesf&& val, TypeTag<EulerAnglesf>)
inline int LuaImplReplyVal(const LuaState& state, EulerAnglesf&& val, TypeTag<EulerAnglesf>)
{
instance.PushInstance<EulerAnglesd>("EulerAngles", val);
state.PushInstance<EulerAnglesd>("EulerAngles", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, FontRef&& val, TypeTag<FontRef>)
inline int LuaImplReplyVal(const LuaState& state, FontRef&& val, TypeTag<FontRef>)
{
instance.PushInstance<FontRef>("Font", val);
state.PushInstance<FontRef>("Font", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Font::SizeInfo&& val, TypeTag<Font::SizeInfo>)
inline int LuaImplReplyVal(const LuaState& state, Font::SizeInfo&& val, TypeTag<Font::SizeInfo>)
{
instance.PushTable();
instance.PushField("LineHeight", val.lineHeight);
instance.PushField("SpaceAdvance", val.spaceAdvance);
instance.PushField("UnderlinePosition", val.underlinePosition);
instance.PushField("UnderlineThickness", val.underlineThickness);
state.PushTable();
state.PushField("LineHeight", val.lineHeight);
state.PushField("SpaceAdvance", val.spaceAdvance);
state.PushField("UnderlinePosition", val.underlinePosition);
state.PushField("UnderlineThickness", val.underlineThickness);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, ImageParams&& val, TypeTag<ImageParams>)
inline int LuaImplReplyVal(const LuaState& state, ImageParams&& val, TypeTag<ImageParams>)
{
instance.PushTable(0, 2);
instance.PushField("LevelCount", val.levelCount);
instance.PushField("LoadFormat", val.loadFormat);
state.PushTable(0, 2);
state.PushField("LevelCount", val.levelCount);
state.PushField("LoadFormat", val.loadFormat);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, IpAddress&& val, TypeTag<IpAddress>)
inline int LuaImplReplyVal(const LuaState& state, IpAddress&& val, TypeTag<IpAddress>)
{
instance.PushInstance<IpAddress>("IpAddress", val);
state.PushInstance<IpAddress>("IpAddress", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Matrix4d&& val, TypeTag<Matrix4d>)
inline int LuaImplReplyVal(const LuaState& state, Matrix4d&& val, TypeTag<Matrix4d>)
{
instance.PushInstance<Matrix4d>("Matrix4", val);
state.PushInstance<Matrix4d>("Matrix4", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Matrix4f&& val, TypeTag<Matrix4f>)
inline int LuaImplReplyVal(const LuaState& state, Matrix4f&& val, TypeTag<Matrix4f>)
{
instance.PushInstance<Matrix4d>("Matrix4", val);
state.PushInstance<Matrix4d>("Matrix4", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Quaterniond&& val, TypeTag<Quaterniond>)
inline int LuaImplReplyVal(const LuaState& state, Quaterniond&& val, TypeTag<Quaterniond>)
{
instance.PushInstance<Quaterniond>("Quaternion", val);
state.PushInstance<Quaterniond>("Quaternion", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Quaternionf&& val, TypeTag<Quaternionf>)
inline int LuaImplReplyVal(const LuaState& state, Quaternionf&& val, TypeTag<Quaternionf>)
{
instance.PushInstance<Quaterniond>("Quaternion", val);
state.PushInstance<Quaterniond>("Quaternion", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Rectd&& val, TypeTag<Rectd>)
inline int LuaImplReplyVal(const LuaState& state, Rectd&& val, TypeTag<Rectd>)
{
instance.PushInstance<Rectd>("Rect", val);
state.PushInstance<Rectd>("Rect", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Rectf&& val, TypeTag<Rectf>)
inline int LuaImplReplyVal(const LuaState& state, Rectf&& val, TypeTag<Rectf>)
{
instance.PushInstance<Rectd>("Rect", val);
state.PushInstance<Rectd>("Rect", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Recti&& val, TypeTag<Recti>)
inline int LuaImplReplyVal(const LuaState& state, Recti&& val, TypeTag<Recti>)
{
instance.PushInstance<Rectd>("Rect", val);
state.PushInstance<Rectd>("Rect", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Rectui&& val, TypeTag<Rectui>)
inline int LuaImplReplyVal(const LuaState& state, Rectui&& val, TypeTag<Rectui>)
{
instance.PushInstance<Rectd>("Rect", val);
state.PushInstance<Rectd>("Rect", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Vector2d&& val, TypeTag<Vector2d>)
inline int LuaImplReplyVal(const LuaState& state, Vector2d&& val, TypeTag<Vector2d>)
{
instance.PushInstance<Vector2d>("Vector2", val);
state.PushInstance<Vector2d>("Vector2", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Vector2f&& val, TypeTag<Vector2f>)
inline int LuaImplReplyVal(const LuaState& state, Vector2f&& val, TypeTag<Vector2f>)
{
instance.PushInstance<Vector2d>("Vector2", val);
state.PushInstance<Vector2d>("Vector2", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Vector2ui&& val, TypeTag<Vector2ui>)
inline int LuaImplReplyVal(const LuaState& state, Vector2ui&& val, TypeTag<Vector2ui>)
{
instance.PushInstance<Vector2d>("Vector2", val);
state.PushInstance<Vector2d>("Vector2", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Vector3d&& val, TypeTag<Vector3d>)
inline int LuaImplReplyVal(const LuaState& state, Vector3d&& val, TypeTag<Vector3d>)
{
instance.PushInstance<Vector3d>("Vector3", val);
state.PushInstance<Vector3d>("Vector3", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Vector3f&& val, TypeTag<Vector3f>)
inline int LuaImplReplyVal(const LuaState& state, Vector3f&& val, TypeTag<Vector3f>)
{
instance.PushInstance<Vector3d>("Vector3", val);
state.PushInstance<Vector3d>("Vector3", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Vector3ui&& val, TypeTag<Vector3ui>)
inline int LuaImplReplyVal(const LuaState& state, Vector3ui&& val, TypeTag<Vector3ui>)
{
instance.PushInstance<Vector3d>("Vector3", val);
state.PushInstance<Vector3d>("Vector3", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::Entity* ptr, TypeTag<Ndk::Entity*>)
inline int LuaImplReplyVal(const LuaState& state, Ndk::Entity* ptr, TypeTag<Ndk::Entity*>)
{
instance.PushInstance<Ndk::EntityHandle>("Entity", ptr);
state.PushInstance<Ndk::EntityHandle>("Entity", ptr);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::Application* ptr, TypeTag<Ndk::Application*>)
inline int LuaImplReplyVal(const LuaState& state, Ndk::Application* ptr, TypeTag<Ndk::Application*>)
{
instance.PushInstance<Ndk::Application*>("Application", ptr);
state.PushInstance<Ndk::Application*>("Application", ptr);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::EntityHandle&& handle, TypeTag<Ndk::EntityHandle>)
inline int LuaImplReplyVal(const LuaState& state, Ndk::EntityHandle&& handle, TypeTag<Ndk::EntityHandle>)
{
instance.PushInstance<Ndk::EntityHandle>("Entity", handle);
state.PushInstance<Ndk::EntityHandle>("Entity", handle);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::NodeComponentHandle&& handle, TypeTag<Ndk::NodeComponentHandle>)
inline int LuaImplReplyVal(const LuaState& state, Ndk::NodeComponentHandle&& handle, TypeTag<Ndk::NodeComponentHandle>)
{
instance.PushInstance<Ndk::NodeComponentHandle>("NodeComponent", handle);
state.PushInstance<Ndk::NodeComponentHandle>("NodeComponent", handle);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::VelocityComponentHandle&& handle, TypeTag<Ndk::VelocityComponentHandle>)
inline int LuaImplReplyVal(const LuaState& state, Ndk::VelocityComponentHandle&& handle, TypeTag<Ndk::VelocityComponentHandle>)
{
instance.PushInstance<Ndk::VelocityComponentHandle>("VelocityComponent", handle);
state.PushInstance<Ndk::VelocityComponentHandle>("VelocityComponent", handle);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::World* ptr, TypeTag<Ndk::World*>)
inline int LuaImplReplyVal(const LuaState& state, Ndk::World* ptr, TypeTag<Ndk::World*>)
{
instance.PushInstance<Ndk::WorldHandle>("World", ptr);
state.PushInstance<Ndk::WorldHandle>("World", ptr);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::WorldHandle&& handle, TypeTag<Ndk::WorldHandle>)
inline int LuaImplReplyVal(const LuaState& state, Ndk::WorldHandle&& handle, TypeTag<Ndk::WorldHandle>)
{
instance.PushInstance<Ndk::WorldHandle>("World", handle);
state.PushInstance<Ndk::WorldHandle>("World", handle);
return 1;
}
#ifndef NDK_SERVER
inline int LuaImplReplyVal(const LuaInstance& instance, MaterialRef&& handle, TypeTag<MaterialRef>)
inline int LuaImplReplyVal(const LuaState& state, MaterialRef&& handle, TypeTag<MaterialRef>)
{
instance.PushInstance<MaterialRef>("Material", handle);
state.PushInstance<MaterialRef>("Material", handle);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, const SoundBuffer* val, TypeTag<const SoundBuffer*>)
inline int LuaImplReplyVal(const LuaState& state, const SoundBuffer* val, TypeTag<const SoundBuffer*>)
{
instance.PushInstance<SoundBufferConstRef>("SoundBuffer", val);
state.PushInstance<SoundBufferConstRef>("SoundBuffer", val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, SpriteRef&& handle, TypeTag<SpriteRef>)
inline int LuaImplReplyVal(const LuaState& state, SpriteRef&& handle, TypeTag<SpriteRef>)
{
instance.PushInstance<SpriteRef>("Sprite", handle);
state.PushInstance<SpriteRef>("Sprite", handle);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, TextureRef&& handle, TypeTag<TextureRef>)
inline int LuaImplReplyVal(const LuaState& state, TextureRef&& handle, TypeTag<TextureRef>)
{
instance.PushInstance<TextureRef>("Texture", handle);
state.PushInstance<TextureRef>("Texture", handle);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::CameraComponentHandle&& handle, TypeTag<Ndk::CameraComponentHandle>)
inline int LuaImplReplyVal(const LuaState& state, Ndk::CameraComponentHandle&& handle, TypeTag<Ndk::CameraComponentHandle>)
{
instance.PushInstance<Ndk::CameraComponentHandle>("CameraComponent", handle);
state.PushInstance<Ndk::CameraComponentHandle>("CameraComponent", handle);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::ConsoleHandle&& handle, TypeTag<Ndk::ConsoleHandle>)
inline int LuaImplReplyVal(const LuaState& state, Ndk::ConsoleHandle&& handle, TypeTag<Ndk::ConsoleHandle>)
{
instance.PushInstance<Ndk::ConsoleHandle>("Console", handle);
state.PushInstance<Ndk::ConsoleHandle>("Console", handle);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, Ndk::GraphicsComponentHandle&& handle, TypeTag<Ndk::GraphicsComponentHandle>)
inline int LuaImplReplyVal(const LuaState& state, Ndk::GraphicsComponentHandle&& handle, TypeTag<Ndk::GraphicsComponentHandle>)
{
instance.PushInstance<Ndk::GraphicsComponentHandle>("GraphicsComponent", handle);
state.PushInstance<Ndk::GraphicsComponentHandle>("GraphicsComponent", handle);
return 1;
}
#endif

View File

@ -164,25 +164,25 @@ namespace Ndk
LuaAPI::RegisterClasses(overlay->lua);
// Override "print" function to add a line in the console
overlay->lua.PushFunction([&consoleRef] (Nz::LuaInstance& instance)
overlay->lua.PushFunction([&consoleRef] (Nz::LuaState& state)
{
Nz::StringStream stream;
unsigned int argCount = instance.GetStackTop();
instance.GetGlobal("tostring");
unsigned int argCount = state.GetStackTop();
state.GetGlobal("tostring");
for (unsigned int i = 1; i <= argCount; ++i)
{
instance.PushValue(-1); // tostring function
instance.PushValue(i); // argument
instance.Call(1, 1);
state.PushValue(-1); // tostring function
state.PushValue(i); // argument
state.Call(1, 1);
std::size_t length;
const char* str = instance.CheckString(-1, &length);
const char* str = state.CheckString(-1, &length);
if (i > 1)
stream << '\t';
stream << Nz::String(str, length);
instance.Pop(1);
state.Pop(1);
}
consoleRef.AddLine(stream);

View File

@ -33,10 +33,10 @@ namespace Ndk
* \param instance Lua instance that will interact with the world
*/
Console::Console(World& world, const Nz::Vector2f& size, Nz::LuaInstance& instance) :
Console::Console(World& world, const Nz::Vector2f& size, Nz::LuaState& state) :
m_historyPosition(0),
m_defaultFont(Nz::Font::GetDefault()),
m_instance(instance),
m_state(state),
m_size(size),
m_opened(false),
m_characterSize(24)
@ -310,8 +310,8 @@ namespace Ndk
AddLineInternal(input); //< With the input prefix
if (!m_instance.Execute(inputCmd))
AddLineInternal(m_instance.GetLastError(), Nz::Color::Red);
if (!m_state.Execute(inputCmd))
AddLineInternal(m_state.GetLastError(), Nz::Color::Red);
RefreshHistory();
}

View File

@ -23,6 +23,7 @@ namespace Ndk
Entity::Entity(Entity&& entity) :
HandledObject(std::move(entity)),
m_components(std::move(entity.m_components)),
m_containedInLists(std::move(entity.m_containedInLists)),
m_componentBits(std::move(entity.m_componentBits)),
m_removedComponentBits(std::move(entity.m_removedComponentBits)),
m_systemBits(std::move(entity.m_systemBits)),
@ -176,9 +177,15 @@ namespace Ndk
m_components.clear();
m_componentBits.Reset();
// And then free every handle
// Free every handle
UnregisterAllHandles();
// Remove from every list
for (EntityList* list : m_containedInLists)
list->NotifyEntityDestruction(this);
m_containedInLists.clear();
m_valid = false;
}

View File

@ -22,7 +22,7 @@ namespace Ndk
utility = LuaBinding_Base::BindUtility(*this);
#ifndef NDK_SERVER
audio = LuaBinding_Base::BindAudio(*this);
audio = LuaBinding_Base::BindAudio(*this);
renderer = LuaBinding_Base::BindRenderer(*this);
graphics = LuaBinding_Base::BindGraphics(*this);
#endif
@ -36,31 +36,31 @@ namespace Ndk
* \param instance Lua instance that will interact with the engine & SDK
*/
void LuaBinding::RegisterClasses(Nz::LuaInstance& instance)
void LuaBinding::RegisterClasses(Nz::LuaState& state)
{
core->Register(instance);
math->Register(instance);
network->Register(instance);
sdk->Register(instance);
utility->Register(instance);
core->Register(state);
math->Register(state);
network->Register(state);
sdk->Register(state);
utility->Register(state);
#ifndef NDK_SERVER
audio->Register(instance);
graphics->Register(instance);
renderer->Register(instance);
audio->Register(state);
graphics->Register(state);
renderer->Register(state);
#endif
// ComponentType (fake enumeration to expose component indexes)
instance.PushTable(0, m_componentBinding.size());
state.PushTable(0, m_componentBinding.size());
{
for (const ComponentBinding& entry : m_componentBinding)
{
if (entry.name.IsEmpty())
continue;
instance.PushField(entry.name, entry.index);
state.PushField(entry.name, entry.index);
}
}
instance.SetGlobal("ComponentType");
state.SetGlobal("ComponentType");
}
}

View File

@ -77,7 +77,7 @@ namespace Ndk
music.BindMethod("Stop", &Nz::Music::Stop);
// Manual
music.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Music& instance, std::size_t /*argumentCount*/) -> int
music.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::Music& instance, std::size_t /*argumentCount*/) -> int
{
Nz::StringStream ss("Music(");
ss << instance.GetFilePath() << ')';
@ -104,7 +104,7 @@ namespace Ndk
sound.BindMethod("SetPlayingOffset", &Nz::Sound::SetPlayingOffset);
// Manual
sound.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Sound& instance, std::size_t /*argumentCount*/) -> int
sound.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::Sound& instance, std::size_t /*argumentCount*/) -> int
{
Nz::StringStream ss("Sound(");
if (const Nz::SoundBuffer* buffer = instance.GetBuffer())
@ -120,7 +120,7 @@ namespace Ndk
/*********************************** Nz::SoundBuffer **********************************/
soundBuffer.Reset("SoundBuffer");
{
soundBuffer.SetConstructor([] (Nz::LuaInstance& lua, Nz::SoundBufferRef* instance, std::size_t argumentCount)
soundBuffer.SetConstructor([] (Nz::LuaState& lua, Nz::SoundBufferRef* instance, std::size_t argumentCount)
{
NazaraUnused(lua);
NazaraUnused(argumentCount);
@ -143,7 +143,7 @@ namespace Ndk
soundBuffer.BindStaticMethod("IsFormatSupported", &Nz::SoundBuffer::IsFormatSupported);
// Manual
soundBuffer.BindMethod("Create", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance, std::size_t /*argumentCount*/) -> int
soundBuffer.BindMethod("Create", [] (Nz::LuaState& lua, Nz::SoundBufferRef& instance, std::size_t /*argumentCount*/) -> int
{
int index = 2;
Nz::AudioFormat format = lua.Check<Nz::AudioFormat>(&index);
@ -158,13 +158,13 @@ namespace Ndk
return 1;
});
soundBuffer.BindMethod("GetSamples", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance, std::size_t /*argumentCount*/) -> int
soundBuffer.BindMethod("GetSamples", [] (Nz::LuaState& lua, Nz::SoundBufferRef& instance, std::size_t /*argumentCount*/) -> int
{
lua.PushString(reinterpret_cast<const char*>(instance->GetSamples()), instance->GetSampleCount() * sizeof(Nz::Int16));
return 1;
});
soundBuffer.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance, std::size_t /*argumentCount*/) -> int
soundBuffer.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::SoundBufferRef& instance, std::size_t /*argumentCount*/) -> int
{
Nz::StringStream ss("SoundBuffer(");
if (instance->IsValid())
@ -188,11 +188,11 @@ namespace Ndk
*
* \param instance Lua instance that will interact with the Audio classes
*/
void LuaBinding_Audio::Register(Nz::LuaInstance& instance)
void LuaBinding_Audio::Register(Nz::LuaState& state)
{
music.Register(instance);
sound.Register(instance);
soundBuffer.Register(instance);
soundEmitter.Register(instance);
music.Register(state);
sound.Register(state);
soundBuffer.Register(state);
soundEmitter.Register(state);
}
}

View File

@ -32,28 +32,28 @@ namespace Ndk
stream.BindMethod("IsWritable", &Nz::Stream::IsWritable);
stream.BindMethod("SetCursorPos", &Nz::Stream::SetCursorPos);
stream.BindMethod("Read", [] (Nz::LuaInstance& lua, Nz::Stream& instance, std::size_t /*argumentCount*/) -> int {
stream.BindMethod("Read", [] (Nz::LuaState& lua, Nz::Stream& stream, std::size_t /*argumentCount*/) -> int {
int argIndex = 2;
std::size_t length = lua.Check<std::size_t>(&argIndex);
std::unique_ptr<char[]> buffer(new char[length]);
std::size_t readLength = instance.Read(buffer.get(), length);
std::size_t readLength = stream.Read(buffer.get(), length);
lua.PushString(Nz::String(buffer.get(), readLength));
return 1;
});
stream.BindMethod("Write", [] (Nz::LuaInstance& lua, Nz::Stream& instance, std::size_t /*argumentCount*/) -> int {
stream.BindMethod("Write", [] (Nz::LuaState& lua, Nz::Stream& stream, std::size_t /*argumentCount*/) -> int {
int argIndex = 2;
std::size_t bufferSize = 0;
const char* buffer = lua.CheckString(argIndex, &bufferSize);
if (instance.IsTextModeEnabled())
lua.Push(instance.Write(Nz::String(buffer, bufferSize)));
if (stream.IsTextModeEnabled())
lua.Push(stream.Write(Nz::String(buffer, bufferSize)));
else
lua.Push(instance.Write(buffer, bufferSize));
lua.Push(stream.Write(buffer, bufferSize));
return 1;
});
}
@ -61,7 +61,7 @@ namespace Ndk
/*********************************** Nz::Clock **********************************/
clock.Reset("Clock");
{
clock.SetConstructor([] (Nz::LuaInstance& lua, Nz::Clock* instance, std::size_t argumentCount)
clock.SetConstructor([] (Nz::LuaState& lua, Nz::Clock* instance, std::size_t argumentCount)
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 2U);
@ -103,11 +103,11 @@ namespace Ndk
clock.BindMethod("Unpause", &Nz::Clock::Unpause);
// Manual
clock.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Clock& instance, std::size_t /*argumentCount*/) -> int {
clock.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::Clock& clock, std::size_t /*argumentCount*/) -> int {
Nz::StringStream ss("Clock(Elapsed: ");
ss << instance.GetSeconds();
ss << clock.GetSeconds();
ss << "s, Paused: ";
ss << instance.IsPaused();
ss << clock.IsPaused();
ss << ')';
lua.PushString(ss);
@ -118,7 +118,7 @@ namespace Ndk
/********************************* Nz::Directory ********************************/
directory.Reset("Directory");
{
directory.SetConstructor([] (Nz::LuaInstance& lua, Nz::Directory* instance, std::size_t argumentCount)
directory.SetConstructor([] (Nz::LuaState& lua, Nz::Directory* instance, std::size_t argumentCount)
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 1U);
@ -159,9 +159,9 @@ namespace Ndk
directory.BindStaticMethod("SetCurrent", Nz::Directory::SetCurrent);
// Manual
directory.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::Directory& instance, std::size_t /*argumentCount*/) -> int {
directory.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::Directory& dir, std::size_t /*argumentCount*/) -> int {
Nz::StringStream ss("Directory(");
ss << instance.GetPath();
ss << dir.GetPath();
ss << ')';
lua.PushString(ss);
@ -174,7 +174,7 @@ namespace Ndk
{
file.Inherit(stream);
file.SetConstructor([] (Nz::LuaInstance& lua, Nz::File* instance, std::size_t argumentCount)
file.SetConstructor([] (Nz::LuaState& lua, Nz::File* instance, std::size_t argumentCount)
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 1U);
@ -237,7 +237,7 @@ namespace Ndk
file.BindStaticMethod("Rename", &Nz::File::Rename);
// Manual
file.BindMethod("Open", [] (Nz::LuaInstance& lua, Nz::File& instance, std::size_t argumentCount) -> int
file.BindMethod("Open", [] (Nz::LuaState& lua, Nz::File& file, std::size_t argumentCount) -> int
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 2U);
@ -246,13 +246,13 @@ namespace Ndk
{
case 0:
case 1:
return lua.Push(instance.Open(lua.Check<Nz::UInt32>(&argIndex, Nz::OpenMode_NotOpen)));
return lua.Push(file.Open(lua.Check<Nz::UInt32>(&argIndex, Nz::OpenMode_NotOpen)));
case 2:
{
Nz::String filePath = lua.Check<Nz::String>(&argIndex);
Nz::UInt32 openMode = lua.Check<Nz::UInt32>(&argIndex, Nz::OpenMode_NotOpen);
return lua.Push(instance.Open(filePath, openMode));
return lua.Push(file.Open(filePath, openMode));
}
}
@ -260,7 +260,7 @@ namespace Ndk
return 0;
});
file.BindMethod("SetCursorPos", [] (Nz::LuaInstance& lua, Nz::File& instance, std::size_t argumentCount) -> int
file.BindMethod("SetCursorPos", [] (Nz::LuaState& lua, Nz::File& file, std::size_t argumentCount) -> int
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 2U);
@ -268,13 +268,13 @@ namespace Ndk
switch (argCount)
{
case 1:
return lua.Push(instance.SetCursorPos(lua.Check<Nz::UInt64>(&argIndex)));
return lua.Push(file.SetCursorPos(lua.Check<Nz::UInt64>(&argIndex)));
case 2:
{
Nz::CursorPosition curPos = lua.Check<Nz::CursorPosition>(&argIndex);
Nz::Int64 offset = lua.Check<Nz::Int64>(&argIndex);
return lua.Push(instance.SetCursorPos(curPos, offset));
return lua.Push(file.SetCursorPos(curPos, offset));
}
}
@ -282,10 +282,10 @@ namespace Ndk
return 0;
});
file.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::File& instance, std::size_t /*argumentCount*/) -> int {
file.BindMethod("__tostring", [] (Nz::LuaState& lua, Nz::File& file, std::size_t /*argumentCount*/) -> int {
Nz::StringStream ss("File(");
if (instance.IsOpen())
ss << "Path: " << instance.GetPath();
if (file.IsOpen())
ss << "Path: " << file.GetPath();
ss << ')';
@ -300,55 +300,55 @@ namespace Ndk
*
* \param instance Lua instance that will interact with the Core classes
*/
void LuaBinding_Core::Register(Nz::LuaInstance& instance)
void LuaBinding_Core::Register(Nz::LuaState& state)
{
// Classes
clock.Register(instance);
directory.Register(instance);
file.Register(instance);
stream.Register(instance);
clock.Register(state);
directory.Register(state);
file.Register(state);
stream.Register(state);
// Enums
// Nz::CursorPosition
static_assert(Nz::CursorPosition_Max + 1 == 3, "Nz::CursorPosition has been updated but change was not reflected to Lua binding");
instance.PushTable(0, 3);
state.PushTable(0, 3);
{
instance.PushField("AtBegin", Nz::CursorPosition_AtBegin);
instance.PushField("AtCurrent", Nz::CursorPosition_AtCurrent);
instance.PushField("AtEnd", Nz::CursorPosition_AtEnd);
state.PushField("AtBegin", Nz::CursorPosition_AtBegin);
state.PushField("AtCurrent", Nz::CursorPosition_AtCurrent);
state.PushField("AtEnd", Nz::CursorPosition_AtEnd);
}
instance.SetGlobal("CursorPosition");
state.SetGlobal("CursorPosition");
// Nz::HashType
static_assert(Nz::HashType_Max + 1 == 9, "Nz::HashType has been updated but change was not reflected to Lua binding");
instance.PushTable(0, 9);
state.PushTable(0, 9);
{
instance.PushField("CRC32", Nz::HashType_CRC32);
instance.PushField("Fletcher16", Nz::HashType_Fletcher16);
instance.PushField("MD5", Nz::HashType_MD5);
instance.PushField("SHA1", Nz::HashType_SHA1);
instance.PushField("SHA224", Nz::HashType_SHA224);
instance.PushField("SHA256", Nz::HashType_SHA256);
instance.PushField("SHA384", Nz::HashType_SHA384);
instance.PushField("SHA512", Nz::HashType_SHA512);
instance.PushField("Whirlpool", Nz::HashType_Whirlpool);
state.PushField("CRC32", Nz::HashType_CRC32);
state.PushField("Fletcher16", Nz::HashType_Fletcher16);
state.PushField("MD5", Nz::HashType_MD5);
state.PushField("SHA1", Nz::HashType_SHA1);
state.PushField("SHA224", Nz::HashType_SHA224);
state.PushField("SHA256", Nz::HashType_SHA256);
state.PushField("SHA384", Nz::HashType_SHA384);
state.PushField("SHA512", Nz::HashType_SHA512);
state.PushField("Whirlpool", Nz::HashType_Whirlpool);
}
instance.SetGlobal("HashType");
state.SetGlobal("HashType");
// Nz::OpenMode
static_assert(Nz::OpenMode_Max + 1 == 8, "Nz::OpenModeFlags has been updated but change was not reflected to Lua binding");
instance.PushTable(0, Nz::OpenMode_Max + 1);
state.PushTable(0, Nz::OpenMode_Max + 1);
{
instance.PushField("Append", Nz::OpenMode_Append);
instance.PushField("NotOpen", Nz::OpenMode_NotOpen);
instance.PushField("Lock", Nz::OpenMode_Lock);
instance.PushField("ReadOnly", Nz::OpenMode_ReadOnly);
instance.PushField("ReadWrite", Nz::OpenMode_ReadWrite);
instance.PushField("Text", Nz::OpenMode_Text);
instance.PushField("Truncate", Nz::OpenMode_Truncate);
instance.PushField("WriteOnly", Nz::OpenMode_WriteOnly);
state.PushField("Append", Nz::OpenMode_Append);
state.PushField("NotOpen", Nz::OpenMode_NotOpen);
state.PushField("Lock", Nz::OpenMode_Lock);
state.PushField("ReadOnly", Nz::OpenMode_ReadOnly);
state.PushField("ReadWrite", Nz::OpenMode_ReadWrite);
state.PushField("Text", Nz::OpenMode_Text);
state.PushField("Truncate", Nz::OpenMode_Truncate);
state.PushField("WriteOnly", Nz::OpenMode_WriteOnly);
}
instance.SetGlobal("OpenMode");
state.SetGlobal("OpenMode");
}
}

View File

@ -71,7 +71,7 @@ namespace Ndk
/*********************************** Nz::Material ***********************************/
material.Reset("Material");
{
material.SetConstructor([] (Nz::LuaInstance& lua, Nz::MaterialRef* instance, std::size_t argumentCount)
material.SetConstructor([] (Nz::LuaState& lua, Nz::MaterialRef* instance, std::size_t argumentCount)
{
switch (argumentCount)
{
@ -104,7 +104,7 @@ namespace Ndk
return false;
});
material.BindMethod("Configure", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
material.BindMethod("Configure", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
if (lua.IsOfType(argIndex, "MaterialPipeline"))
@ -204,7 +204,7 @@ namespace Ndk
material.BindStaticMethod("GetDefault", &Nz::Material::GetDefault);
material.BindMethod("SetAlphaMap", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
material.BindMethod("SetAlphaMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
if (lua.IsOfType(argIndex, "Texture"))
@ -216,7 +216,7 @@ namespace Ndk
return lua.Push(instance->SetAlphaMap(lua.Check<Nz::String>(&argIndex)));
});
material.BindMethod("SetDiffuseMap", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
material.BindMethod("SetDiffuseMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
if (lua.IsOfType(argIndex, "Texture"))
@ -228,7 +228,7 @@ namespace Ndk
return lua.Push(instance->SetDiffuseMap(lua.Check<Nz::String>(&argIndex)));
});
material.BindMethod("SetEmissiveMap", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
material.BindMethod("SetEmissiveMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
if (lua.IsOfType(argIndex, "Texture"))
@ -240,7 +240,7 @@ namespace Ndk
return lua.Push(instance->SetEmissiveMap(lua.Check<Nz::String>(&argIndex)));
});
material.BindMethod("SetHeightMap", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
material.BindMethod("SetHeightMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
if (lua.IsOfType(argIndex, "Texture"))
@ -252,7 +252,7 @@ namespace Ndk
return lua.Push(instance->SetHeightMap(lua.Check<Nz::String>(&argIndex)));
});
material.BindMethod("SetNormalMap", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
material.BindMethod("SetNormalMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
if (lua.IsOfType(argIndex, "Texture"))
@ -264,7 +264,7 @@ namespace Ndk
return lua.Push(instance->SetNormalMap(lua.Check<Nz::String>(&argIndex)));
});
material.BindMethod("SetShader", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
material.BindMethod("SetShader", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
if (lua.IsOfType(argIndex, "UberShader"))
@ -276,7 +276,7 @@ namespace Ndk
return lua.Push(instance->SetShader(lua.Check<Nz::String>(&argIndex)));
});
material.BindMethod("SetSpecularMap", [] (Nz::LuaInstance& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
material.BindMethod("SetSpecularMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
if (lua.IsOfType(argIndex, "Texture"))
@ -297,7 +297,7 @@ namespace Ndk
return reinterpret_cast<Nz::InstancedRenderableRef*>(modelRef); //TODO: Make a ObjectRefCast
});
model.SetConstructor([] (Nz::LuaInstance& /*lua*/, Nz::ModelRef* instance, std::size_t /*argumentCount*/)
model.SetConstructor([] (Nz::LuaState& /*lua*/, Nz::ModelRef* instance, std::size_t /*argumentCount*/)
{
Nz::PlacementNew(instance, Nz::Model::New());
return true;
@ -379,7 +379,7 @@ namespace Ndk
return reinterpret_cast<Nz::InstancedRenderableRef*>(spriteRef); //TODO: Make a ObjectRefCast
});
sprite.SetConstructor([] (Nz::LuaInstance& /*lua*/, Nz::SpriteRef* instance, std::size_t /*argumentCount*/)
sprite.SetConstructor([] (Nz::LuaState& /*lua*/, Nz::SpriteRef* instance, std::size_t /*argumentCount*/)
{
Nz::PlacementNew(instance, Nz::Sprite::New());
return true;
@ -399,7 +399,7 @@ namespace Ndk
sprite.BindMethod("SetTextureCoords", &Nz::Sprite::SetTextureCoords);
sprite.BindMethod("SetTextureRect", &Nz::Sprite::SetTextureRect);
sprite.BindMethod("SetMaterial", [] (Nz::LuaInstance& lua, Nz::SpriteRef& instance, std::size_t /*argumentCount*/) -> int
sprite.BindMethod("SetMaterial", [] (Nz::LuaState& lua, Nz::SpriteRef& instance, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
if (lua.IsOfType(argIndex, "Material"))
@ -428,7 +428,7 @@ namespace Ndk
return 0;
});
sprite.BindMethod("SetTexture", [] (Nz::LuaInstance& lua, Nz::SpriteRef& instance, std::size_t /*argumentCount*/) -> int
sprite.BindMethod("SetTexture", [] (Nz::LuaState& lua, Nz::SpriteRef& instance, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
if (lua.IsOfType(argIndex, "Texture"))
@ -475,13 +475,13 @@ namespace Ndk
* \param instance Lua instance that will interact with the Graphics classes
*/
void LuaBinding_Graphics::Register(Nz::LuaInstance& instance)
void LuaBinding_Graphics::Register(Nz::LuaState& state)
{
abstractViewer.Register(instance);
instancedRenderable.Register(instance);
material.Register(instance);
model.Register(instance);
sprite.Register(instance);
spriteLibrary.Register(instance);
abstractViewer.Register(state);
instancedRenderable.Register(state);
material.Register(state);
model.Register(state);
sprite.Register(state);
spriteLibrary.Register(state);
}
}

View File

@ -18,7 +18,7 @@ namespace Ndk
/*********************************** Nz::EulerAngles **********************************/
eulerAngles.Reset("EulerAngles");
{
eulerAngles.SetConstructor([] (Nz::LuaInstance& lua, Nz::EulerAnglesd* instance, std::size_t argumentCount)
eulerAngles.SetConstructor([] (Nz::LuaState& lua, Nz::EulerAnglesd* instance, std::size_t argumentCount)
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 3U);
@ -46,7 +46,7 @@ namespace Ndk
eulerAngles.BindMethod("__tostring", &Nz::EulerAnglesd::ToString);
eulerAngles.SetGetter([] (Nz::LuaInstance& lua, Nz::EulerAnglesd& instance)
eulerAngles.SetGetter([] (Nz::LuaState& lua, Nz::EulerAnglesd& instance)
{
std::size_t length;
const char* ypr = lua.CheckString(2, &length);
@ -103,7 +103,7 @@ namespace Ndk
return false;
});
eulerAngles.SetSetter([] (Nz::LuaInstance& lua, Nz::EulerAnglesd& instance)
eulerAngles.SetSetter([] (Nz::LuaState& lua, Nz::EulerAnglesd& instance)
{
std::size_t length;
const char* ypr = lua.CheckString(2, &length);
@ -165,7 +165,7 @@ namespace Ndk
/*********************************** Nz::Matrix4 **********************************/
matrix4d.Reset("Matrix4");
{
matrix4d.SetConstructor([] (Nz::LuaInstance& lua, Nz::Matrix4d* matrix, std::size_t argumentCount)
matrix4d.SetConstructor([] (Nz::LuaState& lua, Nz::Matrix4d* matrix, std::size_t argumentCount)
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 3U);
@ -207,7 +207,7 @@ namespace Ndk
matrix4d.BindMethod("GetDeterminant", &Nz::Matrix4d::GetDeterminant);
matrix4d.BindMethod("GetDeterminantAffine", &Nz::Matrix4d::GetDeterminantAffine);
matrix4d.BindMethod("GetInverse", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int
matrix4d.BindMethod("GetInverse", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int
{
Nz::Matrix4d result;
if (instance.GetInverse(&result))
@ -216,7 +216,7 @@ namespace Ndk
return lua.Push(false);
});
matrix4d.BindMethod("GetInverseAffine", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int
matrix4d.BindMethod("GetInverseAffine", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int
{
Nz::Matrix4d result;
if (instance.GetInverseAffine(&result))
@ -232,7 +232,7 @@ namespace Ndk
matrix4d.BindMethod("GetSquaredScale", &Nz::Matrix4d::GetSquaredScale);
matrix4d.BindMethod("GetTranslation", &Nz::Matrix4d::GetTranslation);
matrix4d.BindMethod("GetTransposed", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int
matrix4d.BindMethod("GetTransposed", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int
{
Nz::Matrix4d result;
instance.GetTransposed(&result);
@ -243,7 +243,7 @@ namespace Ndk
matrix4d.BindMethod("HasNegativeScale", &Nz::Matrix4d::HasNegativeScale);
matrix4d.BindMethod("HasScale", &Nz::Matrix4d::HasScale);
matrix4d.BindMethod("Inverse", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int
matrix4d.BindMethod("Inverse", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int
{
bool succeeded;
instance.Inverse(&succeeded);
@ -251,7 +251,7 @@ namespace Ndk
return lua.Push(succeeded);
});
matrix4d.BindMethod("InverseAffine", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int
matrix4d.BindMethod("InverseAffine", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int
{
bool succeeded;
instance.InverseAffine(&succeeded);
@ -273,7 +273,7 @@ namespace Ndk
matrix4d.BindMethod("MakeViewMatrix", &Nz::Matrix4d::MakeViewMatrix);
matrix4d.BindMethod("MakeZero", &Nz::Matrix4d::MakeZero);
matrix4d.BindMethod("Set", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t argumentCount) -> int
matrix4d.BindMethod("Set", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t argumentCount) -> int
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 3U);
@ -305,7 +305,7 @@ namespace Ndk
matrix4d.BindMethod("SetScale", &Nz::Matrix4d::SetScale);
matrix4d.BindMethod("SetTranslation", &Nz::Matrix4d::SetTranslation);
matrix4d.BindMethod("Transform", [] (Nz::LuaInstance& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int
matrix4d.BindMethod("Transform", [] (Nz::LuaState& lua, Nz::Matrix4d& instance, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
if (lua.IsOfType(argIndex, "Vector2"))
@ -345,7 +345,7 @@ namespace Ndk
matrix4d.BindStaticMethod("ViewMatrix", &Nz::Matrix4d::ViewMatrix);
matrix4d.BindStaticMethod("Zero", &Nz::Matrix4d::Zero);
matrix4d.SetGetter([] (Nz::LuaInstance& lua, Nz::Matrix4d& instance)
matrix4d.SetGetter([] (Nz::LuaState& lua, Nz::Matrix4d& instance)
{
bool succeeded = false;
std::size_t index = static_cast<std::size_t>(lua.ToInteger(2, &succeeded));
@ -356,7 +356,7 @@ namespace Ndk
return true;
});
matrix4d.SetSetter([] (Nz::LuaInstance& lua, Nz::Matrix4d& instance)
matrix4d.SetSetter([] (Nz::LuaState& lua, Nz::Matrix4d& instance)
{
bool succeeded = false;
std::size_t index = static_cast<std::size_t>(lua.ToInteger(2, &succeeded));
@ -372,7 +372,7 @@ namespace Ndk
/*********************************** Nz::Rect **********************************/
rect.Reset("Rect");
{
rect.SetConstructor([] (Nz::LuaInstance& lua, Nz::Rectd* instance, std::size_t argumentCount)
rect.SetConstructor([] (Nz::LuaState& lua, Nz::Rectd* instance, std::size_t argumentCount)
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 4U);
@ -422,7 +422,7 @@ namespace Ndk
rect.BindMethod("__tostring", &Nz::Rectd::ToString);
rect.SetGetter([] (Nz::LuaInstance& lua, Nz::Rectd& instance)
rect.SetGetter([] (Nz::LuaState& lua, Nz::Rectd& instance)
{
switch (lua.GetType(2))
{
@ -475,7 +475,7 @@ namespace Ndk
return false;
});
rect.SetSetter([] (Nz::LuaInstance& lua, Nz::Rectd& instance)
rect.SetSetter([] (Nz::LuaState& lua, Nz::Rectd& instance)
{
switch (lua.GetType(2))
{
@ -531,7 +531,7 @@ namespace Ndk
/*********************************** Nz::Quaternion **********************************/
quaternion.Reset("Quaternion");
{
quaternion.SetConstructor([] (Nz::LuaInstance& lua, Nz::Quaterniond* instance, std::size_t argumentCount)
quaternion.SetConstructor([] (Nz::LuaState& lua, Nz::Quaterniond* instance, std::size_t argumentCount)
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 4U);
@ -587,7 +587,7 @@ namespace Ndk
quaternion.BindStaticMethod("RotationBetween", &Nz::Quaterniond::RotationBetween);
quaternion.BindStaticMethod("Slerp", &Nz::Quaterniond::Slerp);
quaternion.BindMethod("GetNormal", [] (Nz::LuaInstance& lua, Nz::Quaterniond& instance, std::size_t /*argumentCount*/) -> int
quaternion.BindMethod("GetNormal", [] (Nz::LuaState& lua, Nz::Quaterniond& instance, std::size_t /*argumentCount*/) -> int
{
double length;
@ -597,7 +597,7 @@ namespace Ndk
return 2;
});
quaternion.BindMethod("Normalize", [] (Nz::LuaInstance& lua, Nz::Quaterniond& instance, std::size_t /*argumentCount*/) -> int
quaternion.BindMethod("Normalize", [] (Nz::LuaState& lua, Nz::Quaterniond& instance, std::size_t /*argumentCount*/) -> int
{
double length;
@ -608,20 +608,20 @@ namespace Ndk
return 2;
});
quaternion.BindStaticMethod("Normalize", [] (Nz::LuaInstance& instance) -> int
quaternion.BindStaticMethod("Normalize", [] (Nz::LuaState& state) -> int
{
int argIndex = 1;
Nz::Quaterniond quat = instance.Check<Nz::Quaterniond>(&argIndex);
Nz::Quaterniond quat = state.Check<Nz::Quaterniond>(&argIndex);
double length;
instance.Push(Nz::Quaterniond::Normalize(quat, &length));
instance.Push(length);
state.Push(Nz::Quaterniond::Normalize(quat, &length));
state.Push(length);
return 2;
});
quaternion.SetGetter([] (Nz::LuaInstance& lua, Nz::Quaterniond& instance)
quaternion.SetGetter([] (Nz::LuaState& lua, Nz::Quaterniond& instance)
{
std::size_t length;
const char* wxyz = lua.CheckString(2, &length);
@ -651,7 +651,7 @@ namespace Ndk
return false;
});
quaternion.SetSetter([] (Nz::LuaInstance& lua, Nz::Quaterniond& instance)
quaternion.SetSetter([] (Nz::LuaState& lua, Nz::Quaterniond& instance)
{
std::size_t length;
const char* wxyz = lua.CheckString(2, &length);
@ -690,7 +690,7 @@ namespace Ndk
/*********************************** Nz::Vector2 **********************************/
vector2d.Reset("Vector2");
{
vector2d.SetConstructor([] (Nz::LuaInstance& lua, Nz::Vector2d* vector, std::size_t argumentCount)
vector2d.SetConstructor([] (Nz::LuaState& lua, Nz::Vector2d* vector, std::size_t argumentCount)
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 2U);
@ -720,7 +720,7 @@ namespace Ndk
vector2d.BindMethod("__tostring", &Nz::Vector2d::ToString);
vector2d.SetGetter([] (Nz::LuaInstance& lua, Nz::Vector2d& instance)
vector2d.SetGetter([] (Nz::LuaState& lua, Nz::Vector2d& instance)
{
switch (lua.GetType(2))
{
@ -765,7 +765,7 @@ namespace Ndk
return false;
});
vector2d.SetSetter([] (Nz::LuaInstance& lua, Nz::Vector2d& instance)
vector2d.SetSetter([] (Nz::LuaState& lua, Nz::Vector2d& instance)
{
switch (lua.GetType(2))
{
@ -816,7 +816,7 @@ namespace Ndk
/*********************************** Nz::Vector3 **********************************/
vector3d.Reset("Vector3");
{
vector3d.SetConstructor([] (Nz::LuaInstance& lua, Nz::Vector3d* vector, std::size_t argumentCount)
vector3d.SetConstructor([] (Nz::LuaState& lua, Nz::Vector3d* vector, std::size_t argumentCount)
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 3U);
@ -860,7 +860,7 @@ namespace Ndk
vector3d.BindMethod("__tostring", &Nz::Vector3d::ToString);
vector3d.SetGetter([] (Nz::LuaInstance& lua, Nz::Vector3d& instance)
vector3d.SetGetter([] (Nz::LuaState& lua, Nz::Vector3d& instance)
{
switch (lua.GetType(2))
{
@ -909,7 +909,7 @@ namespace Ndk
return false;
});
vector3d.SetSetter([] (Nz::LuaInstance& lua, Nz::Vector3d& instance)
vector3d.SetSetter([] (Nz::LuaState& lua, Nz::Vector3d& instance)
{
switch (lua.GetType(2))
{
@ -967,20 +967,20 @@ namespace Ndk
*
* \param instance Lua instance that will interact with the Math classes
*/
void LuaBinding_Math::Register(Nz::LuaInstance& instance)
void LuaBinding_Math::Register(Nz::LuaState& state)
{
eulerAngles.Register(instance);
matrix4d.Register(instance);
quaternion.Register(instance);
rect.Register(instance);
vector2d.Register(instance);
vector3d.Register(instance);
eulerAngles.Register(state);
matrix4d.Register(state);
quaternion.Register(state);
rect.Register(state);
vector2d.Register(state);
vector3d.Register(state);
quaternion.PushGlobalTable(instance);
quaternion.PushGlobalTable(state);
{
instance.PushField("Identity", Nz::Quaterniond::Identity());
instance.PushField("Zero", Nz::Quaterniond::Zero());
state.PushField("Identity", Nz::Quaterniond::Identity());
state.PushField("Zero", Nz::Quaterniond::Zero());
}
instance.Pop();
state.Pop();
}
}

View File

@ -28,11 +28,11 @@ namespace Ndk
/*********************************** Nz::IpAddress **********************************/
ipAddress.Reset("IpAddress");
{
ipAddress.SetConstructor([] (Nz::LuaInstance& lua, Nz::IpAddress* instance, std::size_t argumentCount)
ipAddress.SetConstructor([] (Nz::LuaState& lua, Nz::IpAddress* instance, std::size_t argumentCount)
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 9U);
int argIndex = 2;
int argIndex = 1;
switch (argCount)
{
case 0:
@ -85,63 +85,120 @@ namespace Ndk
ipAddress.BindMethod("ToUInt32", &Nz::IpAddress::ToUInt32);
ipAddress.BindMethod("__tostring", &Nz::IpAddress::ToString);
ipAddress.BindStaticMethod("ResolveAddress", [] (Nz::LuaInstance& instance) -> int
ipAddress.BindStaticMethod("ResolveAddress", [] (Nz::LuaState& state) -> int
{
Nz::String service;
Nz::ResolveError error = Nz::ResolveError_Unknown;
int argIndex = 2;
Nz::String hostName = Nz::IpAddress::ResolveAddress(instance.Check<Nz::IpAddress>(&argIndex), &service, &error);
Nz::String hostName = Nz::IpAddress::ResolveAddress(state.Check<Nz::IpAddress>(&argIndex), &service, &error);
if (error == Nz::ResolveError_NoError)
{
instance.Push(hostName);
instance.Push(service);
state.Push(hostName);
state.Push(service);
return 2;
}
else
{
instance.PushBoolean(false);
instance.Push(error);
state.PushBoolean(false);
state.Push(error);
return 2;
}
});
ipAddress.BindStaticMethod("ResolveHostname", [] (Nz::LuaInstance& instance) -> int
ipAddress.BindStaticMethod("ResolveHostname", [] (Nz::LuaState& state) -> int
{
Nz::ResolveError error = Nz::ResolveError_Unknown;
int argIndex = 2;
Nz::NetProtocol protocol = instance.Check<Nz::NetProtocol>(&argIndex);
Nz::String hostname = instance.Check<Nz::String>(&argIndex);
Nz::String service = instance.Check<Nz::String>(&argIndex, "http");
Nz::NetProtocol protocol = state.Check<Nz::NetProtocol>(&argIndex);
Nz::String hostname = state.Check<Nz::String>(&argIndex);
Nz::String service = state.Check<Nz::String>(&argIndex, "http");
std::vector<Nz::HostnameInfo> addresses = Nz::IpAddress::ResolveHostname(protocol, hostname, service, &error);
if (error == Nz::ResolveError_NoError)
{
int index = 1;
instance.PushTable(addresses.size());
state.PushTable(addresses.size());
for (Nz::HostnameInfo& info : addresses)
{
instance.PushInteger(index++);
instance.PushTable(0, 4);
instance.PushField("Address", std::move(info.address));
instance.PushField("CanonicalName", std::move(info.canonicalName));
instance.PushField("Protocol", std::move(info.protocol));
instance.PushField("SocketType", std::move(info.socketType));
instance.SetTable();
state.PushInteger(index++);
state.PushTable(0, 4);
state.PushField("Address", std::move(info.address));
state.PushField("CanonicalName", std::move(info.canonicalName));
state.PushField("Protocol", std::move(info.protocol));
state.PushField("SocketType", std::move(info.socketType));
state.SetTable();
}
return 1;
}
else
{
instance.PushBoolean(false);
instance.Push(error);
state.PushBoolean(false);
state.Push(error);
return 2;
}
});
}
udpSocket.Reset("UdpSocket");
{
udpSocket.Inherit<Nz::AbstractSocket>(abstractSocket);
udpSocket.BindDefaultConstructor();
udpSocket.BindMethod("Create", &Nz::UdpSocket::Create);
udpSocket.BindMethod("EnableBroadcasting", &Nz::UdpSocket::EnableBroadcasting);
udpSocket.BindMethod("GetBoundAddress", &Nz::UdpSocket::GetBoundAddress);
udpSocket.BindMethod("GetBoundPort", &Nz::UdpSocket::GetBoundPort);
udpSocket.BindMethod("IsBroadcastingEnabled", &Nz::UdpSocket::IsBroadcastingEnabled);
udpSocket.BindMethod("QueryMaxDatagramSize", &Nz::UdpSocket::QueryMaxDatagramSize);
udpSocket.BindMethod("Bind", [](Nz::LuaState& lua, Nz::UdpSocket& socket, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
if (lua.IsOfType(argIndex, "IpAddress"))
return lua.Push(socket.Bind(*static_cast<Nz::IpAddress*>(lua.ToUserdata(argIndex))));
else
return lua.Push(socket.Bind(lua.Check<Nz::UInt16>(&argIndex)));
});
udpSocket.BindMethod("Receive", [](Nz::LuaState& lua, Nz::UdpSocket& socket, std::size_t /*argumentCount*/) -> int
{
Nz::IpAddress from;
std::array<char, 0xFFFF> buffer;
std::size_t received;
if (socket.Receive(buffer.data(), buffer.size(), &from, &received))
{
lua.PushBoolean(true);
lua.PushString(from.ToString());
lua.PushString(buffer.data(), received);
return 3;
}
lua.PushBoolean(false);
return 1;
});
udpSocket.BindMethod("Send", [](Nz::LuaState& lua, Nz::UdpSocket& socket, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
Nz::String to = lua.Check<Nz::String>(&argIndex);
std::size_t bufferLength;
const char* buffer = lua.CheckString(argIndex, &bufferLength);
std::size_t sent;
bool ret;
if ((ret = socket.Send(Nz::IpAddress(to), buffer, bufferLength, &sent)) != true)
sent = 0;
return lua.Push(std::make_pair(ret, sent));
});
}
}
/*!
@ -149,107 +206,108 @@ namespace Ndk
*
* \param instance Lua instance that will interact with the Network classes
*/
void LuaBinding_Network::Register(Nz::LuaInstance& instance)
void LuaBinding_Network::Register(Nz::LuaState& state)
{
// Classes
abstractSocket.Register(instance);
ipAddress.Register(instance);
abstractSocket.Register(state);
ipAddress.Register(state);
udpSocket.Register(state);
// Enums
// Nz::NetProtocol
static_assert(Nz::NetProtocol_Max + 1 == 4, "Nz::NetProtocol has been updated but change was not reflected to Lua binding");
instance.PushTable(0, 4);
state.PushTable(0, 4);
{
instance.PushField("Any", Nz::NetProtocol_Any);
instance.PushField("IPv4", Nz::NetProtocol_IPv4);
instance.PushField("IPv6", Nz::NetProtocol_IPv6);
instance.PushField("Unknown", Nz::NetProtocol_Unknown);
state.PushField("Any", Nz::NetProtocol_Any);
state.PushField("IPv4", Nz::NetProtocol_IPv4);
state.PushField("IPv6", Nz::NetProtocol_IPv6);
state.PushField("Unknown", Nz::NetProtocol_Unknown);
}
instance.SetGlobal("NetProtocol");
state.SetGlobal("NetProtocol");
// Nz::PacketPriority
static_assert(Nz::PacketPriority_Max + 1 == 4, "Nz::PacketPriority has been updated but change was not reflected to Lua binding");
instance.PushTable(0, 6);
state.PushTable(0, 6);
{
instance.PushField("High", Nz::PacketPriority_High);
instance.PushField("Highest", Nz::PacketPriority_Highest);
instance.PushField("Immediate", Nz::PacketPriority_Immediate);
instance.PushField("Medium", Nz::PacketPriority_Medium);
instance.PushField("Low", Nz::PacketPriority_Low);
instance.PushField("Lowest", Nz::PacketPriority_Lowest);
state.PushField("High", Nz::PacketPriority_High);
state.PushField("Highest", Nz::PacketPriority_Highest);
state.PushField("Immediate", Nz::PacketPriority_Immediate);
state.PushField("Medium", Nz::PacketPriority_Medium);
state.PushField("Low", Nz::PacketPriority_Low);
state.PushField("Lowest", Nz::PacketPriority_Lowest);
}
instance.SetGlobal("PacketPriority");
state.SetGlobal("PacketPriority");
// Nz::PacketReliability
static_assert(Nz::PacketReliability_Max + 1 == 3, "Nz::PacketReliability has been updated but change was not reflected to Lua binding");
instance.PushTable(0, 3);
state.PushTable(0, 3);
{
instance.PushField("Reliable", Nz::PacketReliability_Reliable);
instance.PushField("ReliableOrdered", Nz::PacketReliability_ReliableOrdered);
instance.PushField("Unreliable", Nz::PacketReliability_Unreliable);
state.PushField("Reliable", Nz::PacketReliability_Reliable);
state.PushField("ReliableOrdered", Nz::PacketReliability_ReliableOrdered);
state.PushField("Unreliable", Nz::PacketReliability_Unreliable);
}
instance.SetGlobal("PacketReliability");
state.SetGlobal("PacketReliability");
// Nz::ResolveError
static_assert(Nz::ResolveError_Max + 1 == 9, "Nz::ResolveError has been updated but change was not reflected to Lua binding");
instance.PushTable(0, 9);
state.PushTable(0, 9);
{
instance.PushField("Internal", Nz::ResolveError_Internal);
instance.PushField("ResourceError", Nz::ResolveError_ResourceError);
instance.PushField("NoError", Nz::ResolveError_NoError);
instance.PushField("NonRecoverable", Nz::ResolveError_NonRecoverable);
instance.PushField("NotFound", Nz::ResolveError_NotFound);
instance.PushField("NotInitialized", Nz::ResolveError_NotInitialized);
instance.PushField("ProtocolNotSupported", Nz::ResolveError_ProtocolNotSupported);
instance.PushField("TemporaryFailure", Nz::ResolveError_TemporaryFailure);
instance.PushField("Unknown", Nz::ResolveError_Unknown);
state.PushField("Internal", Nz::ResolveError_Internal);
state.PushField("ResourceError", Nz::ResolveError_ResourceError);
state.PushField("NoError", Nz::ResolveError_NoError);
state.PushField("NonRecoverable", Nz::ResolveError_NonRecoverable);
state.PushField("NotFound", Nz::ResolveError_NotFound);
state.PushField("NotInitialized", Nz::ResolveError_NotInitialized);
state.PushField("ProtocolNotSupported", Nz::ResolveError_ProtocolNotSupported);
state.PushField("TemporaryFailure", Nz::ResolveError_TemporaryFailure);
state.PushField("Unknown", Nz::ResolveError_Unknown);
}
instance.SetGlobal("ResolveError");
state.SetGlobal("ResolveError");
// Nz::SocketError
static_assert(Nz::SocketError_Max + 1 == 15, "Nz::ResolveError has been updated but change was not reflected to Lua binding");
instance.PushTable(0, 15);
state.PushTable(0, 15);
{
instance.PushField("AddressNotAvailable", Nz::SocketError_AddressNotAvailable);
instance.PushField("ConnectionClosed", Nz::SocketError_ConnectionClosed);
instance.PushField("ConnectionRefused", Nz::SocketError_ConnectionRefused);
instance.PushField("DatagramSize", Nz::SocketError_DatagramSize);
instance.PushField("Internal", Nz::SocketError_Internal);
instance.PushField("Packet", Nz::SocketError_Packet);
instance.PushField("NetworkError", Nz::SocketError_NetworkError);
instance.PushField("NoError", Nz::SocketError_NoError);
instance.PushField("NotInitialized", Nz::SocketError_NotInitialized);
instance.PushField("NotSupported", Nz::SocketError_NotSupported);
instance.PushField("ResolveError", Nz::SocketError_ResolveError);
instance.PushField("ResourceError", Nz::SocketError_ResourceError);
instance.PushField("TimedOut", Nz::SocketError_TimedOut);
instance.PushField("Unknown", Nz::SocketError_Unknown);
instance.PushField("UnreachableHost", Nz::SocketError_UnreachableHost);
state.PushField("AddressNotAvailable", Nz::SocketError_AddressNotAvailable);
state.PushField("ConnectionClosed", Nz::SocketError_ConnectionClosed);
state.PushField("ConnectionRefused", Nz::SocketError_ConnectionRefused);
state.PushField("DatagramSize", Nz::SocketError_DatagramSize);
state.PushField("Internal", Nz::SocketError_Internal);
state.PushField("Packet", Nz::SocketError_Packet);
state.PushField("NetworkError", Nz::SocketError_NetworkError);
state.PushField("NoError", Nz::SocketError_NoError);
state.PushField("NotInitialized", Nz::SocketError_NotInitialized);
state.PushField("NotSupported", Nz::SocketError_NotSupported);
state.PushField("ResolveError", Nz::SocketError_ResolveError);
state.PushField("ResourceError", Nz::SocketError_ResourceError);
state.PushField("TimedOut", Nz::SocketError_TimedOut);
state.PushField("Unknown", Nz::SocketError_Unknown);
state.PushField("UnreachableHost", Nz::SocketError_UnreachableHost);
}
instance.SetGlobal("SocketError");
state.SetGlobal("SocketError");
// Nz::SocketState
static_assert(Nz::SocketState_Max + 1 == 5, "Nz::SocketState has been updated but change was not reflected to Lua binding");
instance.PushTable(0, 5);
state.PushTable(0, 5);
{
instance.PushField("Bound", Nz::SocketState_Bound);
instance.PushField("Connecting", Nz::SocketState_Connecting);
instance.PushField("Connected", Nz::SocketState_Connected);
instance.PushField("NotConnected", Nz::SocketState_NotConnected);
instance.PushField("Resolving", Nz::SocketState_Resolving);
state.PushField("Bound", Nz::SocketState_Bound);
state.PushField("Connecting", Nz::SocketState_Connecting);
state.PushField("Connected", Nz::SocketState_Connected);
state.PushField("NotConnected", Nz::SocketState_NotConnected);
state.PushField("Resolving", Nz::SocketState_Resolving);
}
instance.SetGlobal("SocketState");
state.SetGlobal("SocketState");
// Nz::SocketType
static_assert(Nz::SocketType_Max + 1 == 4, "Nz::SocketState has been updated but change was not reflected to Lua binding");
instance.PushTable(0, 4);
state.PushTable(0, 4);
{
instance.PushField("Raw", Nz::SocketType_Raw);
instance.PushField("TCP", Nz::SocketType_TCP);
instance.PushField("UDP", Nz::SocketType_UDP);
instance.PushField("Unknown", Nz::SocketType_Unknown);
state.PushField("Raw", Nz::SocketType_Raw);
state.PushField("TCP", Nz::SocketType_TCP);
state.PushField("UDP", Nz::SocketType_UDP);
state.PushField("Unknown", Nz::SocketType_Unknown);
}
instance.SetGlobal("SocketType");
state.SetGlobal("SocketType");
}
}

View File

@ -27,7 +27,7 @@ namespace Ndk
return reinterpret_cast<Nz::AbstractImageRef*>(textureRef); //TODO: Make a ObjectRefCast
});
texture.SetConstructor([] (Nz::LuaInstance& /*lua*/, Nz::TextureRef* instance, std::size_t /*argumentCount*/)
texture.SetConstructor([] (Nz::LuaState& /*lua*/, Nz::TextureRef* instance, std::size_t /*argumentCount*/)
{
Nz::PlacementNew(instance, Nz::Texture::New());
return true;
@ -101,10 +101,10 @@ namespace Ndk
*
* \param instance Lua instance that will interact with the Renderer classes
*/
void LuaBinding_Renderer::Register(Nz::LuaInstance& instance)
void LuaBinding_Renderer::Register(Nz::LuaState& state)
{
texture.Register(instance);
textureLibrary.Register(instance);
textureManager.Register(instance);
texture.Register(state);
textureLibrary.Register(state);
textureManager.Register(state);
}
}

View File

@ -40,7 +40,7 @@ namespace Ndk
application.BindMethod("IsFPSCounterEnabled", &Application::IsFPSCounterEnabled);
#endif
application.BindMethod("AddWorld", [] (Nz::LuaInstance& lua, Application* instance, std::size_t /*argumentCount*/) -> int
application.BindMethod("AddWorld", [] (Nz::LuaState& lua, Application* instance, std::size_t /*argumentCount*/) -> int
{
lua.Push(instance->AddWorld().CreateHandle());
return 1;
@ -94,23 +94,23 @@ namespace Ndk
entity.BindMethod("RemoveAllComponents", &Entity::RemoveAllComponents);
entity.BindMethod("__tostring", &EntityHandle::ToString);
entity.BindMethod("AddComponent", [this] (Nz::LuaInstance& instance, EntityHandle& handle, std::size_t /*argumentCount*/) -> int
entity.BindMethod("AddComponent", [this] (Nz::LuaState& state, EntityHandle& handle, std::size_t /*argumentCount*/) -> int
{
LuaBinding::ComponentBinding* bindingComponent = m_binding.QueryComponentIndex(instance);
LuaBinding::ComponentBinding* bindingComponent = m_binding.QueryComponentIndex(state);
return bindingComponent->adder(instance, handle);
return bindingComponent->adder(state, handle);
});
entity.BindMethod("GetComponent", [this] (Nz::LuaInstance& instance, EntityHandle& handle, std::size_t /*argumentCount*/) -> int
entity.BindMethod("GetComponent", [this] (Nz::LuaState& state, EntityHandle& handle, std::size_t /*argumentCount*/) -> int
{
LuaBinding::ComponentBinding* bindingComponent = m_binding.QueryComponentIndex(instance);
LuaBinding::ComponentBinding* bindingComponent = m_binding.QueryComponentIndex(state);
return bindingComponent->getter(instance, handle->GetComponent(bindingComponent->index));
return bindingComponent->getter(state, handle->GetComponent(bindingComponent->index));
});
entity.BindMethod("RemoveComponent", [this] (Nz::LuaInstance& instance, EntityHandle& handle, std::size_t /*argumentCount*/) -> int
entity.BindMethod("RemoveComponent", [this] (Nz::LuaState& state, EntityHandle& handle, std::size_t /*argumentCount*/) -> int
{
LuaBinding::ComponentBinding* bindingComponent = m_binding.QueryComponentIndex(instance);
LuaBinding::ComponentBinding* bindingComponent = m_binding.QueryComponentIndex(state);
handle->RemoveComponent(bindingComponent->index);
return 0;
@ -129,7 +129,7 @@ namespace Ndk
/*********************************** Ndk::VelocityComponent **********************************/
velocityComponent.Reset("VelocityComponent");
{
velocityComponent.SetGetter([] (Nz::LuaInstance& lua, VelocityComponentHandle& instance)
velocityComponent.SetGetter([] (Nz::LuaState& lua, VelocityComponentHandle& instance)
{
std::size_t length;
const char* member = lua.CheckString(2, &length);
@ -143,7 +143,7 @@ namespace Ndk
return false;
});
velocityComponent.SetSetter([] (Nz::LuaInstance& lua, VelocityComponentHandle& instance)
velocityComponent.SetSetter([] (Nz::LuaState& lua, VelocityComponentHandle& instance)
{
std::size_t length;
const char* member = lua.CheckString(2, &length);
@ -193,7 +193,7 @@ namespace Ndk
/*********************************** Ndk::GraphicsComponent **********************************/
graphicsComponent.Reset("GraphicsComponent");
{
graphicsComponent.BindMethod("Attach", [] (Nz::LuaInstance& lua, Ndk::GraphicsComponent* instance, std::size_t argumentCount) -> int
graphicsComponent.BindMethod("Attach", [] (Nz::LuaState& lua, Ndk::GraphicsComponent* instance, std::size_t argumentCount) -> int
{
/*
void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0);
@ -267,19 +267,19 @@ namespace Ndk
*
* \param instance Lua instance that will interact with the SDK classes
*/
void LuaBinding_SDK::Register(Nz::LuaInstance& instance)
void LuaBinding_SDK::Register(Nz::LuaState& state)
{
// Classes
application.Register(instance);
entity.Register(instance);
nodeComponent.Register(instance);
velocityComponent.Register(instance);
world.Register(instance);
application.Register(state);
entity.Register(state);
nodeComponent.Register(state);
velocityComponent.Register(state);
world.Register(state);
#ifndef NDK_SERVER
cameraComponent.Register(instance);
console.Register(instance);
graphicsComponent.Register(instance);
cameraComponent.Register(state);
console.Register(state);
graphicsComponent.Register(state);
#endif
// Enums
@ -292,23 +292,23 @@ namespace Ndk
* \param instance Lua instance that will interact with the component
* \param argIndex Index of the component
*/
LuaBinding::ComponentBinding* LuaBinding::QueryComponentIndex(Nz::LuaInstance& instance, int argIndex)
LuaBinding::ComponentBinding* LuaBinding::QueryComponentIndex(Nz::LuaState& state, int argIndex)
{
switch (instance.GetType(argIndex))
switch (state.GetType(argIndex))
{
case Nz::LuaType_Number:
{
ComponentIndex componentIndex = instance.Check<ComponentIndex>(&argIndex);
ComponentIndex componentIndex = state.Check<ComponentIndex>(&argIndex);
if (componentIndex > m_componentBinding.size())
{
instance.Error("Invalid component index");
state.Error("Invalid component index");
return nullptr;
}
ComponentBinding& binding = m_componentBinding[componentIndex];
if (binding.name.IsEmpty())
{
instance.Error("Invalid component index");
state.Error("Invalid component index");
return nullptr;
}
@ -317,11 +317,11 @@ namespace Ndk
case Nz::LuaType_String:
{
const char* key = instance.CheckString(argIndex);
const char* key = state.CheckString(argIndex);
auto it = m_componentBindingByName.find(key);
if (it == m_componentBindingByName.end())
{
instance.Error("Invalid component name");
state.Error("Invalid component name");
return nullptr;
}
@ -332,7 +332,7 @@ namespace Ndk
break;
}
instance.Error("Invalid component index at #" + Nz::String::Number(argIndex));
state.Error("Invalid component index at #" + Nz::String::Number(argIndex));
return nullptr;
}
}

View File

@ -29,7 +29,7 @@ namespace Ndk
abstractImage.BindMethod("IsCompressed", &Nz::AbstractImage::IsCompressed);
abstractImage.BindMethod("IsCubemap", &Nz::AbstractImage::IsCubemap);
abstractImage.BindMethod("GetMemoryUsage", [] (Nz::LuaInstance& lua, Nz::AbstractImage* instance, std::size_t argumentCount) -> int
abstractImage.BindMethod("GetMemoryUsage", [] (Nz::LuaState& lua, Nz::AbstractImage* instance, std::size_t argumentCount) -> int
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 1U);
switch (argCount)
@ -50,7 +50,7 @@ namespace Ndk
return 0;
});
abstractImage.BindMethod("Update", [] (Nz::LuaInstance& lua, Nz::AbstractImage* instance, std::size_t argumentCount) -> int
abstractImage.BindMethod("Update", [] (Nz::LuaState& lua, Nz::AbstractImage* instance, std::size_t argumentCount) -> int
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 6U);
int argIndex = 2;
@ -100,7 +100,7 @@ namespace Ndk
/*********************************** Nz::Font **********************************/
font.Reset("Font");
{
font.SetConstructor([] (Nz::LuaInstance& /*lua*/, Nz::FontRef* instance, std::size_t /*argumentCount*/)
font.SetConstructor([] (Nz::LuaState& /*lua*/, Nz::FontRef* instance, std::size_t /*argumentCount*/)
{
Nz::PlacementNew(instance, Nz::Font::New());
return true;
@ -112,7 +112,7 @@ namespace Ndk
font.BindMethod("Destroy", &Nz::Font::Destroy);
font.BindMethod("GetCachedGlyphCount", [] (Nz::LuaInstance& lua, Nz::FontRef& instance, std::size_t argumentCount) -> int
font.BindMethod("GetCachedGlyphCount", [] (Nz::LuaState& lua, Nz::FontRef& instance, std::size_t argumentCount) -> int
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 2U);
@ -216,29 +216,29 @@ namespace Ndk
node.BindMethod("SetPosition", (void(Nz::Node::*)(const Nz::Vector3f&, Nz::CoordSys)) &Nz::Node::SetPosition, Nz::CoordSys_Local);
node.BindMethod("SetRotation", (void(Nz::Node::*)(const Nz::Quaternionf&, Nz::CoordSys)) &Nz::Node::SetRotation, Nz::CoordSys_Local);
node.BindMethod("Move", [] (Nz::LuaInstance& lua, Nz::Node& instance, std::size_t /*argumentCount*/) -> int
node.BindMethod("Move", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
Nz::Vector3f offset = lua.Check<Nz::Vector3f>(&argIndex);
Nz::CoordSys coordSys = lua.Check<Nz::CoordSys>(&argIndex, Nz::CoordSys_Local);
instance.Move(offset, coordSys);
node.Move(offset, coordSys);
return 0;
});
node.BindMethod("Rotate", [] (Nz::LuaInstance& lua, Nz::Node& instance, std::size_t /*argumentCount*/) -> int
node.BindMethod("Rotate", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t /*argumentCount*/) -> int
{
int argIndex = 2;
Nz::Quaternionf rotation = lua.Check<Nz::Quaternionf>(&argIndex);
Nz::CoordSys coordSys = lua.Check<Nz::CoordSys>(&argIndex, Nz::CoordSys_Local);
instance.Rotate(rotation, coordSys);
node.Rotate(rotation, coordSys);
return 0;
});
node.BindMethod("Scale", [] (Nz::LuaInstance& lua, Nz::Node& instance, std::size_t argumentCount) -> int
node.BindMethod("Scale", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t argumentCount) -> int
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 4U);
@ -248,15 +248,15 @@ namespace Ndk
case 1:
{
if (lua.IsOfType(argIndex, Nz::LuaType_Number))
instance.Scale(lua.Check<float>(&argIndex));
node.Scale(lua.Check<float>(&argIndex));
else
instance.Scale(lua.Check<Nz::Vector3f>(&argIndex));
node.Scale(lua.Check<Nz::Vector3f>(&argIndex));
return 0;
}
case 3:
instance.Scale(lua.Check<Nz::Vector3f>(&argIndex));
node.Scale(lua.Check<Nz::Vector3f>(&argIndex));
return 0;
}
@ -264,7 +264,7 @@ namespace Ndk
return 0;
});
node.BindMethod("SetScale", [] (Nz::LuaInstance& lua, Nz::Node& instance, std::size_t argumentCount) -> int
node.BindMethod("SetScale", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t argumentCount) -> int
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 4U);
@ -278,10 +278,10 @@ namespace Ndk
{
float scale = lua.Check<float>(&argIndex);
Nz::CoordSys coordSys = lua.Check<Nz::CoordSys>(&argIndex, Nz::CoordSys_Local);
instance.SetScale(scale, coordSys);
node.SetScale(scale, coordSys);
}
else
instance.SetScale(lua.Check<Nz::Vector3f>(&argIndex));
node.SetScale(lua.Check<Nz::Vector3f>(&argIndex));
return 0;
}
@ -292,7 +292,7 @@ namespace Ndk
Nz::Vector3f scale = lua.Check<Nz::Vector3f>(&argIndex);
Nz::CoordSys coordSys = lua.Check<Nz::CoordSys>(&argIndex, Nz::CoordSys_Local);
instance.SetScale(scale, coordSys);
node.SetScale(scale, coordSys);
return 0;
}
}
@ -301,7 +301,7 @@ namespace Ndk
return 0;
});
node.BindMethod("SetInitialScale", [] (Nz::LuaInstance& lua, Nz::Node& instance, std::size_t argumentCount) -> int
node.BindMethod("SetInitialScale", [] (Nz::LuaState& lua, Nz::Node& node, std::size_t argumentCount) -> int
{
std::size_t argCount = std::min<std::size_t>(argumentCount, 4U);
@ -311,16 +311,16 @@ namespace Ndk
case 1:
{
if (lua.IsOfType(argIndex, Nz::LuaType_Number))
instance.SetInitialScale(lua.Check<float>(&argIndex));
node.SetInitialScale(lua.Check<float>(&argIndex));
else
instance.SetInitialScale(lua.Check<Nz::Vector2f>(&argIndex));
node.SetInitialScale(lua.Check<Nz::Vector2f>(&argIndex));
return 0;
}
case 2:
case 3:
instance.SetInitialScale(lua.Check<Nz::Vector3f>(&argIndex));
node.SetInitialScale(lua.Check<Nz::Vector3f>(&argIndex));
return 0;
}
@ -335,112 +335,110 @@ namespace Ndk
*
* \param instance Lua instance that will interact with the Utility classes
*/
void LuaBinding_Utility::Register(Nz::LuaInstance& instance)
void LuaBinding_Utility::Register(Nz::LuaState& state)
{
abstractImage.Register(instance);
font.Register(instance);
keyboard.Register(instance);
node.Register(instance);
abstractImage.Register(state);
font.Register(state);
keyboard.Register(state);
node.Register(state);
keyboard.PushGlobalTable(instance);
keyboard.PushGlobalTable(state);
{
static_assert(Nz::Keyboard::Count == 121, "Nz::Keyboard::Key has been updated but change was not reflected to Lua binding");
instance.PushField("Undefined", Nz::Keyboard::Undefined);
state.PushField("Undefined", Nz::Keyboard::Undefined);
// A-Z
for (std::size_t i = 0; i < 26; ++i)
instance.PushField(Nz::String('A' + char(i)), Nz::Keyboard::A + i);
state.PushField(Nz::String('A' + char(i)), Nz::Keyboard::A + i);
// Numerical
for (std::size_t i = 0; i < 10; ++i)
{
instance.PushField("Num" + Nz::String::Number(i), Nz::Keyboard::Num0 + i);
instance.PushField("Numpad" + Nz::String::Number(i), Nz::Keyboard::Numpad0 + i);
state.PushField("Num" + Nz::String::Number(i), Nz::Keyboard::Num0 + i);
state.PushField("Numpad" + Nz::String::Number(i), Nz::Keyboard::Numpad0 + i);
}
// F1-F15
for (std::size_t i = 0; i < 15; ++i)
instance.PushField('F' + Nz::String::Number(i+1), Nz::Keyboard::F1 + i);
state.PushField('F' + Nz::String::Number(i+1), Nz::Keyboard::F1 + i);
// And all the others...
instance.PushField("Down", Nz::Keyboard::Down);
instance.PushField("Left", Nz::Keyboard::Left);
instance.PushField("Right", Nz::Keyboard::Right);
instance.PushField("Up", Nz::Keyboard::Up);
state.PushField("Down", Nz::Keyboard::Down);
state.PushField("Left", Nz::Keyboard::Left);
state.PushField("Right", Nz::Keyboard::Right);
state.PushField("Up", Nz::Keyboard::Up);
instance.PushField("Add", Nz::Keyboard::Add);
instance.PushField("Decimal", Nz::Keyboard::Decimal);
instance.PushField("Divide", Nz::Keyboard::Divide);
instance.PushField("Multiply", Nz::Keyboard::Multiply);
instance.PushField("Subtract", Nz::Keyboard::Subtract);
state.PushField("Add", Nz::Keyboard::Add);
state.PushField("Decimal", Nz::Keyboard::Decimal);
state.PushField("Divide", Nz::Keyboard::Divide);
state.PushField("Multiply", Nz::Keyboard::Multiply);
state.PushField("Subtract", Nz::Keyboard::Subtract);
instance.PushField("Backslash", Nz::Keyboard::Backslash);
instance.PushField("Backspace", Nz::Keyboard::Backspace);
instance.PushField("Clear", Nz::Keyboard::Clear);
instance.PushField("Comma", Nz::Keyboard::Comma);
instance.PushField("Dash", Nz::Keyboard::Dash);
instance.PushField("Delete", Nz::Keyboard::Delete);
instance.PushField("End", Nz::Keyboard::End);
instance.PushField("Equal", Nz::Keyboard::Equal);
instance.PushField("Escape", Nz::Keyboard::Escape);
instance.PushField("Home", Nz::Keyboard::Home);
instance.PushField("Insert", Nz::Keyboard::Insert);
instance.PushField("LAlt", Nz::Keyboard::LAlt);
instance.PushField("LBracket", Nz::Keyboard::LBracket);
instance.PushField("LControl", Nz::Keyboard::LControl);
instance.PushField("LShift", Nz::Keyboard::LShift);
instance.PushField("LSystem", Nz::Keyboard::LSystem);
instance.PushField("PageDown", Nz::Keyboard::PageDown);
instance.PushField("PageUp", Nz::Keyboard::PageUp);
instance.PushField("Pause", Nz::Keyboard::Pause);
instance.PushField("Period", Nz::Keyboard::Period);
instance.PushField("Print", Nz::Keyboard::Print);
instance.PushField("PrintScreen", Nz::Keyboard::PrintScreen);
instance.PushField("Quote", Nz::Keyboard::Quote);
instance.PushField("RAlt", Nz::Keyboard::RAlt);
instance.PushField("RBracket", Nz::Keyboard::RBracket);
instance.PushField("RControl", Nz::Keyboard::RControl);
instance.PushField("Return", Nz::Keyboard::Return);
instance.PushField("RShift", Nz::Keyboard::RShift);
instance.PushField("RSystem", Nz::Keyboard::RSystem);
instance.PushField("Semicolon", Nz::Keyboard::Semicolon);
instance.PushField("Slash", Nz::Keyboard::Slash);
instance.PushField("Space", Nz::Keyboard::Space);
instance.PushField("Tab", Nz::Keyboard::Tab);
instance.PushField("Tilde", Nz::Keyboard::Tilde);
instance.PushField("Browser_Back", Nz::Keyboard::Browser_Back);
instance.PushField("Browser_Favorites", Nz::Keyboard::Browser_Favorites);
instance.PushField("Browser_Forward", Nz::Keyboard::Browser_Forward);
instance.PushField("Browser_Home", Nz::Keyboard::Browser_Home);
instance.PushField("Browser_Refresh", Nz::Keyboard::Browser_Refresh);
instance.PushField("Browser_Search", Nz::Keyboard::Browser_Search);
instance.PushField("Browser_Stop", Nz::Keyboard::Browser_Stop);
instance.PushField("Media_Next", Nz::Keyboard::Media_Next);
instance.PushField("Media_Play", Nz::Keyboard::Media_Play);
instance.PushField("Media_Previous", Nz::Keyboard::Media_Previous);
instance.PushField("Media_Stop", Nz::Keyboard::Media_Stop);
instance.PushField("Volume_Down", Nz::Keyboard::Volume_Down);
instance.PushField("Volume_Mute", Nz::Keyboard::Volume_Mute);
instance.PushField("Volume_Up", Nz::Keyboard::Volume_Up);
instance.PushField("CapsLock", Nz::Keyboard::CapsLock);
instance.PushField("NumLock", Nz::Keyboard::NumLock);
instance.PushField("ScrollLock", Nz::Keyboard::ScrollLock);
state.PushField("Backslash", Nz::Keyboard::Backslash);
state.PushField("Backspace", Nz::Keyboard::Backspace);
state.PushField("Clear", Nz::Keyboard::Clear);
state.PushField("Comma", Nz::Keyboard::Comma);
state.PushField("Dash", Nz::Keyboard::Dash);
state.PushField("Delete", Nz::Keyboard::Delete);
state.PushField("End", Nz::Keyboard::End);
state.PushField("Equal", Nz::Keyboard::Equal);
state.PushField("Escape", Nz::Keyboard::Escape);
state.PushField("Home", Nz::Keyboard::Home);
state.PushField("Insert", Nz::Keyboard::Insert);
state.PushField("LAlt", Nz::Keyboard::LAlt);
state.PushField("LBracket", Nz::Keyboard::LBracket);
state.PushField("LControl", Nz::Keyboard::LControl);
state.PushField("LShift", Nz::Keyboard::LShift);
state.PushField("LSystem", Nz::Keyboard::LSystem);
state.PushField("PageDown", Nz::Keyboard::PageDown);
state.PushField("PageUp", Nz::Keyboard::PageUp);
state.PushField("Pause", Nz::Keyboard::Pause);
state.PushField("Period", Nz::Keyboard::Period);
state.PushField("Print", Nz::Keyboard::Print);
state.PushField("PrintScreen", Nz::Keyboard::PrintScreen);
state.PushField("Quote", Nz::Keyboard::Quote);
state.PushField("RAlt", Nz::Keyboard::RAlt);
state.PushField("RBracket", Nz::Keyboard::RBracket);
state.PushField("RControl", Nz::Keyboard::RControl);
state.PushField("Return", Nz::Keyboard::Return);
state.PushField("RShift", Nz::Keyboard::RShift);
state.PushField("RSystem", Nz::Keyboard::RSystem);
state.PushField("Semicolon", Nz::Keyboard::Semicolon);
state.PushField("Slash", Nz::Keyboard::Slash);
state.PushField("Space", Nz::Keyboard::Space);
state.PushField("Tab", Nz::Keyboard::Tab);
state.PushField("Tilde", Nz::Keyboard::Tilde);
state.PushField("Browser_Back", Nz::Keyboard::Browser_Back);
state.PushField("Browser_Favorites", Nz::Keyboard::Browser_Favorites);
state.PushField("Browser_Forward", Nz::Keyboard::Browser_Forward);
state.PushField("Browser_Home", Nz::Keyboard::Browser_Home);
state.PushField("Browser_Refresh", Nz::Keyboard::Browser_Refresh);
state.PushField("Browser_Search", Nz::Keyboard::Browser_Search);
state.PushField("Browser_Stop", Nz::Keyboard::Browser_Stop);
state.PushField("Media_Next", Nz::Keyboard::Media_Next);
state.PushField("Media_Play", Nz::Keyboard::Media_Play);
state.PushField("Media_Previous", Nz::Keyboard::Media_Previous);
state.PushField("Media_Stop", Nz::Keyboard::Media_Stop);
state.PushField("Volume_Down", Nz::Keyboard::Volume_Down);
state.PushField("Volume_Mute", Nz::Keyboard::Volume_Mute);
state.PushField("Volume_Up", Nz::Keyboard::Volume_Up);
state.PushField("CapsLock", Nz::Keyboard::CapsLock);
state.PushField("NumLock", Nz::Keyboard::NumLock);
state.PushField("ScrollLock", Nz::Keyboard::ScrollLock);
}
instance.Pop();
state.Pop();
static_assert(Nz::WindowStyle_Max + 1 == 6, "Nz::WindowStyle has been updated but change was not reflected to Lua binding");
instance.PushTable(0, Nz::WindowStyle_Max + 1);
state.PushTable(0, Nz::WindowStyle_Max + 1);
{
instance.PushField("None", Nz::WindowStyle_None);
instance.PushField("Fullscreen", Nz::WindowStyle_Fullscreen);
instance.PushField("Closable", Nz::WindowStyle_Closable);
instance.PushField("Resizable", Nz::WindowStyle_Resizable);
instance.PushField("Titlebar", Nz::WindowStyle_Titlebar);
instance.PushField("Threaded", Nz::WindowStyle_Threaded);
state.PushField("None", Nz::WindowStyle_None);
state.PushField("Fullscreen", Nz::WindowStyle_Fullscreen);
state.PushField("Closable", Nz::WindowStyle_Closable);
state.PushField("Resizable", Nz::WindowStyle_Resizable);
state.PushField("Titlebar", Nz::WindowStyle_Titlebar);
state.PushField("Threaded", Nz::WindowStyle_Threaded);
}
instance.SetGlobal("WindowStyle");
state.SetGlobal("WindowStyle");
}
}

View File

@ -44,10 +44,10 @@ namespace Ndk
* \param instance Lua instance that will interact with the engine & SDK
*/
void LuaAPI::RegisterClasses(Nz::LuaInstance& instance)
void LuaAPI::RegisterClasses(Nz::LuaState& state)
{
Nz::ErrorFlags errFlags(Nz::ErrorFlag_ThrowException, true);
GetBinding()->RegisterClasses(instance);
GetBinding()->RegisterClasses(state);
}
/*!

View File

@ -58,12 +58,6 @@ namespace Ndk
}
}
m_directionalLights.Remove(entity);
m_drawables.Remove(entity);
m_lights.Remove(entity);
m_particleGroups.Remove(entity);
m_pointSpotLights.Remove(entity);
if (entity->HasComponent<GraphicsComponent>())
{
GraphicsComponent& gfxComponent = entity->GetComponent<GraphicsComponent>();

View File

@ -119,6 +119,7 @@ namespace Ndk
// This is made to avoid that handle warn uselessly entities before their destruction
m_entities.clear();
m_entityBlocks.clear();
m_waitingEntities.clear();
m_aliveEntities.Clear();
m_dirtyEntities.Clear();
@ -152,7 +153,7 @@ namespace Ndk
clone->AddComponent(std::move(component));
}
return GetEntity(clone->GetId());
return clone;
}
/*!

View File

@ -16,6 +16,7 @@
#include <Nazara/Lua.hpp> // Module de scripting
#include <Nazara/Graphics.hpp> // Module graphique
#include <Nazara/Renderer.hpp> // Module de rendu
#include <Nazara/Network.hpp> // Module utilitaire
#include <Nazara/Utility.hpp> // Module utilitaire
#include <NDK/Application.hpp>
#include <NDK/Components.hpp>
@ -33,6 +34,7 @@ int main()
{
// Ndk::Application est une classe s'occupant de l'initialisation du moteur ainsi que de la gestion de beaucoup de choses
Ndk::Application application;
Nz::Initializer<Nz::Network> network;
// Nazara étant initialisé, nous pouvons créer le monde pour contenir notre scène.
// Dans un ECS, le monde représente bien ce que son nom indique, c'est l'ensemble de ce qui existe au niveau de l'application.

View File

@ -49,6 +49,7 @@
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/File.hpp>
#include <Nazara/Core/FileLogger.hpp>
#include <Nazara/Core/Flags.hpp>
#include <Nazara/Core/Functor.hpp>
#include <Nazara/Core/GuillotineBinPack.hpp>
#include <Nazara/Core/HandledObject.hpp>

View File

@ -105,7 +105,7 @@ namespace Nz
{
ParameterType_Boolean,
ParameterType_Color,
ParameterType_Float,
ParameterType_Double,
ParameterType_Integer,
ParameterType_None,
ParameterType_Pointer,

View File

@ -54,12 +54,20 @@ namespace Nz
private:
BitField m_value;
};
// Little hack to have them in both Nz and global scope
namespace DetailFlagOperators
{
template<typename E> constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator~(E lhs);
template<typename E> constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator|(E lhs, E rhs);
template<typename E> constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator&(E lhs, E rhs);
template<typename E> constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator^(E lhs, E rhs);
}
using namespace DetailFlagOperators;
}
template<typename E> constexpr std::enable_if_t<Nz::EnumAsFlags<E>::value, Nz::Flags<E>> operator~(E lhs);
template<typename E> constexpr std::enable_if_t<Nz::EnumAsFlags<E>::value, Nz::Flags<E>> operator|(E lhs, E rhs);
template<typename E> constexpr std::enable_if_t<Nz::EnumAsFlags<E>::value, Nz::Flags<E>> operator&(E lhs, E rhs);
template<typename E> constexpr std::enable_if_t<Nz::EnumAsFlags<E>::value, Nz::Flags<E>> operator^(E lhs, E rhs);
using namespace Nz::DetailFlagOperators;
#include <Nazara/Core/Flags.inl>

View File

@ -209,67 +209,71 @@ namespace Nz
{
return 1U << static_cast<BitField>(enumValue);
}
}
/*!
* \brief Override binary NOT operator on enum to turns into a Flags object.
* \return A Flags object with reversed bits.
*
* \param lhs Enumeration value to reverse.
*
* Returns a Flags object with all state enabled except for the enum one.
*/
template<typename E>
constexpr std::enable_if_t<Nz::EnumAsFlags<E>::value, Nz::Flags<E>> operator~(E lhs)
{
return ~Nz::Flags<E>(lhs);
}
/*!
* \brief Override binary OR operator on enum to turns into a Flags object.
* \return A Flags object with combined enum states.
*
* \param lhs First enumeration value to combine.
* \param rhs Second enumeration value to combine.
*
* Returns a Flags object with combined states from the two enumeration values.
*/
template<typename E>
constexpr std::enable_if_t<Nz::EnumAsFlags<E>::value, Nz::Flags<E>> operator|(E lhs, E rhs)
{
return Nz::Flags<E>(lhs) | rhs;
}
namespace DetailFlagOperators
{
/*!
* \brief Override binary NOT operator on enum to turns into a Flags object.
* \return A Flags object with reversed bits.
*
* \param lhs Enumeration value to reverse.
*
* Returns a Flags object with all state enabled except for the enum one.
*/
template<typename E>
constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator~(E lhs)
{
return ~Flags<E>(lhs);
}
/*!
* \brief Override binary AND operator on enum to turns into a Flags object.
* \return A Flags object with compare enum states.
*
* \param lhs First enumeration value to compare.
* \param rhs Second enumeration value to compare.
*
* Returns a Flags object with compared states from the two enumeration values.
* In this case, only one flag will be enabled if both enumeration values are the same.
*/
template<typename E>
constexpr std::enable_if_t<Nz::EnumAsFlags<E>::value, Nz::Flags<E>> operator&(E lhs, E rhs)
{
return Nz::Flags<E>(lhs) & rhs;
}
/*!
* \brief Override binary OR operator on enum to turns into a Flags object.
* \return A Flags object with combined enum states.
*
* \param lhs First enumeration value to combine.
* \param rhs Second enumeration value to combine.
*
* Returns a Flags object with combined states from the two enumeration values.
*/
template<typename E>
constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator|(E lhs, E rhs)
{
return Flags<E>(lhs) | rhs;
}
/*!
* \brief Override binary XOR operator on enum to turns into a Flags object.
* \return A Flags object with XORed enum states.
*
* \param lhs First enumeration value to compare.
* \param rhs Second enumeration value to compare.
*
* Returns a Flags object with XORed states from the two enumeration values.
* In this case, two flags will be enabled if both the enumeration values are different.
*/
template<typename E>
constexpr std::enable_if_t<Nz::EnumAsFlags<E>::value, Nz::Flags<E>> operator^(E lhs, E rhs)
{
return Nz::Flags<E>(lhs) ^ rhs;
/*!
* \brief Override binary AND operator on enum to turns into a Flags object.
* \return A Flags object with compare enum states.
*
* \param lhs First enumeration value to compare.
* \param rhs Second enumeration value to compare.
*
* Returns a Flags object with compared states from the two enumeration values.
* In this case, only one flag will be enabled if both enumeration values are the same.
*/
template<typename E>
constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator&(E lhs, E rhs)
{
return Flags<E>(lhs) & rhs;
}
/*!
* \brief Override binary XOR operator on enum to turns into a Flags object.
* \return A Flags object with XORed enum states.
*
* \param lhs First enumeration value to compare.
* \param rhs Second enumeration value to compare.
*
* Returns a Flags object with XORed states from the two enumeration values.
* In this case, two flags will be enabled if both the enumeration values are different.
*/
template<typename E>
constexpr std::enable_if_t<EnumAsFlags<E>::value, Flags<E>> operator^(E lhs, E rhs)
{
return Flags<E>(lhs) ^ rhs;
}
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -27,10 +27,13 @@ namespace Nz
void Clear();
inline void ForEach(const std::function<bool(const ParameterList& list, const String& name)>& callback);
inline void ForEach(const std::function<void(const ParameterList& list, const String& name)>& callback) const;
bool GetBooleanParameter(const String& name, bool* value) const;
bool GetColorParameter(const String& name, Color* value) const;
bool GetFloatParameter(const String& name, float* value) const;
bool GetIntegerParameter(const String& name, int* value) const;
bool GetDoubleParameter(const String& name, double* value) const;
bool GetIntegerParameter(const String& name, long long* value) const;
bool GetParameterType(const String& name, ParameterType* type) const;
bool GetPointerParameter(const String& name, void** value) const;
bool GetStringParameter(const String& name, String* value) const;
@ -45,8 +48,8 @@ namespace Nz
void SetParameter(const String& name, const String& value);
void SetParameter(const String& name, const char* value);
void SetParameter(const String& name, bool value);
void SetParameter(const String& name, float value);
void SetParameter(const String& name, int value);
void SetParameter(const String& name, double value);
void SetParameter(const String& name, long long value);
void SetParameter(const String& name, void* value);
void SetParameter(const String& name, void* value, Destructor destructor);
@ -81,8 +84,8 @@ namespace Nz
~Value() {}
bool boolVal;
float floatVal;
int intVal;
double doubleVal;
long long intVal;
void* ptrVal;
Color colorVal;
String stringVal;
@ -102,4 +105,6 @@ namespace Nz
std::ostream& operator<<(std::ostream& out, const Nz::ParameterList& parameterList);
#include <Nazara/Core/ParameterList.inl>
#endif // NAZARA_PARAMETERLIST_HPP

View File

@ -0,0 +1,42 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/ParameterList.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \brief Iterates over every value of the parameter list
*
* \param callback Callback function called with every parameter contained in the list, which can return true to remove the key (or false to keep it)
*
* \remark Changing the ParameterList while iterating on it may cause bugs, but querying data is safe.
*/
inline void ParameterList::ForEach(const std::function<bool(const ParameterList& list, const String& name)>& callback)
{
for (auto it = m_parameters.begin(); it != m_parameters.end();)
{
if (callback(*this, it->first))
it = m_parameters.erase(it);
else
++it;
}
}
/*!
* \brief Iterates over every value of the parameter list
*
* \param callback Callback function called with every parameter contained in the list
*
* \remark Changing the ParameterList while iterating on it may cause bugs, but querying data is safe.
*/
inline void ParameterList::ForEach(const std::function<void(const ParameterList& list, const String& name)>& callback) const
{
for (auto& pair : m_parameters)
callback(*this, pair.first);
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@ -33,6 +33,8 @@
#include <Nazara/Lua/Enums.hpp>
#include <Nazara/Lua/Lua.hpp>
#include <Nazara/Lua/LuaClass.hpp>
#include <Nazara/Lua/LuaCoroutine.hpp>
#include <Nazara/Lua/LuaInstance.hpp>
#include <Nazara/Lua/LuaState.hpp>
#endif // NAZARA_GLOBAL_LUA_HPP

View File

@ -26,13 +26,13 @@ namespace Nz
friend class LuaClass;
public:
using ClassFunc = std::function<int(LuaInstance& lua, T& instance, std::size_t argumentCount)>;
using ClassIndexFunc = std::function<bool(LuaInstance& lua, T& instance)>;
using ConstructorFunc = std::function<bool(LuaInstance& lua, T* instance, std::size_t argumentCount)>;
using ClassFunc = std::function<int(LuaState& state, T& instance, std::size_t argumentCount)>;
using ClassIndexFunc = std::function<bool(LuaState& state, T& instance)>;
using ConstructorFunc = std::function<bool(LuaState& state, T* instance, std::size_t argumentCount)>;
template<typename P> using ConvertToParent = std::function<P*(T*)>;
using FinalizerFunc = std::function<bool(LuaInstance& lua, T& instance)>;
using StaticIndexFunc = std::function<bool(LuaInstance& lua)>;
using StaticFunc = std::function<int(LuaInstance& lua)>;
using FinalizerFunc = std::function<bool(LuaState& state, T& instance)>;
using StaticIndexFunc = std::function<bool(LuaState& state)>;
using StaticFunc = std::function<int(LuaState& state)>;
LuaClass() = default;
LuaClass(const String& name);
@ -54,9 +54,9 @@ namespace Nz
void Reset();
void Reset(const String& name);
void Register(LuaInstance& lua);
void Register(LuaState& state);
void PushGlobalTable(LuaInstance& lua);
void PushGlobalTable(LuaState& state);
void SetConstructor(ConstructorFunc constructor);
void SetFinalizer(FinalizerFunc finalizer);
@ -69,18 +69,18 @@ namespace Nz
template<typename U, bool HasDestructor>
friend struct LuaClassImplFinalizerSetupProxy;
void PushClassInfo(LuaInstance& lua);
void SetupConstructor(LuaInstance& lua);
void SetupDefaultToString(LuaInstance& lua);
void SetupFinalizer(LuaInstance& lua);
void SetupGetter(LuaInstance& lua, LuaCFunction proxy);
void SetupGlobalTable(LuaInstance& lua);
void SetupMetatable(LuaInstance& lua);
void SetupMethod(LuaInstance& lua, LuaCFunction proxy, const String& name, std::size_t methodIndex);
void SetupSetter(LuaInstance& lua, LuaCFunction proxy);
void PushClassInfo(LuaState& state);
void SetupConstructor(LuaState& state);
void SetupDefaultToString(LuaState& state);
void SetupFinalizer(LuaState& state);
void SetupGetter(LuaState& state, LuaCFunction proxy);
void SetupGlobalTable(LuaState& state);
void SetupMetatable(LuaState& state);
void SetupMethod(LuaState& state, LuaCFunction proxy, const String& name, std::size_t methodIndex);
void SetupSetter(LuaState& state, LuaCFunction proxy);
using ParentFunc = std::function<void(LuaInstance& lua, T* instance)>;
using InstanceGetter = std::function<T*(LuaInstance& lua)>;
using ParentFunc = std::function<void(LuaState& state, T* instance)>;
using InstanceGetter = std::function<T*(LuaState& state)>;
struct ClassInfo
{
@ -98,17 +98,17 @@ namespace Nz
int globalTableRef = -1;
};
static int ConstructorProxy(lua_State* state);
static int FinalizerProxy(lua_State* state);
static int InfoDestructor(lua_State* state);
static void Get(const std::shared_ptr<ClassInfo>& info, LuaInstance& lua, T* instance);
static int GetterProxy(lua_State* state);
static int MethodProxy(lua_State* state);
static int SetterProxy(lua_State* state);
static int StaticGetterProxy(lua_State* state);
static int StaticMethodProxy(lua_State* state);
static int StaticSetterProxy(lua_State* state);
static int ToStringProxy(lua_State* state);
static int ConstructorProxy(lua_State* internalState);
static int FinalizerProxy(lua_State* internalState);
static int InfoDestructor(lua_State* internalState);
static void Get(const std::shared_ptr<ClassInfo>& info, LuaState& state, T* instance);
static int GetterProxy(lua_State* internalState);
static int MethodProxy(lua_State* internalState);
static int SetterProxy(lua_State* internalState);
static int StaticGetterProxy(lua_State* internalState);
static int StaticMethodProxy(lua_State* internalState);
static int StaticSetterProxy(lua_State* internalState);
static int ToStringProxy(lua_State* internalState);
std::map<String, ClassFunc> m_methods;
std::map<String, StaticFunc> m_staticMethods;

View File

@ -19,9 +19,9 @@ namespace Nz
template<class T>
inline void LuaClass<T>::BindDefaultConstructor()
{
SetConstructor([] (Nz::LuaInstance& lua, T* instance, std::size_t argumentCount)
SetConstructor([] (Nz::LuaState& state, T* instance, std::size_t argumentCount)
{
NazaraUnused(lua);
NazaraUnused(state);
NazaraUnused(argumentCount);
PlacementNew(instance);
@ -47,14 +47,14 @@ namespace Nz
std::shared_ptr<typename LuaClass<P>::ClassInfo>& parentInfo = parent.m_info;
parentInfo->instanceGetters[m_info->name] = [info = m_info, convertFunc] (LuaInstance& lua) -> P*
parentInfo->instanceGetters[m_info->name] = [info = m_info, convertFunc] (LuaState& state) -> P*
{
return convertFunc(static_cast<T*>(lua.CheckUserdata(1, info->name)));
return convertFunc(static_cast<T*>(state.CheckUserdata(1, info->name)));
};
m_info->parentGetters.emplace_back([parentInfo, convertFunc] (LuaInstance& lua, T* instance)
m_info->parentGetters.emplace_back([parentInfo, convertFunc] (LuaState& state, T* instance)
{
LuaClass<P>::Get(parentInfo, lua, convertFunc(instance));
LuaClass<P>::Get(parentInfo, state, convertFunc(instance));
});
}
@ -71,30 +71,30 @@ namespace Nz
m_info = std::make_shared<ClassInfo>();
m_info->name = name;
m_info->instanceGetters[m_info->name] = [info = m_info] (LuaInstance& instance)
m_info->instanceGetters[m_info->name] = [info = m_info] (LuaState& state)
{
return static_cast<T*>(instance.CheckUserdata(1, info->name));
return static_cast<T*>(state.CheckUserdata(1, info->name));
};
}
template<class T>
void LuaClass<T>::Register(LuaInstance& lua)
void LuaClass<T>::Register(LuaState& state)
{
PushClassInfo(lua);
PushClassInfo(state);
// Let's create the metatable which will be associated with every instance.
SetupMetatable(lua);
// Let's create the metatable which will be associated with every state.
SetupMetatable(state);
if (m_info->constructor || m_info->staticGetter || m_info->staticSetter || !m_staticMethods.empty())
SetupGlobalTable(lua);
SetupGlobalTable(state);
lua.Pop(); // Pop our ClassInfo, which is now referenced by all our functions
state.Pop(); // Pop our ClassInfo, which is now referenced by all our functions
}
template<class T>
void LuaClass<T>::PushGlobalTable(LuaInstance& lua)
void LuaClass<T>::PushGlobalTable(LuaState& state)
{
lua.PushReference(m_info->globalTableRef);
state.PushReference(m_info->globalTableRef);
}
template<class T>
@ -127,11 +127,11 @@ namespace Nz
{
typename LuaImplMethodProxy<Args...>::template Impl<DefArgs...> handler(std::forward<DefArgs>(defArgs)...);
BindMethod(name, [func, handler] (LuaInstance& lua, T& object, std::size_t /*argumentCount*/) -> int
BindMethod(name, [func, handler] (LuaState& state, T& object, std::size_t /*argumentCount*/) -> int
{
handler.ProcessArguments(lua);
handler.ProcessArguments(state);
return handler.Invoke(lua, object, func);
return handler.Invoke(state, object, func);
});
}
@ -141,11 +141,11 @@ namespace Nz
{
typename LuaImplMethodProxy<Args...>::template Impl<DefArgs...> handler(std::forward<DefArgs>(defArgs)...);
BindMethod(name, [func, handler] (LuaInstance& lua, T& object, std::size_t /*argumentCount*/) -> int
BindMethod(name, [func, handler] (LuaState& state, T& object, std::size_t /*argumentCount*/) -> int
{
handler.ProcessArguments(lua);
handler.ProcessArguments(state);
return handler.Invoke(lua, object, func);
return handler.Invoke(state, object, func);
});
}
@ -155,11 +155,11 @@ namespace Nz
{
typename LuaImplMethodProxy<Args...>::template Impl<DefArgs...> handler(std::forward<DefArgs>(defArgs)...);
BindMethod(name, [func, handler] (LuaInstance& lua, T& object, std::size_t /*argumentCount*/) -> int
BindMethod(name, [func, handler] (LuaState& state, T& object, std::size_t /*argumentCount*/) -> int
{
handler.ProcessArguments(lua);
handler.ProcessArguments(state);
return handler.Invoke(lua, object, func);
return handler.Invoke(state, object, func);
});
}
@ -169,11 +169,11 @@ namespace Nz
{
typename LuaImplMethodProxy<Args...>::template Impl<DefArgs...> handler(std::forward<DefArgs>(defArgs)...);
BindMethod(name, [func, handler] (LuaInstance& lua, T& object, std::size_t /*argumentCount*/) -> int
BindMethod(name, [func, handler] (LuaState& state, T& object, std::size_t /*argumentCount*/) -> int
{
handler.ProcessArguments(lua);
handler.ProcessArguments(state);
return handler.Invoke(lua, object, func);
return handler.Invoke(state, object, func);
});
}
@ -201,11 +201,11 @@ namespace Nz
{
typename LuaImplFunctionProxy<Args...>::template Impl<DefArgs...> handler(std::forward<DefArgs>(defArgs)...);
BindStaticMethod(name, [func, handler] (LuaInstance& lua) -> int
BindStaticMethod(name, [func, handler] (LuaState& state) -> int
{
handler.ProcessArguments(lua);
handler.ProcessArguments(state);
return handler.Invoke(lua, func);
return handler.Invoke(state, func);
});
}
@ -216,37 +216,37 @@ namespace Nz
}
template<class T>
void LuaClass<T>::PushClassInfo(LuaInstance& lua)
void LuaClass<T>::PushClassInfo(LuaState& state)
{
// Our ClassInfo has to outlive the LuaClass, because we don't want to force the user to keep the LuaClass alive
// To do that, each Registration creates a tiny shared_ptr wrapper whose life is directly managed by Lua.
// This shared_ptr object gets pushed as a up-value for every proxy function set in the metatable.
// This way, there is no way our ClassInfo gets freed before any instance and the global class gets destroyed.
std::shared_ptr<ClassInfo>* info = static_cast<std::shared_ptr<ClassInfo>*>(lua.PushUserdata(sizeof(std::shared_ptr<ClassInfo>)));
std::shared_ptr<ClassInfo>* info = static_cast<std::shared_ptr<ClassInfo>*>(state.PushUserdata(sizeof(std::shared_ptr<ClassInfo>)));
PlacementNew(info, m_info);
// Setup a tiny metatable to let Lua know how to destroy our ClassInfo
lua.PushTable(0, 1);
lua.PushLightUserdata(info);
lua.PushCFunction(InfoDestructor, 1);
lua.SetField("__gc");
lua.SetMetatable(-2);
state.PushTable(0, 1);
state.PushLightUserdata(info);
state.PushCFunction(InfoDestructor, 1);
state.SetField("__gc");
state.SetMetatable(-2);
}
template<class T>
void LuaClass<T>::SetupConstructor(LuaInstance& lua)
void LuaClass<T>::SetupConstructor(LuaState& state)
{
lua.PushValue(1); // ClassInfo
lua.PushCFunction(ConstructorProxy, 1);
lua.SetField("__call"); // ClassMeta.__call = ConstructorProxy
state.PushValue(1); // ClassInfo
state.PushCFunction(ConstructorProxy, 1);
state.SetField("__call"); // ClassMeta.__call = ConstructorProxy
}
template<class T>
void LuaClass<T>::SetupDefaultToString(LuaInstance& lua)
void LuaClass<T>::SetupDefaultToString(LuaState& state)
{
lua.PushValue(1); // shared_ptr on UserData
lua.PushCFunction(ToStringProxy, 1);
lua.SetField("__tostring");
state.PushValue(1); // shared_ptr on UserData
state.PushCFunction(ToStringProxy, 1);
state.SetField("__tostring");
}
template<typename T, bool HasDestructor>
@ -255,61 +255,61 @@ namespace Nz
template<typename T>
struct LuaClassImplFinalizerSetupProxy<T, true>
{
static void Setup(LuaInstance& lua)
static void Setup(LuaState& state)
{
lua.PushValue(1); // ClassInfo
lua.PushCFunction(LuaClass<T>::FinalizerProxy, 1);
lua.SetField("__gc");
state.PushValue(1); // ClassInfo
state.PushCFunction(LuaClass<T>::FinalizerProxy, 1);
state.SetField("__gc");
}
};
template<typename T>
struct LuaClassImplFinalizerSetupProxy<T, false>
{
static void Setup(LuaInstance&)
static void Setup(LuaState&)
{
}
};
template<class T>
void LuaClass<T>::SetupFinalizer(LuaInstance& lua)
void LuaClass<T>::SetupFinalizer(LuaState& state)
{
LuaClassImplFinalizerSetupProxy<T, std::is_destructible<T>::value>::Setup(lua);
LuaClassImplFinalizerSetupProxy<T, std::is_destructible<T>::value>::Setup(state);
}
template<class T>
void LuaClass<T>::SetupGetter(LuaInstance& lua, LuaCFunction proxy)
void LuaClass<T>::SetupGetter(LuaState& state, LuaCFunction proxy)
{
lua.PushValue(1); // ClassInfo
lua.PushValue(-2); // Metatable
lua.PushCFunction(proxy, 2);
state.PushValue(1); // ClassInfo
state.PushValue(-2); // Metatable
state.PushCFunction(proxy, 2);
lua.SetField("__index"); // Getter
state.SetField("__index"); // Getter
}
template<class T>
void LuaClass<T>::SetupGlobalTable(LuaInstance& lua)
void LuaClass<T>::SetupGlobalTable(LuaState& state)
{
// Create the global table
lua.PushTable(); // Class = {}
state.PushTable(); // Class = {}
// Create a metatable which will be used for our global table
lua.PushTable(); // ClassMeta = {}
state.PushTable(); // ClassMeta = {}
if (m_info->constructor)
SetupConstructor(lua);
SetupConstructor(state);
if (m_info->staticGetter)
SetupGetter(lua, StaticGetterProxy);
SetupGetter(state, StaticGetterProxy);
else
{
// Optimize by assigning the metatable instead of a search function
lua.PushValue(-1); // Metatable
lua.SetField("__index");
state.PushValue(-1); // Metatable
state.SetField("__index");
}
if (m_info->staticSetter)
SetupSetter(lua, StaticSetterProxy);
SetupSetter(state, StaticSetterProxy);
m_info->staticMethods.reserve(m_staticMethods.size());
for (auto& pair : m_staticMethods)
@ -317,41 +317,41 @@ namespace Nz
std::size_t methodIndex = m_info->staticMethods.size();
m_info->staticMethods.push_back(pair.second);
SetupMethod(lua, StaticMethodProxy, pair.first, methodIndex);
SetupMethod(state, StaticMethodProxy, pair.first, methodIndex);
}
lua.SetMetatable(-2); // setmetatable(Class, ClassMeta), pops ClassMeta
state.SetMetatable(-2); // setmetatable(Class, ClassMeta), pops ClassMeta
lua.PushValue(-1); // As CreateReference() pops the table, push a copy
m_info->globalTableRef = lua.CreateReference();
state.PushValue(-1); // As CreateReference() pops the table, push a copy
m_info->globalTableRef = state.CreateReference();
lua.SetGlobal(m_info->name); // _G["Class"] = Class
state.SetGlobal(m_info->name); // _G["Class"] = Class
}
template<class T>
void LuaClass<T>::SetupMetatable(LuaInstance& lua)
void LuaClass<T>::SetupMetatable(LuaState& state)
{
if (!lua.NewMetatable(m_info->name))
if (!state.NewMetatable(m_info->name))
NazaraWarning("Class \"" + m_info->name + "\" already registred in this instance");
{
SetupFinalizer(lua);
SetupFinalizer(state);
if (m_info->getter || !m_info->parentGetters.empty())
SetupGetter(lua, GetterProxy);
SetupGetter(state, GetterProxy);
else
{
// Optimize by assigning the metatable instead of a search function
// This is only possible if we have no custom getter nor parent
lua.PushValue(-1); // Metatable
lua.SetField("__index");
state.PushValue(-1); // Metatable
state.SetField("__index");
}
if (m_info->setter)
SetupSetter(lua, SetterProxy);
SetupSetter(state, SetterProxy);
// In case a __tostring method is missing, add a default implementation returning the class name
if (m_methods.find("__tostring") == m_methods.end())
SetupDefaultToString(lua);
SetupDefaultToString(state);
m_info->methods.reserve(m_methods.size());
for (auto& pair : m_methods)
@ -359,80 +359,80 @@ namespace Nz
std::size_t methodIndex = m_info->methods.size();
m_info->methods.push_back(pair.second);
SetupMethod(lua, MethodProxy, pair.first, methodIndex);
SetupMethod(state, MethodProxy, pair.first, methodIndex);
}
}
lua.Pop(); //< Pops the metatable, it won't be collected before it's referenced by the Lua registry.
state.Pop(); //< Pops the metatable, it won't be collected before it's referenced by the Lua registry.
}
template<class T>
void LuaClass<T>::SetupMethod(LuaInstance& lua, LuaCFunction proxy, const String& name, std::size_t methodIndex)
void LuaClass<T>::SetupMethod(LuaState& state, LuaCFunction proxy, const String& name, std::size_t methodIndex)
{
lua.PushValue(1); // ClassInfo
lua.PushInteger(methodIndex);
lua.PushCFunction(proxy, 2);
state.PushValue(1); // ClassInfo
state.PushInteger(methodIndex);
state.PushCFunction(proxy, 2);
lua.SetField(name); // Method name
state.SetField(name); // Method name
}
template<class T>
void LuaClass<T>::SetupSetter(LuaInstance& lua, LuaCFunction proxy)
void LuaClass<T>::SetupSetter(LuaState& state, LuaCFunction proxy)
{
lua.PushValue(1); // ClassInfo
lua.PushCFunction(proxy, 1);
state.PushValue(1); // ClassInfo
state.PushCFunction(proxy, 1);
lua.SetField("__newindex"); // Setter
state.SetField("__newindex"); // Setter
}
template<class T>
int LuaClass<T>::ConstructorProxy(lua_State* state)
int LuaClass<T>::ConstructorProxy(lua_State* internalState)
{
LuaInstance& lua = *LuaInstance::GetInstance(state);
LuaState state = LuaInstance::GetState(internalState);
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(state.ToUserdata(state.GetIndexOfUpValue(1)));
const ConstructorFunc& constructor = info->constructor;
lua.Remove(1); // On enlève l'argument "table" du stack
state.Remove(1); // On enlève l'argument "table" du stack
std::size_t argCount = lua.GetStackTop();
std::size_t argCount = state.GetStackTop();
T* instance = static_cast<T*>(lua.PushUserdata(sizeof(T)));
T* instance = static_cast<T*>(state.PushUserdata(sizeof(T)));
if (!constructor(lua, instance, argCount))
if (!constructor(state, instance, argCount))
{
lua.Error("Constructor failed");
state.Error("Constructor failed");
return 0; // Normalement jamais exécuté (l'erreur provoquant une exception)
}
lua.SetMetatable(info->name);
state.SetMetatable(info->name);
return 1;
}
template<class T>
int LuaClass<T>::FinalizerProxy(lua_State* state)
int LuaClass<T>::FinalizerProxy(lua_State* internalState)
{
LuaInstance& lua = *LuaInstance::GetInstance(state);
LuaState state = LuaInstance::GetState(internalState);
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(state.ToUserdata(state.GetIndexOfUpValue(1)));
const FinalizerFunc& finalizer = info->finalizer;
T* instance = static_cast<T*>(lua.CheckUserdata(1, info->name));
lua.Remove(1); //< Remove the instance from the Lua stack
T* instance = static_cast<T*>(state.CheckUserdata(1, info->name));
state.Remove(1); //< Remove the instance from the Lua stack
if (!finalizer || finalizer(lua, *instance))
if (!finalizer || finalizer(state, *instance))
instance->~T();
return 0;
}
template<class T>
int LuaClass<T>::InfoDestructor(lua_State* state)
int LuaClass<T>::InfoDestructor(lua_State* internalState)
{
LuaInstance& lua = *LuaInstance::GetInstance(state);
LuaState state = LuaInstance::GetState(internalState);
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
lua.DestroyReference(info->globalTableRef);
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(state.ToUserdata(state.GetIndexOfUpValue(1)));
state.DestroyReference(info->globalTableRef);
using namespace std; // Obligatoire pour le destructeur
info.~shared_ptr(); // Si vous voyez une autre façon de faire, je suis preneur
@ -441,27 +441,27 @@ namespace Nz
}
template<class T>
void LuaClass<T>::Get(const std::shared_ptr<ClassInfo>& info, LuaInstance& lua, T* instance)
void LuaClass<T>::Get(const std::shared_ptr<ClassInfo>& info, LuaState& state, T* instance)
{
const ClassIndexFunc& getter = info->getter;
if (!getter || !getter(lua, *instance))
if (!getter || !getter(state, *instance))
{
// Query from the metatable
lua.GetMetatable(info->name); //< Metatable
lua.PushValue(2); //< Field
lua.GetTable(); // Metatable[Field]
state.GetMetatable(info->name); //< Metatable
state.PushValue(2); //< Field
state.GetTable(); // Metatable[Field]
lua.Remove(-2); // Remove Metatable
state.Remove(-2); // Remove Metatable
if (!lua.IsValid(-1))
if (!state.IsValid(-1))
{
for (const ParentFunc& parentGetter : info->parentGetters)
{
lua.Pop(); //< Pop the last nil value
state.Pop(); //< Pop the last nil value
parentGetter(lua, instance);
if (lua.IsValid(-1))
parentGetter(state, instance);
if (state.IsValid(-1))
return;
}
}
@ -469,131 +469,131 @@ namespace Nz
}
template<class T>
int LuaClass<T>::GetterProxy(lua_State* state)
int LuaClass<T>::GetterProxy(lua_State* internalState)
{
LuaInstance& lua = *LuaInstance::GetInstance(state);
LuaState state = LuaInstance::GetState(internalState);
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(state.ToUserdata(state.GetIndexOfUpValue(1)));
T* instance = static_cast<T*>(lua.CheckUserdata(1, info->name));
T* instance = static_cast<T*>(state.CheckUserdata(1, info->name));
Get(info, lua, instance);
Get(info, state, instance);
return 1;
}
template<class T>
int LuaClass<T>::MethodProxy(lua_State* state)
int LuaClass<T>::MethodProxy(lua_State* internalState)
{
LuaInstance& lua = *LuaInstance::GetInstance(state);
LuaState state = LuaInstance::GetState(internalState);
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(state.ToUserdata(state.GetIndexOfUpValue(1)));
T* instance = nullptr;
if (lua.GetMetatable(1))
if (state.GetMetatable(1))
{
LuaType type = lua.GetField("__name");
LuaType type = state.GetField("__name");
if (type == LuaType_String)
{
String name = lua.ToString(-1);
String name = state.ToString(-1);
auto it = info->instanceGetters.find(name);
if (it != info->instanceGetters.end())
instance = it->second(lua);
instance = it->second(state);
}
lua.Pop(2);
state.Pop(2);
}
if (!instance)
{
lua.Error("Method cannot be called without an object");
state.Error("Method cannot be called without an object");
return 0;
}
std::size_t argCount = lua.GetStackTop() - 1U;
std::size_t argCount = state.GetStackTop() - 1U;
unsigned int index = static_cast<unsigned int>(lua.ToInteger(lua.GetIndexOfUpValue(2)));
unsigned int index = static_cast<unsigned int>(state.ToInteger(state.GetIndexOfUpValue(2)));
const ClassFunc& method = info->methods[index];
return method(lua, *instance, argCount);
return method(state, *instance, argCount);
}
template<class T>
int LuaClass<T>::SetterProxy(lua_State* state)
int LuaClass<T>::SetterProxy(lua_State* internalState)
{
LuaInstance& lua = *LuaInstance::GetInstance(state);
LuaState state = LuaInstance::GetState(internalState);
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(state.ToUserdata(state.GetIndexOfUpValue(1)));
const ClassIndexFunc& setter = info->setter;
T& instance = *static_cast<T*>(lua.CheckUserdata(1, info->name));
T& instance = *static_cast<T*>(state.CheckUserdata(1, info->name));
if (!setter(lua, instance))
if (!setter(state, instance))
{
std::size_t length;
const char* str = lua.ToString(2, &length);
const char* str = state.ToString(2, &length);
lua.Error("Class \"" + info->name + "\" has no field \"" + String(str, length) + "\")");
state.Error("Class \"" + info->name + "\" has no field \"" + String(str, length) + "\")");
}
return 1;
}
template<class T>
int LuaClass<T>::StaticGetterProxy(lua_State* state)
int LuaClass<T>::StaticGetterProxy(lua_State* internalState)
{
LuaInstance& lua = *LuaInstance::GetInstance(state);
LuaState state = LuaInstance::GetState(internalState);
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(state.ToUserdata(state.GetIndexOfUpValue(1)));
const StaticIndexFunc& getter = info->staticGetter;
if (!getter(lua))
if (!getter(state))
{
// On accède alors à la table
lua.PushValue(lua.GetIndexOfUpValue(2));
lua.PushValue(-2);
lua.GetTable();
state.PushValue(state.GetIndexOfUpValue(2));
state.PushValue(-2);
state.GetTable();
}
return 1;
}
template<class T>
int LuaClass<T>::StaticMethodProxy(lua_State* state)
int LuaClass<T>::StaticMethodProxy(lua_State* internalState)
{
LuaInstance& lua = *LuaInstance::GetInstance(state);
LuaState state = LuaInstance::GetState(internalState);
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
unsigned int index = static_cast<unsigned int>(lua.ToInteger(lua.GetIndexOfUpValue(2)));
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(state.ToUserdata(state.GetIndexOfUpValue(1)));
unsigned int index = static_cast<unsigned int>(state.ToInteger(state.GetIndexOfUpValue(2)));
const StaticFunc& method = info->staticMethods[index];
return method(lua);
return method(state);
}
template<class T>
int LuaClass<T>::StaticSetterProxy(lua_State* state)
int LuaClass<T>::StaticSetterProxy(lua_State* internalState)
{
LuaInstance& lua = *LuaInstance::GetInstance(state);
LuaState state = LuaInstance::GetState(internalState);
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(state.ToUserdata(state.GetIndexOfUpValue(1)));
const StaticIndexFunc& setter = info->staticSetter;
if (!setter(lua))
if (!setter(state))
{
std::size_t length;
const char* str = lua.ToString(2, &length);
const char* str = state.ToString(2, &length);
lua.Error("Class \"" + info->name + "\" has no static field \"" + String(str, length) + ')');
state.Error("Class \"" + info->name + "\" has no static field \"" + String(str, length) + ')');
}
return 1;
}
template<class T>
int LuaClass<T>::ToStringProxy(lua_State* state)
int LuaClass<T>::ToStringProxy(lua_State* internalState)
{
LuaInstance& lua = *LuaInstance::GetInstance(state);
LuaState state = LuaInstance::GetState(internalState);
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(lua.ToUserdata(lua.GetIndexOfUpValue(1)));
std::shared_ptr<ClassInfo>& info = *static_cast<std::shared_ptr<ClassInfo>*>(state.ToUserdata(state.GetIndexOfUpValue(1)));
lua.PushString(info->name);
state.PushString(info->name);
return 1;
}
}

View File

@ -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/LuaCoroutine.inl>
#endif // NAZARA_LUACOROUTINE_HPP

View File

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

View File

@ -4,198 +4,51 @@
#pragma once
#ifndef NAZARA_LUASTATE_HPP
#define NAZARA_LUASTATE_HPP
#ifndef NAZARA_LUAINSTANCE_HPP
#define NAZARA_LUAINSTANCE_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Core/Stream.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Lua/Config.hpp>
#include <Nazara/Lua/Enums.hpp>
#include <Nazara/Lua/LuaState.hpp>
#include <cstddef>
#include <functional>
struct lua_Debug;
struct lua_State;
namespace Nz
{
class LuaInstance;
using LuaCFunction = int (*)(lua_State* state);
using LuaFunction = std::function<int(LuaInstance& instance)>;
class NAZARA_LUA_API LuaInstance
class NAZARA_LUA_API LuaInstance : public LuaState
{
friend class LuaCoroutine;
friend class LuaState;
public:
LuaInstance();
LuaInstance(const LuaInstance&) = delete;
LuaInstance(LuaInstance&& instance) noexcept;
LuaInstance(LuaInstance&& instance) = default;
~LuaInstance();
void ArgCheck(bool condition, unsigned int argNum, const char* error) const;
void ArgCheck(bool condition, unsigned int argNum, const String& error) const;
int ArgError(unsigned int argNum, const char* error) const;
int ArgError(unsigned int argNum, const String& error) const;
bool Call(unsigned int argCount);
bool Call(unsigned int argCount, unsigned int resultCount);
template<typename T> T Check(int* index) const;
template<typename T> T Check(int* index, T defValue) const;
void CheckAny(int index) const;
bool CheckBoolean(int index) const;
bool CheckBoolean(int index, bool defValue) const;
template<typename T> T CheckBoundInteger(int index) const;
template<typename T> T CheckBoundInteger(int index, T defValue) const;
template<typename T> T CheckField(const char* fieldName, int tableIndex = -1) const;
template<typename T> T CheckField(const String& fieldName, int tableIndex = -1) const;
template<typename T> T CheckField(const char* fieldName, T defValue, int tableIndex = -1) const;
template<typename T> T CheckField(const String& fieldName, T defValue, int tableIndex = -1) const;
long long CheckInteger(int index) const;
long long CheckInteger(int index, long long defValue) const;
template<typename T> T CheckGlobal(const char* fieldName) const;
template<typename T> T CheckGlobal(const String& fieldName) const;
template<typename T> T CheckGlobal(const char* fieldName, T defValue) const;
template<typename T> T CheckGlobal(const String& fieldName, T 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 String& 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, LuaType type) const;
void* CheckUserdata(int index, const char* tname) const;
void* CheckUserdata(int index, const String& tname) const;
bool Compare(int index1, int index2, LuaComparison comparison) const;
void Compute(LuaOperation operation) const;
void Concatenate(int count) const;
int CreateReference();
void DestroyReference(int ref);
String DumpStack() const;
void Error(const char* message) const;
void Error(const String& message) const;
bool Execute(const String& code);
bool ExecuteFromFile(const String& filePath);
bool ExecuteFromMemory(const void* data, std::size_t size);
bool ExecuteFromStream(Stream& stream);
int GetAbsIndex(int index) const;
LuaType GetField(const char* fieldName, int tableIndex = -1) const;
LuaType GetField(const String& fieldName, int tableIndex = -1) const;
LuaType GetGlobal(const char* name) const;
LuaType GetGlobal(const String& name) const;
inline lua_State* GetInternalState() const;
inline String GetLastError() const;
inline std::size_t GetMemoryLimit() const;
inline std::size_t GetMemoryUsage() const;
LuaType GetMetatable(const char* tname) const;
LuaType GetMetatable(const String& tname) const;
bool GetMetatable(int index) const;
unsigned int GetStackTop() const;
LuaType GetTable(int index = -2) const;
inline UInt32 GetTimeLimit() const;
LuaType GetType(int index) const;
const char* GetTypeName(LuaType type) const;
void Insert(int index) const;
bool IsOfType(int index, LuaType type) const;
bool IsOfType(int index, const char* tname) const;
bool IsOfType(int index, const String& tname) const;
bool IsValid(int index) const;
long long Length(int index) const;
void MoveTo(LuaInstance* instance, int n) const;
bool NewMetatable(const char* str);
bool NewMetatable(const String& str);
bool Next(int index = -2) const;
void Pop(unsigned int n = 1U) const;
template<typename T> int Push(T arg) const;
template<typename T, typename T2, typename... Args> int Push(T firstArg, T2 secondArg, Args... args) const;
void PushBoolean(bool value) const;
void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0) const;
template<typename T> void PushField(const char* name, T&& arg, int tableIndex = -2) const;
template<typename T> void PushField(const String& name, T&& arg, int tableIndex = -2) const;
void PushFunction(LuaFunction func) const;
template<typename R, typename... Args, typename... DefArgs> void PushFunction(R(*func)(Args...), DefArgs&&... defArgs) const;
template<typename T> void PushGlobal(const char* name, T&& arg);
template<typename T> void PushGlobal(const String& name, T&& arg);
template<typename T> void PushInstance(const char* tname, const T& instance) const;
template<typename T> void PushInstance(const char* tname, T&& instance) const;
template<typename T, typename... Args> void PushInstance(const char* tname, Args&&... args) const;
void PushInteger(long long value) const;
void PushLightUserdata(void* value) const;
void PushMetatable(const char* str) const;
void PushMetatable(const String& str) const;
void PushNil() const;
void PushNumber(double value) const;
void PushReference(int ref) const;
void PushString(const char* str) const;
void PushString(const char* str, std::size_t size) const;
void PushString(const String& str) const;
void PushTable(std::size_t sequenceElementCount = 0, std::size_t arrayElementCount = 0) const;
void* PushUserdata(std::size_t size) const;
void PushValue(int index) const;
void Remove(int index) const;
void Replace(int index) const;
void SetField(const char* name, int tableIndex = -2) const;
void SetField(const String& name, int tableIndex = -2) const;
void SetGlobal(const char* name);
void SetGlobal(const String& name);
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 SetTimeLimit(UInt32 timeLimit);
bool ToBoolean(int index) const;
long long ToInteger(int index, bool* succeeded = nullptr) const;
double ToNumber(int index, bool* succeeded = nullptr) const;
const void* ToPointer(int index) const;
const char* ToString(int index, std::size_t* length = nullptr) const;
void* ToUserdata(int index) const;
void* ToUserdata(int index, const char* tname) const;
void* ToUserdata(int index, const String& tname) const;
inline void SetMemoryLimit(std::size_t memoryLimit);
inline void SetTimeLimit(UInt32 limit);
LuaInstance& operator=(const LuaInstance&) = delete;
LuaInstance& operator=(LuaInstance&& instance) noexcept;
static int GetIndexOfUpValue(int upValue);
static LuaInstance* GetInstance(lua_State* state);
LuaInstance& operator=(LuaInstance&& instance) = default;
private:
template<typename T> T CheckBounds(int index, long long value) const;
bool Run(int argCount, int resultCount);
inline void SetMemoryUsage(std::size_t memoryUsage);
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);
static void TimeLimiter(lua_State* internalState, lua_Debug* debug);
std::size_t m_memoryLimit;
std::size_t m_memoryUsage;
UInt32 m_timeLimit;
Clock m_clock;
String m_lastError;
lua_State* m_state;
unsigned int m_level;
};
}
#include <Nazara/Lua/LuaInstance.inl>
#endif // NAZARA_LUASTATE_HPP
#endif // NAZARA_LUAINSTANCE_HPP

View File

@ -3,28 +3,10 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Lua/LuaInstance.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/Flags.hpp>
#include <Nazara/Core/MemoryHelper.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <limits>
#include <string>
#include <vector>
#include <type_traits>
#include <Nazara/Lua/Debug.hpp>
namespace Nz
{
inline lua_State* LuaInstance::GetInternalState() const
{
return m_state;
}
inline String LuaInstance::GetLastError() const
{
return m_lastError;
}
inline std::size_t LuaInstance::GetMemoryLimit() const
{
return m_memoryLimit;
@ -40,758 +22,15 @@ namespace Nz
return m_timeLimit;
}
// Functions args
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, bool* arg, TypeTag<bool>)
inline void LuaInstance::SetMemoryLimit(std::size_t memoryLimit)
{
*arg = instance.CheckBoolean(index);
return 1;
m_memoryLimit = m_memoryLimit;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, bool* arg, bool defValue, TypeTag<bool>)
inline void LuaInstance::SetTimeLimit(UInt32 limit)
{
*arg = instance.CheckBoolean(index, defValue);
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, std::string* arg, TypeTag<std::string>)
{
std::size_t strLength = 0;
const char* str = instance.CheckString(index, &strLength);
arg->assign(str, strLength);
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, String* arg, TypeTag<String>)
{
std::size_t strLength = 0;
const char* str = instance.CheckString(index, &strLength);
arg->Set(str, strLength);
return 1;
}
template<typename T>
std::enable_if_t<std::is_enum<T>::value && !EnumAsFlags<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag<T>)
{
using UnderlyingT = std::underlying_type_t<T>;
return LuaImplQueryArg(instance, index, reinterpret_cast<UnderlyingT*>(arg), TypeTag<UnderlyingT>());
}
template<typename T>
std::enable_if_t<std::is_enum<T>::value && !EnumAsFlags<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag<T>)
{
using UnderlyingT = std::underlying_type_t<T>;
return LuaImplQueryArg(instance, index, reinterpret_cast<UnderlyingT*>(arg), static_cast<UnderlyingT>(defValue), TypeTag<UnderlyingT>());
}
template<typename T>
std::enable_if_t<std::is_enum<T>::value && EnumAsFlags<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag<T>)
{
using UnderlyingT = std::underlying_type_t<T>;
UnderlyingT pot2Val;
unsigned int ret = LuaImplQueryArg(instance, index, &pot2Val, TypeTag<UnderlyingT>());
*arg = static_cast<T>(IntegralLog2Pot(pot2Val));
return ret;
}
template<typename T>
std::enable_if_t<std::is_enum<T>::value && EnumAsFlags<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag<T>)
{
using UnderlyingT = std::underlying_type_t<T>;
UnderlyingT pot2Val;
unsigned int ret = LuaImplQueryArg(instance, index, &pot2Val, 1U << static_cast<UnderlyingT>(defValue), TypeTag<UnderlyingT>());
*arg = static_cast<T>(IntegralLog2Pot(pot2Val));
return ret;
}
template<typename E>
unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Flags<E>* arg, TypeTag<Flags<E>>)
{
*arg = Flags<E>(instance.CheckBoundInteger<UInt32>(index));
return 1;
}
template<typename T>
std::enable_if_t<std::is_floating_point<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag<T>)
{
*arg = static_cast<T>(instance.CheckNumber(index));
return 1;
}
template<typename T>
std::enable_if_t<std::is_floating_point<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag<T>)
{
*arg = static_cast<T>(instance.CheckNumber(index, static_cast<double>(defValue)));
return 1;
}
template<typename T>
std::enable_if_t<std::is_integral<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag<T>)
{
*arg = instance.CheckBoundInteger<T>(index);
return 1;
}
template<typename T>
std::enable_if_t<std::is_integral<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag<T>)
{
*arg = instance.CheckBoundInteger<T>(index, defValue);
return 1;
}
template<typename T>
std::enable_if_t<!std::is_integral<T>::value && !std::is_enum<T>::value && !std::is_floating_point<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag<T> tag)
{
if (instance.IsValid(index))
return LuaImplQueryArg(instance, index, arg, tag);
else
{
*arg = defValue;
return 1;
}
}
template<typename T>
unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag<const T&>)
{
return LuaImplQueryArg(instance, index, arg, TypeTag<T>());
}
template<typename T>
unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag<const T&>)
{
return LuaImplQueryArg(instance, index, arg, defValue, TypeTag<T>());
}
// Function returns
inline int LuaImplReplyVal(const LuaInstance& instance, bool val, TypeTag<bool>)
{
instance.PushBoolean(val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, double val, TypeTag<double>)
{
instance.PushNumber(val);
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, float val, TypeTag<float>)
{
instance.PushNumber(val);
return 1;
}
template<typename T>
std::enable_if_t<std::is_enum<T>::value && !EnumAsFlags<T>::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag<T>)
{
using EnumT = typename std::underlying_type<T>::type;
return LuaImplReplyVal(instance, static_cast<EnumT>(val), TypeTag<EnumT>());
}
template<typename T>
std::enable_if_t<std::is_enum<T>::value && EnumAsFlags<T>::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag<T>)
{
Flags<T> flags(val);
return LuaImplReplyVal(instance, flags, TypeTag<decltype(flags)>());
}
template<typename E>
int LuaImplReplyVal(const LuaInstance& instance, Flags<E> val, TypeTag<Flags<E>>)
{
instance.PushInteger(UInt32(val));
return 1;
}
template<typename T>
std::enable_if_t<std::is_integral<T>::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag<T>)
{
instance.PushInteger(val);
return 1;
}
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value || std::is_enum<T>::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag<T&>)
{
return LuaImplReplyVal(instance, val, TypeTag<T>());
}
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value || std::is_enum<T>::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag<const T&>)
{
return LuaImplReplyVal(instance, val, TypeTag<T>());
}
template<typename T>
std::enable_if_t<!std::is_arithmetic<T>::value && !std::is_enum<T>::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag<T&>)
{
return LuaImplReplyVal(instance, std::move(val), TypeTag<T>());
}
template<typename T>
std::enable_if_t<!std::is_arithmetic<T>::value && !std::is_enum<T>::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag<const T&>)
{
return LuaImplReplyVal(instance, std::move(val), TypeTag<T>());
}
template<typename T>
int LuaImplReplyVal(const LuaInstance& instance, T&& val, TypeTag<T&&>)
{
return LuaImplReplyVal(instance, std::forward<T>(val), TypeTag<T>());
}
inline int LuaImplReplyVal(const LuaInstance& instance, std::string&& val, TypeTag<std::string>)
{
instance.PushString(val.c_str(), val.size());
return 1;
}
template<typename T>
inline int LuaImplReplyVal(const LuaInstance& instance, std::vector<T>&& valContainer, TypeTag<std::vector<T>>)
{
std::size_t index = 1;
instance.PushTable(valContainer.size());
for (T& val : valContainer)
{
instance.PushInteger(index++);
if (LuaImplReplyVal(instance, std::move(val), TypeTag<T>()) != 1)
{
instance.Error("Couldn't create table: type need more than one place to store");
return 0;
}
instance.SetTable();
}
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, ByteArray&& val, TypeTag<ByteArray>)
{
instance.PushString(reinterpret_cast<const char*>(val.GetConstBuffer()), val.GetSize());
return 1;
}
inline int LuaImplReplyVal(const LuaInstance& instance, String&& val, TypeTag<String>)
{
instance.PushString(std::move(val));
return 1;
}
template<typename T1, typename T2>
int LuaImplReplyVal(const LuaInstance& instance, std::pair<T1, T2>&& val, TypeTag<std::pair<T1, T2>>)
{
int retVal = 0;
retVal += LuaImplReplyVal(instance, std::move(val.first), TypeTag<T1>());
retVal += LuaImplReplyVal(instance, std::move(val.second), TypeTag<T2>());
return retVal;
}
template<bool HasDefault>
struct LuaImplArgProcesser;
template<>
struct LuaImplArgProcesser<true>
{
template<std::size_t N, std::size_t FirstDefArg, typename ArgType, typename ArgContainer, typename DefArgContainer>
static unsigned int Process(const LuaInstance& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs)
{
return LuaImplQueryArg(instance, argIndex, &std::get<N>(args), std::get<FirstDefArg + std::tuple_size<DefArgContainer>() - N - 1>(defArgs), TypeTag<ArgType>());
}
};
template<>
struct LuaImplArgProcesser<false>
{
template<std::size_t N, std::size_t FirstDefArg, typename ArgType, typename ArgContainer, typename DefArgContainer>
static unsigned int Process(const LuaInstance& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs)
{
NazaraUnused(defArgs);
return LuaImplQueryArg(instance, argIndex, &std::get<N>(args), TypeTag<ArgType>());
}
};
template<typename... Args>
class LuaImplFunctionProxy
{
public:
template<typename... DefArgs>
class Impl
{
static constexpr std::size_t ArgCount = sizeof...(Args);
static constexpr std::size_t DefArgCount = sizeof...(DefArgs);
static_assert(ArgCount >= DefArgCount, "There cannot be more default arguments than argument");
static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount;
public:
Impl(DefArgs... defArgs) :
m_defaultArgs(std::forward<DefArgs>(defArgs)...)
{
}
void ProcessArguments(const LuaInstance& instance) const
{
m_index = 1;
ProcessArgs<0, Args...>(instance);
}
int Invoke(const LuaInstance& instance, void(*func)(Args...)) const
{
NazaraUnused(instance);
Apply(func, m_args);
return 0;
}
template<typename Ret>
int Invoke(const LuaInstance& instance, Ret(*func)(Args...)) const
{
return LuaImplReplyVal(instance, std::move(Apply(func, m_args)), TypeTag<decltype(Apply(func, m_args))>());
}
private:
using ArgContainer = std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...>;
using DefArgContainer = std::tuple<std::remove_cv_t<std::remove_reference_t<DefArgs>>...>;
template<std::size_t N>
void ProcessArgs(const LuaInstance& instance) const
{
NazaraUnused(instance);
// No argument to process
}
template<std::size_t N, typename ArgType>
void ProcessArgs(const LuaInstance& instance) const
{
LuaImplArgProcesser<(N >= FirstDefArg)>::template Process<N, FirstDefArg, ArgType>(instance, m_index, m_args, m_defaultArgs);
}
template<std::size_t N, typename ArgType1, typename ArgType2, typename... Rest>
void ProcessArgs(const LuaInstance& instance) const
{
ProcessArgs<N, ArgType1>(instance);
ProcessArgs<N + 1, ArgType2, Rest...>(instance);
}
mutable ArgContainer m_args;
DefArgContainer m_defaultArgs;
mutable unsigned int m_index;
};
};
template<typename... Args>
class LuaImplMethodProxy
{
public:
template<typename... DefArgs>
class Impl
{
static constexpr std::size_t ArgCount = sizeof...(Args);
static constexpr std::size_t DefArgCount = sizeof...(DefArgs);
static_assert(ArgCount >= DefArgCount, "There cannot be more default arguments than argument");
static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount;
public:
Impl(DefArgs... defArgs) :
m_defaultArgs(std::forward<DefArgs>(defArgs)...)
{
}
void ProcessArguments(const LuaInstance& instance) const
{
m_index = 2; //< 1 being the instance
ProcessArgs<0, Args...>(instance);
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, T>::value, int> Invoke(const LuaInstance& instance, T& object, void(P::*func)(Args...)) const
{
NazaraUnused(instance);
Apply(object, func, m_args);
return 0;
}
template<typename T, typename P, typename Ret>
std::enable_if_t<std::is_base_of<P, T>::value, int> Invoke(const LuaInstance& instance, T& object, Ret(P::*func)(Args...)) const
{
return LuaImplReplyVal(instance, std::move(Apply(object, func, m_args)), TypeTag<decltype(Apply(object, func, m_args))>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, T>::value, int> Invoke(const LuaInstance& instance, T& object, T&(P::*func)(Args...)) const
{
T& r = Apply(object, func, m_args);
if (&r == &object)
{
instance.PushValue(1); //< Userdata
return 1;
}
else
return LuaImplReplyVal(instance, r, TypeTag<T&>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, T>::value, int> Invoke(const LuaInstance& instance, const T& object, void(P::*func)(Args...) const) const
{
NazaraUnused(instance);
Apply(object, func, m_args);
return 0;
}
template<typename T, typename P, typename Ret>
std::enable_if_t<std::is_base_of<P, T>::value, int> Invoke(const LuaInstance& instance, const T& object, Ret(P::*func)(Args...) const) const
{
return LuaImplReplyVal(instance, std::move(Apply(object, func, m_args)), TypeTag<decltype(Apply(object, func, m_args))>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, T>::value, int> Invoke(const LuaInstance& instance, const T& object, const T&(P::*func)(Args...) const) const
{
const T& r = Apply(object, func, m_args);
if (&r == &object)
{
instance.PushValue(1); //< Userdata
return 1;
}
else
return LuaImplReplyVal(instance, r, TypeTag<T&>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, typename PointedType<T>::type>::value, int> Invoke(const LuaInstance& instance, T& object, void(P::*func)(Args...)) const
{
if (!object)
{
instance.Error("Invalid object");
return 0;
}
Apply(*object, func, m_args);
return 0;
}
template<typename T, typename P, typename Ret>
std::enable_if_t<std::is_base_of<P, typename PointedType<T>::type>::value, int> Invoke(const LuaInstance& instance, T& object, Ret(P::*func)(Args...)) const
{
if (!object)
{
instance.Error("Invalid object");
return 0;
}
return LuaImplReplyVal(instance, std::move(Apply(*object, func, m_args)), TypeTag<decltype(Apply(*object, func, m_args))>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, typename PointedType<T>::type>::value, int> Invoke(const LuaInstance& instance, T& object, typename PointedType<T>::type&(P::*func)(Args...) const) const
{
if (!object)
{
instance.Error("Invalid object");
return 0;
}
const typename PointedType<T>::type& r = Apply(*object, func, m_args);
if (&r == &*object)
{
instance.PushValue(1); //< Userdata
return 1;
}
else
return LuaImplReplyVal(instance, r, TypeTag<T&>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, typename PointedType<T>::type>::value, int> Invoke(const LuaInstance& instance, const T& object, void(P::*func)(Args...) const) const
{
if (!object)
{
instance.Error("Invalid object");
return 0;
}
Apply(*object, func, m_args);
return 0;
}
template<typename T, typename P, typename Ret>
std::enable_if_t<std::is_base_of<P, typename PointedType<T>::type>::value, int> Invoke(const LuaInstance& instance, const T& object, Ret(P::*func)(Args...) const) const
{
if (!object)
{
instance.Error("Invalid object");
return 0;
}
return LuaImplReplyVal(instance, std::move(Apply(*object, func, m_args)), TypeTag<decltype(Apply(*object, func, m_args))>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, typename PointedType<T>::type>::value, int> Invoke(const LuaInstance& instance, const T& object, const typename PointedType<T>::type&(P::*func)(Args...) const) const
{
if (!object)
{
instance.Error("Invalid object");
return 0;
}
const typename PointedType<T>::type& r = Apply(*object, func, m_args);
if (&r == &*object)
{
instance.PushValue(1); //< Userdata
return 1;
}
else
return LuaImplReplyVal(instance, r, TypeTag<T&>());
}
private:
using ArgContainer = std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...>;
using DefArgContainer = std::tuple<std::remove_cv_t<std::remove_reference_t<DefArgs>>...>;
template<std::size_t N>
void ProcessArgs(const LuaInstance& instance) const
{
NazaraUnused(instance);
// No argument to process
}
template<std::size_t N, typename ArgType>
void ProcessArgs(const LuaInstance& instance) const
{
m_index += LuaImplArgProcesser<(N >= FirstDefArg)>::template Process<N, FirstDefArg, ArgType>(instance, m_index, m_args, m_defaultArgs);
}
template<std::size_t N, typename ArgType1, typename ArgType2, typename... Rest>
void ProcessArgs(const LuaInstance& instance) const
{
ProcessArgs<N, ArgType1>(instance);
ProcessArgs<N + 1, ArgType2, Rest...>(instance);
}
mutable ArgContainer m_args;
DefArgContainer m_defaultArgs;
mutable unsigned int m_index;
};
};
template<typename T>
T LuaInstance::Check(int* index) const
{
NazaraAssert(index, "Invalid index pointer");
T object;
*index += LuaImplQueryArg(*this, *index, &object, TypeTag<T>());
return object;
}
template<typename T>
T LuaInstance::Check(int* index, T defValue) const
{
NazaraAssert(index, "Invalid index pointer");
T object;
*index += LuaImplQueryArg(*this, *index, &object, defValue, TypeTag<T>());
return object;
}
template<typename T>
inline T LuaInstance::CheckBoundInteger(int index) const
{
return CheckBounds<T>(index, CheckInteger(index));
}
template<typename T>
inline T LuaInstance::CheckBoundInteger(int index, T defValue) const
{
return CheckBounds<T>(index, CheckInteger(index, defValue));
}
template<typename T>
T LuaInstance::CheckField(const char* fieldName, int tableIndex) const
{
T object;
GetField(fieldName, tableIndex);
tableIndex += LuaImplQueryArg(*this, -1, &object, TypeTag<T>());
Pop();
return object;
}
template<typename T>
T LuaInstance::CheckField(const String& fieldName, int tableIndex) const
{
return CheckField<T>(fieldName.GetConstBuffer(), tableIndex);
}
template<typename T>
T LuaInstance::CheckField(const char* fieldName, T defValue, int tableIndex) const
{
T object;
GetField(fieldName, tableIndex);
tableIndex += LuaImplQueryArg(*this, -1, &object, defValue, TypeTag<T>());
Pop();
return object;
}
template<typename T>
T LuaInstance::CheckField(const String& fieldName, T defValue, int tableIndex) const
{
return CheckField<T>(fieldName.GetConstBuffer(), defValue, tableIndex);
}
template<typename T>
T LuaInstance::CheckGlobal(const char* fieldName) const
{
T object;
GetGlobal(fieldName);
LuaImplQueryArg(*this, -1, &object, TypeTag<T>());
Pop();
return object;
}
template<typename T>
T LuaInstance::CheckGlobal(const String& fieldName) const
{
return CheckGlobal<T>(fieldName.GetConstBuffer());
}
template<typename T>
T LuaInstance::CheckGlobal(const char* fieldName, T defValue) const
{
T object;
GetGlobal(fieldName);
LuaImplQueryArg(*this, -1, &object, defValue, TypeTag<T>());
Pop();
return object;
}
template<typename T>
T LuaInstance::CheckGlobal(const String& fieldName, T defValue) const
{
return CheckGlobal<T>(fieldName.GetConstBuffer(), defValue);
}
template<typename T>
int LuaInstance::Push(T arg) const
{
return LuaImplReplyVal(*this, std::move(arg), TypeTag<T>());
}
template<typename T, typename T2, typename... Args>
int LuaInstance::Push(T firstArg, T2 secondArg, Args... args) const
{
int valCount = 0;
valCount += Push(std::move(firstArg));
valCount += Push(secondArg, std::forward<Args>(args)...);
return valCount;
}
template<typename T>
void LuaInstance::PushField(const char* name, T&& arg, int tableIndex) const
{
Push<T>(std::forward<T>(arg));
SetField(name, tableIndex);
}
template<typename T>
void LuaInstance::PushField(const String& name, T&& arg, int tableIndex) const
{
PushField(name.GetConstBuffer(), std::forward<T>(arg), tableIndex);
}
template<typename R, typename... Args, typename... DefArgs>
void LuaInstance::PushFunction(R(*func)(Args...), DefArgs&&... defArgs) const
{
typename LuaImplFunctionProxy<Args...>::template Impl<DefArgs...> handler(std::forward<DefArgs>(defArgs)...);
PushFunction([func, handler] (LuaInstance& lua) -> int
{
handler.ProcessArguments(lua);
return handler.Invoke(lua, func);
});
}
template<typename T>
void LuaInstance::PushGlobal(const char* name, T&& arg)
{
Push<T>(std::forward<T>(arg));
SetGlobal(name);
}
template<typename T>
void LuaInstance::PushGlobal(const String& name, T&& arg)
{
PushGlobal(name.GetConstBuffer(), std::forward<T>(arg));
}
template<typename T>
void LuaInstance::PushInstance(const char* tname, const T& instance) const
{
T* userdata = static_cast<T*>(PushUserdata(sizeof(T)));
PlacementNew(userdata, instance);
SetMetatable(tname);
}
template<typename T>
void LuaInstance::PushInstance(const char* tname, T&& instance) const
{
T* userdata = static_cast<T*>(PushUserdata(sizeof(T)));
PlacementNew(userdata, std::move(instance));
SetMetatable(tname);
}
template<typename T, typename... Args>
void LuaInstance::PushInstance(const char* tname, Args&&... args) const
{
T* userdata = static_cast<T*>(PushUserdata(sizeof(T)));
PlacementNew(userdata, std::forward<Args>(args)...);
SetMetatable(tname);
}
template<typename T>
T LuaInstance::CheckBounds(int index, long long value) const
{
constexpr long long minBounds = std::numeric_limits<T>::min();
constexpr long long maxBounds = std::numeric_limits<T>::max();
if (value < minBounds || value > maxBounds)
{
Nz::StringStream stream;
stream << "Argument #" << index << " is outside value range [" << minBounds << ", " << maxBounds << "] (" << value << ')';
Error(stream);
}
return static_cast<T>(value);
m_timeLimit = limit;
}
}
#include <Nazara/Lua/DebugOff.hpp>

View File

@ -0,0 +1,197 @@
// 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_LUASTATE_HPP
#define NAZARA_LUASTATE_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Core/Stream.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Lua/Config.hpp>
#include <Nazara/Lua/Enums.hpp>
#include <cstddef>
#include <functional>
struct lua_Debug;
struct lua_State;
namespace Nz
{
class LuaCoroutine;
class LuaInstance;
class LuaState;
using LuaCFunction = int (*)(lua_State* internalState);
using LuaFunction = std::function<int(LuaState& state)>;
class NAZARA_LUA_API LuaState
{
public:
LuaState(const LuaState&) = default;
LuaState(LuaState&& instance) noexcept;
~LuaState() = default;
void ArgCheck(bool condition, unsigned int argNum, const char* error) const;
void ArgCheck(bool condition, unsigned int argNum, const String& error) const;
int ArgError(unsigned int argNum, const char* error) const;
int ArgError(unsigned int argNum, const String& error) const;
bool Call(unsigned int argCount);
bool Call(unsigned int argCount, unsigned int resultCount);
template<typename T> T Check(int* index) const;
template<typename T> T Check(int* index, T defValue) const;
void CheckAny(int index) const;
bool CheckBoolean(int index) const;
bool CheckBoolean(int index, bool defValue) const;
template<typename T> T CheckBoundInteger(int index) const;
template<typename T> T CheckBoundInteger(int index, T defValue) const;
template<typename T> T CheckField(const char* fieldName, int tableIndex = -1) const;
template<typename T> T CheckField(const String& fieldName, int tableIndex = -1) const;
template<typename T> T CheckField(const char* fieldName, T defValue, int tableIndex = -1) const;
template<typename T> T CheckField(const String& fieldName, T defValue, int tableIndex = -1) const;
long long CheckInteger(int index) const;
long long CheckInteger(int index, long long defValue) const;
template<typename T> T CheckGlobal(const char* fieldName) const;
template<typename T> T CheckGlobal(const String& fieldName) const;
template<typename T> T CheckGlobal(const char* fieldName, T defValue) const;
template<typename T> T CheckGlobal(const String& fieldName, T 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 String& 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, LuaType type) const;
void* CheckUserdata(int index, const char* tname) const;
void* CheckUserdata(int index, const String& tname) const;
bool Compare(int index1, int index2, LuaComparison comparison) const;
void Compute(LuaOperation operation) const;
void Concatenate(int count) const;
int CreateReference();
void DestroyReference(int ref);
String DumpStack() const;
void Error(const char* message) const;
void Error(const String& message) const;
bool Execute(const String& code);
bool ExecuteFromFile(const String& filePath);
bool ExecuteFromMemory(const void* data, std::size_t size);
bool ExecuteFromStream(Stream& stream);
int GetAbsIndex(int index) const;
LuaType GetField(const char* fieldName, int tableIndex = -1) const;
LuaType GetField(const String& fieldName, int tableIndex = -1) const;
LuaType GetGlobal(const char* name) const;
LuaType GetGlobal(const String& name) const;
inline lua_State* GetInternalState() const;
inline String GetLastError() const;
LuaType GetMetatable(const char* tname) const;
LuaType GetMetatable(const String& tname) const;
bool GetMetatable(int index) const;
unsigned int GetStackTop() const;
LuaType GetTable(int index = -2) const;
LuaType GetTableRaw(int index = -2) const;
LuaType GetType(int index) const;
const char* GetTypeName(LuaType type) const;
void Insert(int index) const;
bool IsOfType(int index, LuaType type) const;
bool IsOfType(int index, const char* tname) const;
bool IsOfType(int index, const String& tname) const;
bool IsValid(int index) const;
long long Length(int index) const;
std::size_t LengthRaw(int index) const;
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;
void Pop(unsigned int n = 1U) const;
template<typename T> int Push(T arg) const;
template<typename T, typename T2, typename... Args> int Push(T firstArg, T2 secondArg, Args... args) const;
void PushBoolean(bool value) const;
void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0) const;
template<typename T> void PushField(const char* name, T&& arg, int tableIndex = -2) const;
template<typename T> void PushField(const String& name, T&& arg, int tableIndex = -2) const;
void PushFunction(LuaFunction func) const;
template<typename R, typename... Args, typename... DefArgs> void PushFunction(R(*func)(Args...), DefArgs&&... defArgs) const;
template<typename T> void PushGlobal(const char* name, T&& arg);
template<typename T> void PushGlobal(const String& name, T&& arg);
template<typename T> void PushInstance(const char* tname, const T& instance) const;
template<typename T> void PushInstance(const char* tname, T&& instance) const;
template<typename T, typename... Args> void PushInstance(const char* tname, Args&&... args) const;
void PushInteger(long long value) const;
void PushLightUserdata(void* value) const;
void PushMetatable(const char* str) const;
void PushMetatable(const String& str) const;
void PushNil() const;
void PushNumber(double value) const;
void PushReference(int ref) const;
void PushString(const char* str) const;
void PushString(const char* str, std::size_t size) const;
void PushString(const String& str) const;
void PushTable(std::size_t sequenceElementCount = 0, std::size_t arrayElementCount = 0) const;
void* PushUserdata(std::size_t size) const;
void PushValue(int index) const;
void Remove(int index) const;
void Replace(int index) const;
void SetField(const char* name, int tableIndex = -2) const;
void SetField(const String& name, int tableIndex = -2) const;
void SetGlobal(const char* name);
void SetGlobal(const String& name);
void SetMetatable(const char* tname) const;
void SetMetatable(const String& tname) const;
void SetMetatable(int index) const;
void SetTable(int index = -3) const;
void SetTableRaw(int index = -3) const;
bool ToBoolean(int index) const;
long long ToInteger(int index, bool* succeeded = nullptr) const;
double ToNumber(int index, bool* succeeded = nullptr) const;
const void* ToPointer(int index) const;
const char* ToString(int index, std::size_t* length = nullptr) const;
void* ToUserdata(int index) const;
void* ToUserdata(int index, const char* tname) const;
void* ToUserdata(int index, const String& tname) const;
LuaState& operator=(const LuaState&) = default;
LuaState& operator=(LuaState&& instance) noexcept;
static int GetIndexOfUpValue(int upValue);
static LuaInstance& GetInstance(lua_State* internalState);
static inline LuaState GetState(lua_State* internalState);
protected:
LuaState(lua_State* internalState);
template<typename T> T CheckBounds(int index, long long value) const;
virtual bool Run(int argCount, int resultCount);
static int ProxyFunc(lua_State* internalState);
String m_lastError;
lua_State* m_state;
};
}
#include <Nazara/Lua/LuaState.inl>
#endif // NAZARA_LUASTATE_HPP

View File

@ -0,0 +1,792 @@
// 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/LuaState.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/Flags.hpp>
#include <Nazara/Core/MemoryHelper.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <limits>
#include <string>
#include <vector>
#include <type_traits>
namespace Nz
{
inline LuaState::LuaState(lua_State* internalState) :
m_state(internalState)
{
}
inline lua_State* LuaState::GetInternalState() const
{
return m_state;
}
inline String LuaState::GetLastError() const
{
return m_lastError;
}
// Functions args
inline unsigned int LuaImplQueryArg(const LuaState& instance, int index, bool* arg, TypeTag<bool>)
{
*arg = instance.CheckBoolean(index);
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaState& instance, int index, bool* arg, bool defValue, TypeTag<bool>)
{
*arg = instance.CheckBoolean(index, defValue);
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaState& instance, int index, std::string* arg, TypeTag<std::string>)
{
std::size_t strLength = 0;
const char* str = instance.CheckString(index, &strLength);
arg->assign(str, strLength);
return 1;
}
inline unsigned int LuaImplQueryArg(const LuaState& instance, int index, String* arg, TypeTag<String>)
{
std::size_t strLength = 0;
const char* str = instance.CheckString(index, &strLength);
arg->Set(str, strLength);
return 1;
}
template<typename T>
std::enable_if_t<std::is_enum<T>::value && !EnumAsFlags<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag<T>)
{
using UnderlyingT = std::underlying_type_t<T>;
return LuaImplQueryArg(instance, index, reinterpret_cast<UnderlyingT*>(arg), TypeTag<UnderlyingT>());
}
template<typename T>
std::enable_if_t<std::is_enum<T>::value && !EnumAsFlags<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag<T>)
{
using UnderlyingT = std::underlying_type_t<T>;
return LuaImplQueryArg(instance, index, reinterpret_cast<UnderlyingT*>(arg), static_cast<UnderlyingT>(defValue), TypeTag<UnderlyingT>());
}
template<typename T>
std::enable_if_t<std::is_enum<T>::value && EnumAsFlags<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag<T>)
{
using UnderlyingT = std::underlying_type_t<T>;
UnderlyingT pot2Val;
unsigned int ret = LuaImplQueryArg(instance, index, &pot2Val, TypeTag<UnderlyingT>());
*arg = static_cast<T>(IntegralLog2Pot(pot2Val));
return ret;
}
template<typename T>
std::enable_if_t<std::is_enum<T>::value && EnumAsFlags<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag<T>)
{
using UnderlyingT = std::underlying_type_t<T>;
UnderlyingT pot2Val;
unsigned int ret = LuaImplQueryArg(instance, index, &pot2Val, 1U << static_cast<UnderlyingT>(defValue), TypeTag<UnderlyingT>());
*arg = static_cast<T>(IntegralLog2Pot(pot2Val));
return ret;
}
template<typename E>
unsigned int LuaImplQueryArg(const LuaState& instance, int index, Flags<E>* arg, TypeTag<Flags<E>>)
{
*arg = Flags<E>(instance.CheckBoundInteger<UInt32>(index));
return 1;
}
template<typename T>
std::enable_if_t<std::is_floating_point<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag<T>)
{
*arg = static_cast<T>(instance.CheckNumber(index));
return 1;
}
template<typename T>
std::enable_if_t<std::is_floating_point<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag<T>)
{
*arg = static_cast<T>(instance.CheckNumber(index, static_cast<double>(defValue)));
return 1;
}
template<typename T>
std::enable_if_t<std::is_integral<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag<T>)
{
*arg = instance.CheckBoundInteger<T>(index);
return 1;
}
template<typename T>
std::enable_if_t<std::is_integral<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, T defValue, TypeTag<T>)
{
*arg = instance.CheckBoundInteger<T>(index, defValue);
return 1;
}
template<typename T>
std::enable_if_t<!std::is_integral<T>::value && !std::is_enum<T>::value && !std::is_floating_point<T>::value, unsigned int> LuaImplQueryArg(const LuaState& instance, int index, T* arg, const T& defValue, TypeTag<T> tag)
{
if (instance.IsValid(index))
return LuaImplQueryArg(instance, index, arg, tag);
else
{
*arg = defValue;
return 1;
}
}
template<typename T>
unsigned int LuaImplQueryArg(const LuaState& instance, int index, T* arg, TypeTag<const T&>)
{
return LuaImplQueryArg(instance, index, arg, TypeTag<T>());
}
template<typename T>
unsigned int LuaImplQueryArg(const LuaState& instance, int index, T* arg, const T& defValue, TypeTag<const T&>)
{
return LuaImplQueryArg(instance, index, arg, defValue, TypeTag<T>());
}
// Function returns
inline int LuaImplReplyVal(const LuaState& instance, bool val, TypeTag<bool>)
{
instance.PushBoolean(val);
return 1;
}
inline int LuaImplReplyVal(const LuaState& instance, double val, TypeTag<double>)
{
instance.PushNumber(val);
return 1;
}
inline int LuaImplReplyVal(const LuaState& instance, float val, TypeTag<float>)
{
instance.PushNumber(val);
return 1;
}
template<typename T>
std::enable_if_t<std::is_enum<T>::value && !EnumAsFlags<T>::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag<T>)
{
using EnumT = typename std::underlying_type<T>::type;
return LuaImplReplyVal(instance, static_cast<EnumT>(val), TypeTag<EnumT>());
}
template<typename T>
std::enable_if_t<std::is_enum<T>::value && EnumAsFlags<T>::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag<T>)
{
Flags<T> flags(val);
return LuaImplReplyVal(instance, flags, TypeTag<decltype(flags)>());
}
template<typename E>
int LuaImplReplyVal(const LuaState& instance, Flags<E> val, TypeTag<Flags<E>>)
{
instance.PushInteger(UInt32(val));
return 1;
}
template<typename T>
std::enable_if_t<std::is_integral<T>::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag<T>)
{
instance.PushInteger(val);
return 1;
}
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value || std::is_enum<T>::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag<T&>)
{
return LuaImplReplyVal(instance, val, TypeTag<T>());
}
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value || std::is_enum<T>::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag<const T&>)
{
return LuaImplReplyVal(instance, val, TypeTag<T>());
}
template<typename T>
std::enable_if_t<!std::is_arithmetic<T>::value && !std::is_enum<T>::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag<T&>)
{
return LuaImplReplyVal(instance, std::move(val), TypeTag<T>());
}
template<typename T>
std::enable_if_t<!std::is_arithmetic<T>::value && !std::is_enum<T>::value, int> LuaImplReplyVal(const LuaState& instance, T val, TypeTag<const T&>)
{
return LuaImplReplyVal(instance, std::move(val), TypeTag<T>());
}
template<typename T>
int LuaImplReplyVal(const LuaState& instance, T&& val, TypeTag<T&&>)
{
return LuaImplReplyVal(instance, std::forward<T>(val), TypeTag<T>());
}
inline int LuaImplReplyVal(const LuaState& instance, std::string&& val, TypeTag<std::string>)
{
instance.PushString(val.c_str(), val.size());
return 1;
}
template<typename T>
inline int LuaImplReplyVal(const LuaState& instance, std::vector<T>&& valContainer, TypeTag<std::vector<T>>)
{
std::size_t index = 1;
instance.PushTable(valContainer.size());
for (T& val : valContainer)
{
instance.PushInteger(index++);
if (LuaImplReplyVal(instance, std::move(val), TypeTag<T>()) != 1)
{
instance.Error("Couldn't create table: type need more than one place to store");
return 0;
}
instance.SetTable();
}
return 1;
}
inline int LuaImplReplyVal(const LuaState& instance, ByteArray&& val, TypeTag<ByteArray>)
{
instance.PushString(reinterpret_cast<const char*>(val.GetConstBuffer()), val.GetSize());
return 1;
}
inline int LuaImplReplyVal(const LuaState& instance, String&& val, TypeTag<String>)
{
instance.PushString(std::move(val));
return 1;
}
template<typename T1, typename T2>
int LuaImplReplyVal(const LuaState& instance, std::pair<T1, T2>&& val, TypeTag<std::pair<T1, T2>>)
{
int retVal = 0;
retVal += LuaImplReplyVal(instance, std::move(val.first), TypeTag<T1>());
retVal += LuaImplReplyVal(instance, std::move(val.second), TypeTag<T2>());
return retVal;
}
template<bool HasDefault>
struct LuaImplArgProcesser;
template<>
struct LuaImplArgProcesser<true>
{
template<std::size_t N, std::size_t FirstDefArg, typename ArgType, typename ArgContainer, typename DefArgContainer>
static unsigned int Process(const LuaState& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs)
{
return LuaImplQueryArg(instance, argIndex, &std::get<N>(args), std::get<FirstDefArg + std::tuple_size<DefArgContainer>() - N - 1>(defArgs), TypeTag<ArgType>());
}
};
template<>
struct LuaImplArgProcesser<false>
{
template<std::size_t N, std::size_t FirstDefArg, typename ArgType, typename ArgContainer, typename DefArgContainer>
static unsigned int Process(const LuaState& instance, unsigned int argIndex, ArgContainer& args, DefArgContainer& defArgs)
{
NazaraUnused(defArgs);
return LuaImplQueryArg(instance, argIndex, &std::get<N>(args), TypeTag<ArgType>());
}
};
template<typename... Args>
class LuaImplFunctionProxy
{
public:
template<typename... DefArgs>
class Impl
{
static constexpr std::size_t ArgCount = sizeof...(Args);
static constexpr std::size_t DefArgCount = sizeof...(DefArgs);
static_assert(ArgCount >= DefArgCount, "There cannot be more default arguments than argument");
static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount;
public:
Impl(DefArgs... defArgs) :
m_defaultArgs(std::forward<DefArgs>(defArgs)...)
{
}
void ProcessArguments(const LuaState& instance) const
{
m_index = 1;
ProcessArgs<0, Args...>(instance);
}
int Invoke(const LuaState& instance, void(*func)(Args...)) const
{
NazaraUnused(instance);
Apply(func, m_args);
return 0;
}
template<typename Ret>
int Invoke(const LuaState& instance, Ret(*func)(Args...)) const
{
return LuaImplReplyVal(instance, std::move(Apply(func, m_args)), TypeTag<decltype(Apply(func, m_args))>());
}
private:
using ArgContainer = std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...>;
using DefArgContainer = std::tuple<std::remove_cv_t<std::remove_reference_t<DefArgs>>...>;
template<std::size_t N>
void ProcessArgs(const LuaState& instance) const
{
NazaraUnused(instance);
// No argument to process
}
template<std::size_t N, typename ArgType>
void ProcessArgs(const LuaState& instance) const
{
LuaImplArgProcesser<(N >= FirstDefArg)>::template Process<N, FirstDefArg, ArgType>(instance, m_index, m_args, m_defaultArgs);
}
template<std::size_t N, typename ArgType1, typename ArgType2, typename... Rest>
void ProcessArgs(const LuaState& instance) const
{
ProcessArgs<N, ArgType1>(instance);
ProcessArgs<N + 1, ArgType2, Rest...>(instance);
}
mutable ArgContainer m_args;
DefArgContainer m_defaultArgs;
mutable unsigned int m_index;
};
};
template<typename... Args>
class LuaImplMethodProxy
{
public:
template<typename... DefArgs>
class Impl
{
static constexpr std::size_t ArgCount = sizeof...(Args);
static constexpr std::size_t DefArgCount = sizeof...(DefArgs);
static_assert(ArgCount >= DefArgCount, "There cannot be more default arguments than argument");
static constexpr std::size_t FirstDefArg = ArgCount - DefArgCount;
public:
Impl(DefArgs... defArgs) :
m_defaultArgs(std::forward<DefArgs>(defArgs)...)
{
}
void ProcessArguments(const LuaState& instance) const
{
m_index = 2; //< 1 being the instance
ProcessArgs<0, Args...>(instance);
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, T>::value, int> Invoke(const LuaState& instance, T& object, void(P::*func)(Args...)) const
{
NazaraUnused(instance);
Apply(object, func, m_args);
return 0;
}
template<typename T, typename P, typename Ret>
std::enable_if_t<std::is_base_of<P, T>::value, int> Invoke(const LuaState& instance, T& object, Ret(P::*func)(Args...)) const
{
return LuaImplReplyVal(instance, std::move(Apply(object, func, m_args)), TypeTag<decltype(Apply(object, func, m_args))>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, T>::value, int> Invoke(const LuaState& instance, T& object, T&(P::*func)(Args...)) const
{
T& r = Apply(object, func, m_args);
if (&r == &object)
{
instance.PushValue(1); //< Userdata
return 1;
}
else
return LuaImplReplyVal(instance, r, TypeTag<T&>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, T>::value, int> Invoke(const LuaState& instance, const T& object, void(P::*func)(Args...) const) const
{
NazaraUnused(instance);
Apply(object, func, m_args);
return 0;
}
template<typename T, typename P, typename Ret>
std::enable_if_t<std::is_base_of<P, T>::value, int> Invoke(const LuaState& instance, const T& object, Ret(P::*func)(Args...) const) const
{
return LuaImplReplyVal(instance, std::move(Apply(object, func, m_args)), TypeTag<decltype(Apply(object, func, m_args))>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, T>::value, int> Invoke(const LuaState& instance, const T& object, const T&(P::*func)(Args...) const) const
{
const T& r = Apply(object, func, m_args);
if (&r == &object)
{
instance.PushValue(1); //< Userdata
return 1;
}
else
return LuaImplReplyVal(instance, r, TypeTag<T&>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, typename PointedType<T>::type>::value, int> Invoke(const LuaState& instance, T& object, void(P::*func)(Args...)) const
{
if (!object)
{
instance.Error("Invalid object");
return 0;
}
Apply(*object, func, m_args);
return 0;
}
template<typename T, typename P, typename Ret>
std::enable_if_t<std::is_base_of<P, typename PointedType<T>::type>::value, int> Invoke(const LuaState& instance, T& object, Ret(P::*func)(Args...)) const
{
if (!object)
{
instance.Error("Invalid object");
return 0;
}
return LuaImplReplyVal(instance, std::move(Apply(*object, func, m_args)), TypeTag<decltype(Apply(*object, func, m_args))>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, typename PointedType<T>::type>::value, int> Invoke(const LuaState& instance, T& object, typename PointedType<T>::type&(P::*func)(Args...) const) const
{
if (!object)
{
instance.Error("Invalid object");
return 0;
}
const typename PointedType<T>::type& r = Apply(*object, func, m_args);
if (&r == &*object)
{
instance.PushValue(1); //< Userdata
return 1;
}
else
return LuaImplReplyVal(instance, r, TypeTag<T&>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, typename PointedType<T>::type>::value, int> Invoke(const LuaState& instance, const T& object, void(P::*func)(Args...) const) const
{
if (!object)
{
instance.Error("Invalid object");
return 0;
}
Apply(*object, func, m_args);
return 0;
}
template<typename T, typename P, typename Ret>
std::enable_if_t<std::is_base_of<P, typename PointedType<T>::type>::value, int> Invoke(const LuaState& instance, const T& object, Ret(P::*func)(Args...) const) const
{
if (!object)
{
instance.Error("Invalid object");
return 0;
}
return LuaImplReplyVal(instance, std::move(Apply(*object, func, m_args)), TypeTag<decltype(Apply(*object, func, m_args))>());
}
template<typename T, typename P>
std::enable_if_t<std::is_base_of<P, typename PointedType<T>::type>::value, int> Invoke(const LuaState& instance, const T& object, const typename PointedType<T>::type&(P::*func)(Args...) const) const
{
if (!object)
{
instance.Error("Invalid object");
return 0;
}
const typename PointedType<T>::type& r = Apply(*object, func, m_args);
if (&r == &*object)
{
instance.PushValue(1); //< Userdata
return 1;
}
else
return LuaImplReplyVal(instance, r, TypeTag<T&>());
}
private:
using ArgContainer = std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...>;
using DefArgContainer = std::tuple<std::remove_cv_t<std::remove_reference_t<DefArgs>>...>;
template<std::size_t N>
void ProcessArgs(const LuaState& instance) const
{
NazaraUnused(instance);
// No argument to process
}
template<std::size_t N, typename ArgType>
void ProcessArgs(const LuaState& instance) const
{
m_index += LuaImplArgProcesser<(N >= FirstDefArg)>::template Process<N, FirstDefArg, ArgType>(instance, m_index, m_args, m_defaultArgs);
}
template<std::size_t N, typename ArgType1, typename ArgType2, typename... Rest>
void ProcessArgs(const LuaState& instance) const
{
ProcessArgs<N, ArgType1>(instance);
ProcessArgs<N + 1, ArgType2, Rest...>(instance);
}
mutable ArgContainer m_args;
DefArgContainer m_defaultArgs;
mutable unsigned int m_index;
};
};
template<typename T>
T LuaState::Check(int* index) const
{
NazaraAssert(index, "Invalid index pointer");
T object;
*index += LuaImplQueryArg(*this, *index, &object, TypeTag<T>());
return object;
}
template<typename T>
T LuaState::Check(int* index, T defValue) const
{
NazaraAssert(index, "Invalid index pointer");
T object;
*index += LuaImplQueryArg(*this, *index, &object, defValue, TypeTag<T>());
return object;
}
template<typename T>
inline T LuaState::CheckBoundInteger(int index) const
{
return CheckBounds<T>(index, CheckInteger(index));
}
template<typename T>
inline T LuaState::CheckBoundInteger(int index, T defValue) const
{
return CheckBounds<T>(index, CheckInteger(index, defValue));
}
template<typename T>
T LuaState::CheckField(const char* fieldName, int tableIndex) const
{
T object;
GetField(fieldName, tableIndex);
tableIndex += LuaImplQueryArg(*this, -1, &object, TypeTag<T>());
Pop();
return object;
}
template<typename T>
T LuaState::CheckField(const String& fieldName, int tableIndex) const
{
return CheckField<T>(fieldName.GetConstBuffer(), tableIndex);
}
template<typename T>
T LuaState::CheckField(const char* fieldName, T defValue, int tableIndex) const
{
T object;
GetField(fieldName, tableIndex);
tableIndex += LuaImplQueryArg(*this, -1, &object, defValue, TypeTag<T>());
Pop();
return object;
}
template<typename T>
T LuaState::CheckField(const String& fieldName, T defValue, int tableIndex) const
{
return CheckField<T>(fieldName.GetConstBuffer(), defValue, tableIndex);
}
template<typename T>
T LuaState::CheckGlobal(const char* fieldName) const
{
T object;
GetGlobal(fieldName);
LuaImplQueryArg(*this, -1, &object, TypeTag<T>());
Pop();
return object;
}
template<typename T>
T LuaState::CheckGlobal(const String& fieldName) const
{
return CheckGlobal<T>(fieldName.GetConstBuffer());
}
template<typename T>
T LuaState::CheckGlobal(const char* fieldName, T defValue) const
{
T object;
GetGlobal(fieldName);
LuaImplQueryArg(*this, -1, &object, defValue, TypeTag<T>());
Pop();
return object;
}
template<typename T>
T LuaState::CheckGlobal(const String& fieldName, T defValue) const
{
return CheckGlobal<T>(fieldName.GetConstBuffer(), defValue);
}
template<typename T>
int LuaState::Push(T arg) const
{
return LuaImplReplyVal(*this, std::move(arg), TypeTag<T>());
}
template<typename T, typename T2, typename... Args>
int LuaState::Push(T firstArg, T2 secondArg, Args... args) const
{
int valCount = 0;
valCount += Push(std::move(firstArg));
valCount += Push(secondArg, std::forward<Args>(args)...);
return valCount;
}
template<typename T>
void LuaState::PushField(const char* name, T&& arg, int tableIndex) const
{
Push<T>(std::forward<T>(arg));
SetField(name, tableIndex);
}
template<typename T>
void LuaState::PushField(const String& name, T&& arg, int tableIndex) const
{
PushField(name.GetConstBuffer(), std::forward<T>(arg), tableIndex);
}
template<typename R, typename... Args, typename... DefArgs>
void LuaState::PushFunction(R(*func)(Args...), DefArgs&&... defArgs) const
{
typename LuaImplFunctionProxy<Args...>::template Impl<DefArgs...> handler(std::forward<DefArgs>(defArgs)...);
PushFunction([func, handler] (LuaState& lua) -> int
{
handler.ProcessArguments(lua);
return handler.Invoke(lua, func);
});
}
template<typename T>
void LuaState::PushGlobal(const char* name, T&& arg)
{
Push<T>(std::forward<T>(arg));
SetGlobal(name);
}
template<typename T>
void LuaState::PushGlobal(const String& name, T&& arg)
{
PushGlobal(name.GetConstBuffer(), std::forward<T>(arg));
}
template<typename T>
void LuaState::PushInstance(const char* tname, const T& instance) const
{
T* userdata = static_cast<T*>(PushUserdata(sizeof(T)));
PlacementNew(userdata, instance);
SetMetatable(tname);
}
template<typename T>
void LuaState::PushInstance(const char* tname, T&& instance) const
{
T* userdata = static_cast<T*>(PushUserdata(sizeof(T)));
PlacementNew(userdata, std::move(instance));
SetMetatable(tname);
}
template<typename T, typename... Args>
void LuaState::PushInstance(const char* tname, Args&&... args) const
{
T* userdata = static_cast<T*>(PushUserdata(sizeof(T)));
PlacementNew(userdata, std::forward<Args>(args)...);
SetMetatable(tname);
}
template<typename T>
T LuaState::CheckBounds(int index, long long value) const
{
constexpr long long minBounds = std::numeric_limits<T>::min();
constexpr long long maxBounds = std::numeric_limits<T>::max();
if (value < minBounds || value > maxBounds)
{
Nz::StringStream stream;
stream << "Argument #" << index << " is outside value range [" << minBounds << ", " << maxBounds << "] (" << value << ')';
Error(stream);
}
return static_cast<T>(value);
}
inline LuaState LuaState::GetState(lua_State* internalState)
{
return LuaState(internalState);
}
}

View File

@ -133,9 +133,9 @@ namespace Nz
template<typename T>
bool Box<T>::Contains(T X, T Y, T Z) const
{
return X >= x && X <= x + width &&
Y >= y && Y <= y + height &&
Z >= z && Z <= z + depth;
return X >= x && X < x + width &&
Y >= y && Y < y + height &&
Z >= z && Z < z + depth;
}
/*!

View File

@ -117,8 +117,8 @@ namespace Nz
template<typename T>
bool Rect<T>::Contains(T X, T Y) const
{
return X >= x && X <= (x + width) &&
Y >= y && Y <= (y + height);
return X >= x && X < (x + width) &&
Y >= y && Y < (y + height);
}
/*!

View File

@ -34,6 +34,7 @@
#include <Nazara/Network/Config.hpp>
#include <Nazara/Network/Enums.hpp>
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Network/NetBuffer.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Network/Network.hpp>
#include <Nazara/Network/RUdpConnection.hpp>

View File

@ -9,12 +9,23 @@
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Network/Config.hpp>
#include <Nazara/Network/Enums.hpp>
#include <functional>
#include <tuple>
#include <type_traits>
namespace Nz
{
NAZARA_NETWORK_API const char* ErrorToString(Nz::ResolveError resolveError);
NAZARA_NETWORK_API const char* ErrorToString(Nz::SocketError socketError);
NAZARA_NETWORK_API bool ParseIPAddress(const char* addressPtr, UInt8 result[16], UInt16* port = nullptr, bool* isIPv6 = nullptr, const char** endOfRead = nullptr);
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, T> HostToNet(T value);
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, T> NetToHost(T value);
}
#include <Nazara/Network/Algorithm.inl>

View File

@ -2,6 +2,31 @@
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/Algorithm.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, T> HostToNet(T value)
{
#ifdef NAZARA_LITTLE_ENDIAN
return SwapBytes(value);
#else
return value;
#endif
}
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, T> NetToHost(T value)
{
#ifdef NAZARA_LITTLE_ENDIAN
return SwapBytes(value);
#else
return value;
#endif
}
}
#include <Nazara/Network/DebugOff.hpp>

View File

@ -0,0 +1,166 @@
/*
Copyright(c) 2002 - 2016 Lee Salzman
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.
*/
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_ENETHOST_HPP
#define NAZARA_ENETHOST_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Core/MemoryPool.hpp>
#include <Nazara/Network/ENetPeer.hpp>
#include <Nazara/Network/ENetProtocol.hpp>
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Network/NetBuffer.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Network/SocketPoller.hpp>
#include <Nazara/Network/UdpSocket.hpp>
#include <deque>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
namespace Nz
{
class NAZARA_NETWORK_API ENetHost
{
friend ENetPeer;
friend class Network;
public:
inline ENetHost();
ENetHost(const ENetHost&) = delete;
ENetHost(ENetHost&&) = default;
inline ~ENetHost();
void Broadcast(UInt8 channelId, ENetPacketFlags flags, NetPacket&& packet);
bool CheckEvents(ENetEvent* event);
ENetPeer* Connect(const IpAddress& remoteAddress, std::size_t channelCount = 0, UInt32 data = 0);
ENetPeer* Connect(const String& hostName, NetProtocol protocol = NetProtocol_Any, const String& service = "http", ResolveError* error = nullptr, std::size_t channelCount = 0, UInt32 data = 0);
inline bool Create(NetProtocol protocol, UInt16 port, std::size_t peerCount, std::size_t channelCount = 0);
bool Create(const IpAddress& address, std::size_t peerCount, std::size_t channelCount = 0);
bool Create(const IpAddress& address, std::size_t peerCount, std::size_t channelCount, UInt32 incomingBandwidth, UInt32 outgoingBandwidth);
void Destroy();
void Flush();
inline Nz::IpAddress GetBoundAddress() const;
inline UInt32 GetServiceTime() const;
int Service(ENetEvent* event, UInt32 timeout);
void SimulateNetwork(double packetLossProbability, UInt16 minDelay, UInt16 maxDelay);
ENetHost& operator=(const ENetHost&) = delete;
ENetHost& operator=(ENetHost&&) = default;
private:
ENetPacketRef AllocatePacket(ENetPacketFlags flags);
inline ENetPacketRef AllocatePacket(ENetPacketFlags flags, NetPacket&& data);
bool InitSocket(const IpAddress& address);
void AddToDispatchQueue(ENetPeer* peer);
void RemoveFromDispatchQueue(ENetPeer* peer);
bool DispatchIncomingCommands(ENetEvent* event);
ENetPeer* HandleConnect(ENetProtocolHeader* header, ENetProtocol* command);
bool HandleIncomingCommands(ENetEvent* event);
int ReceiveIncomingCommands(ENetEvent* event);
void NotifyConnect(ENetPeer* peer, ENetEvent* event, bool incoming);
void NotifyDisconnect(ENetPeer*, ENetEvent* event);
void SendAcknowledgements(ENetPeer* peer);
bool SendReliableOutgoingCommands(ENetPeer* peer);
int SendOutgoingCommands(ENetEvent* event, bool checkForTimeouts);
void SendUnreliableOutgoingCommands(ENetPeer* peer);
void ThrottleBandwidth();
static std::size_t GetCommandSize(UInt8 commandNumber);
static bool Initialize();
static void Uninitialize();
struct PendingIncomingPacket
{
IpAddress from;
NetPacket data;
UInt32 deliveryTime;
};
struct PendingOutgoingPacket
{
IpAddress to;
NetPacket data;
UInt32 deliveryTime;
};
std::array<ENetProtocol, ENetConstants::ENetProtocol_MaximumPacketCommands> m_commands;
std::array<NetBuffer, ENetConstants::ENetProtocol_MaximumPacketCommands * 2 + 1> m_buffers;
std::array<UInt8, ENetConstants::ENetProtocol_MaximumMTU> m_packetData[2];
std::bernoulli_distribution m_packetLossProbability;
std::size_t m_bandwidthLimitedPeers;
std::size_t m_bufferCount;
std::size_t m_channelLimit;
std::size_t m_commandCount;
std::size_t m_duplicatePeers;
std::size_t m_maximumPacketSize;
std::size_t m_maximumWaitingData;
std::size_t m_packetSize;
std::size_t m_peerCount;
std::size_t m_receivedDataLength;
std::uniform_int_distribution<UInt16> m_packetDelayDistribution;
std::vector<ENetPeer> m_peers;
std::vector<PendingIncomingPacket> m_pendingIncomingPackets;
std::vector<PendingOutgoingPacket> m_pendingOutgoingPackets;
UInt8* m_receivedData;
Bitset<UInt64> m_dispatchQueue;
MemoryPool m_packetPool;
IpAddress m_address;
IpAddress m_receivedAddress;
SocketPoller m_poller;
UdpSocket m_socket;
UInt16 m_headerFlags;
UInt32 m_bandwidthThrottleEpoch;
UInt32 m_connectedPeers;
UInt32 m_mtu;
UInt32 m_randomSeed;
UInt32 m_incomingBandwidth;
UInt32 m_outgoingBandwidth;
UInt32 m_serviceTime;
UInt32 m_totalSentPackets;
UInt32 m_totalReceivedPackets;
UInt64 m_totalSentData;
UInt64 m_totalReceivedData;
bool m_continueSending;
bool m_isSimulationEnabled;
bool m_recalculateBandwidthLimits;
static std::mt19937 s_randomGenerator;
static std::mt19937_64 s_randomGenerator64;
};
}
#include <Nazara/Network/ENetHost.inl>
#endif // NAZARA_ENETHOST_HPP

View File

@ -0,0 +1,74 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/ENetHost.hpp>
#include <utility>
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
inline ENetHost::ENetHost() :
m_packetPool(sizeof(ENetPacket)),
m_isSimulationEnabled(false)
{
}
inline ENetHost::~ENetHost()
{
Destroy();
}
inline bool ENetHost::Create(NetProtocol protocol, UInt16 port, std::size_t peerCount, std::size_t channelCount)
{
NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO
NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol");
IpAddress any;
switch (protocol)
{
case NetProtocol_Any:
case NetProtocol_Unknown:
NazaraInternalError("Invalid protocol Any at this point");
return false;
case NetProtocol_IPv4:
any = IpAddress::AnyIpV4;
break;
case NetProtocol_IPv6:
any = IpAddress::AnyIpV6;
break;
}
any.SetPort(port);
return Create(any, peerCount, channelCount);
}
inline void ENetHost::Destroy()
{
m_poller.Clear();
m_peers.clear();
m_socket.Close();
}
inline Nz::IpAddress ENetHost::GetBoundAddress() const
{
return m_address;
}
inline UInt32 Nz::ENetHost::GetServiceTime() const
{
return m_serviceTime;
}
inline ENetPacketRef ENetHost::AllocatePacket(ENetPacketFlags flags, NetPacket&& data)
{
ENetPacketRef ref = AllocatePacket(flags);
ref->data = std::move(data);
return ref;
}
}
#include <Nazara/Network/DebugOff.hpp>

View File

@ -0,0 +1,107 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_ENETPACKET_HPP
#define NAZARA_ENETPACKET_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Network/NetPacket.hpp>
namespace Nz
{
enum ENetPacketFlag
{
ENetPacketFlag_Reliable,
ENetPacketFlag_Unsequenced,
ENetPacketFlag_UnreliableFragment
};
template<>
struct EnumAsFlags<ENetPacketFlag>
{
static constexpr bool value = true;
static constexpr int max = ENetPacketFlag_UnreliableFragment;
};
using ENetPacketFlags = Flags<ENetPacketFlag>;
constexpr ENetPacketFlags ENetPacketFlag_Unreliable = 0;
class MemoryPool;
struct ENetPacket
{
MemoryPool* owner;
ENetPacketFlags flags;
NetPacket data;
std::size_t referenceCount = 0;
};
struct NAZARA_NETWORK_API ENetPacketRef
{
ENetPacketRef() = default;
ENetPacketRef(ENetPacket* packet)
{
Reset(packet);
}
ENetPacketRef(const ENetPacketRef& packet) :
ENetPacketRef()
{
Reset(packet);
}
ENetPacketRef(ENetPacketRef&& packet) :
m_packet(packet.m_packet)
{
packet.m_packet = nullptr;
}
~ENetPacketRef()
{
Reset();
}
void Reset(ENetPacket* packet = nullptr);
operator ENetPacket*() const
{
return m_packet;
}
ENetPacket* operator->() const
{
return m_packet;
}
ENetPacketRef& operator=(ENetPacket* packet)
{
Reset(packet);
return *this;
}
ENetPacketRef& operator=(const ENetPacketRef& packet)
{
Reset(packet);
return *this;
}
ENetPacketRef& operator=(ENetPacketRef&& packet)
{
m_packet = packet.m_packet;
packet.m_packet = nullptr;
return *this;
}
ENetPacket* m_packet = nullptr;
};
}
#endif // NAZARA_ENETPACKET_HPP

View File

@ -0,0 +1,248 @@
/*
Copyright(c) 2002 - 2016 Lee Salzman
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.
*/
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_ENETPEER_HPP
#define NAZARA_ENETPEER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Bitset.hpp>
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Network/ENetPacket.hpp>
#include <Nazara/Network/ENetProtocol.hpp>
#include <Nazara/Network/IpAddress.hpp>
#include <Nazara/Network/NetPacket.hpp>
#include <Nazara/Network/UdpSocket.hpp>
#include <array>
#include <list>
#include <random>
#include <vector>
namespace Nz
{
class ENetHost;
class NAZARA_NETWORK_API ENetPeer
{
friend ENetHost;
friend struct PacketRef;
public:
inline ENetPeer(ENetHost* host, UInt16 peerId);
ENetPeer(const ENetPeer&) = delete;
ENetPeer(ENetPeer&&) = default;
~ENetPeer() = default;
void Disconnect(UInt32 data);
void DisconnectLater(UInt32 data);
void DisconnectNow(UInt32 data);
inline const IpAddress& GetAddress() const;
inline UInt32 GetMtu() const;
inline UInt32 GetPacketThrottleAcceleration() const;
inline UInt32 GetPacketThrottleDeceleration() const;
inline UInt32 GetPacketThrottleInterval() const;
inline UInt16 GetPeerId() const;
inline UInt32 GetRoundTripTime() const;
inline ENetPeerState GetState() const;
inline bool HasPendingCommands();
inline bool IsConnected() const;
inline bool IsSimulationEnabled() const;
void Ping();
bool Receive(ENetPacketRef* packet, UInt8* channelId);
void Reset();
bool Send(UInt8 channelId, ENetPacketRef packetRef);
bool Send(UInt8 channelId, ENetPacketFlags flags, NetPacket&& packet);
void SimulateNetwork(double packetLossProbability, UInt16 minDelay, UInt16 maxDelay);
void ThrottleConfigure(UInt32 interval, UInt32 acceleration, UInt32 deceleration);
ENetPeer& operator=(const ENetPeer&) = delete;
ENetPeer& operator=(ENetPeer&&) = default;
private:
void InitIncoming(std::size_t channelCount, const IpAddress& address, ENetProtocolConnect& incomingCommand);
void InitOutgoing(std::size_t channelCount, const IpAddress& address, UInt32 connectId, UInt32 windowSize);
struct Acknowledgement;
struct Channel;
struct IncomingCommmand;
struct OutgoingCommand;
inline void ChangeState(ENetPeerState state);
bool CheckTimeouts(ENetEvent* event);
void DispatchState(ENetPeerState state);
void DispatchIncomingReliableCommands(Channel& channel);
void DispatchIncomingUnreliableCommands(Channel& channel);
bool HandleAcknowledge(const ENetProtocol* command, ENetEvent* event);
bool HandleBandwidthLimit(const ENetProtocol* command);
bool HandleDisconnect(const ENetProtocol* command);
bool HandlePing(const ENetProtocol* command);
bool HandleSendFragment(const ENetProtocol* command, UInt8** data);
bool HandleSendReliable(const ENetProtocol* command, UInt8** data);
bool HandleSendUnreliable(const ENetProtocol* command, UInt8** data);
bool HandleSendUnreliableFragment(const ENetProtocol* command, UInt8** data);
bool HandleSendUnsequenced(const ENetProtocol* command, UInt8** data);
bool HandleThrottleConfigure(const ENetProtocol* command);
bool HandleVerifyConnect(const ENetProtocol* command, ENetEvent* event);
void OnConnect();
void OnDisconnect();
ENetProtocolCommand RemoveSentReliableCommand(UInt16 reliableSequenceNumber, UInt8 channelId);
void RemoveSentUnreliableCommands();
void ResetQueues();
bool QueueAcknowledgement(ENetProtocol* command, UInt16 sentTime);
IncomingCommmand* QueueIncomingCommand(const ENetProtocol& command, const void* data, std::size_t dataLength, UInt32 flags, UInt32 fragmentCount);
inline void QueueOutgoingCommand(ENetProtocol& command);
void QueueOutgoingCommand(ENetProtocol& command, ENetPacketRef packet, UInt32 offset, UInt16 length);
void SetupOutgoingCommand(OutgoingCommand& outgoingCommand);
int Throttle(UInt32 rtt);
struct Acknowledgement
{
ENetProtocol command;
UInt32 sentTime;
};
struct Channel
{
Channel()
{
incomingReliableSequenceNumber = 0;
incomingUnreliableSequenceNumber = 0;
outgoingReliableSequenceNumber = 0;
outgoingUnreliableSequenceNumber = 0;
usedReliableWindows = 0;
reliableWindows.fill(0);
}
std::array<UInt16, ENetPeer_ReliableWindows> reliableWindows;
std::list<IncomingCommmand> incomingReliableCommands;
std::list<IncomingCommmand> incomingUnreliableCommands;
UInt16 incomingReliableSequenceNumber;
UInt16 incomingUnreliableSequenceNumber;
UInt16 outgoingReliableSequenceNumber;
UInt16 outgoingUnreliableSequenceNumber;
UInt16 usedReliableWindows;
};
struct IncomingCommmand
{
ENetProtocol command;
Bitset<> fragments;
ENetPacketRef packet;
UInt16 reliableSequenceNumber;
UInt16 unreliableSequenceNumber;
UInt32 fragmentsRemaining;
};
struct OutgoingCommand
{
ENetProtocol command;
ENetPacketRef packet;
UInt16 fragmentLength;
UInt16 reliableSequenceNumber;
UInt16 sendAttempts;
UInt16 unreliableSequenceNumber;
UInt32 fragmentOffset;
UInt32 roundTripTimeout;
UInt32 roundTripTimeoutLimit;
UInt32 sentTime;
};
static constexpr std::size_t unsequencedWindow = ENetPeer_ReliableWindowSize / 32;
ENetHost* m_host;
IpAddress m_address; /**< Internet address of the peer */
std::array<UInt32, unsequencedWindow> m_unsequencedWindow;
std::bernoulli_distribution m_packetLossProbability;
std::list<IncomingCommmand> m_dispatchedCommands;
std::list<OutgoingCommand> m_outgoingReliableCommands;
std::list<OutgoingCommand> m_outgoingUnreliableCommands;
std::list<OutgoingCommand> m_sentReliableCommands;
std::list<OutgoingCommand> m_sentUnreliableCommands;
std::size_t m_totalWaitingData;
std::uniform_int_distribution<UInt16> m_packetDelayDistribution;
std::vector<Acknowledgement> m_acknowledgements;
std::vector<Channel> m_channels;
ENetPeerState m_state;
UInt8 m_incomingSessionID;
UInt8 m_outgoingSessionID;
UInt16 m_incomingPeerID;
UInt16 m_incomingUnsequencedGroup;
UInt16 m_outgoingPeerID;
UInt16 m_outgoingReliableSequenceNumber;
UInt16 m_outgoingUnsequencedGroup;
UInt32 m_connectID;
UInt32 m_earliestTimeout;
UInt32 m_eventData;
UInt32 m_highestRoundTripTimeVariance;
UInt32 m_incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */
UInt32 m_incomingBandwidthThrottleEpoch;
UInt32 m_incomingDataTotal;
UInt32 m_lastReceiveTime;
UInt32 m_lastRoundTripTime;
UInt32 m_lastRoundTripTimeVariance;
UInt32 m_lastSendTime;
UInt32 m_lowestRoundTripTime;
UInt32 m_mtu;
UInt32 m_nextTimeout;
UInt32 m_outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */
UInt32 m_outgoingBandwidthThrottleEpoch;
UInt32 m_outgoingDataTotal;
UInt32 m_packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */
UInt32 m_packetLossEpoch;
UInt32 m_packetLossVariance;
UInt32 m_packetThrottle;
UInt32 m_packetThrottleAcceleration;
UInt32 m_packetThrottleCounter;
UInt32 m_packetThrottleDeceleration;
UInt32 m_packetThrottleEpoch;
UInt32 m_packetThrottleInterval;
UInt32 m_packetThrottleLimit;
UInt32 m_packetsLost;
UInt32 m_packetsSent;
UInt32 m_pingInterval;
UInt32 m_reliableDataInTransit;
UInt32 m_roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgment */
UInt32 m_roundTripTimeVariance;
UInt32 m_timeoutLimit;
UInt32 m_timeoutMaximum;
UInt32 m_timeoutMinimum;
UInt32 m_windowSize;
UInt64 m_totalPacketLost;
UInt64 m_totalPacketSent;
bool m_isSimulationEnabled;
};
}
#include <Nazara/Network/ENetPeer.inl>
#endif // NAZARA_ENETPEER_HPP

View File

@ -0,0 +1,92 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/ENetPeer.hpp>
#include <utility>
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
inline ENetPeer::ENetPeer(ENetHost* host, UInt16 peerId) :
m_host(host),
m_incomingSessionID(0xFF),
m_outgoingSessionID(0xFF),
m_incomingPeerID(peerId),
m_isSimulationEnabled(false)
{
Reset();
}
inline const IpAddress& ENetPeer::GetAddress() const
{
return m_address;
}
inline UInt32 ENetPeer::GetMtu() const
{
return m_mtu;
}
inline UInt32 ENetPeer::GetPacketThrottleAcceleration() const
{
return m_packetThrottleAcceleration;
}
inline UInt32 ENetPeer::GetPacketThrottleDeceleration() const
{
return m_packetThrottleDeceleration;
}
inline UInt32 ENetPeer::GetPacketThrottleInterval() const
{
return m_packetThrottleInterval;
}
inline UInt16 ENetPeer::GetPeerId() const
{
return m_incomingPeerID;
}
inline UInt32 ENetPeer::GetRoundTripTime() const
{
return m_roundTripTime;
}
inline ENetPeerState ENetPeer::GetState() const
{
return m_state;
}
inline bool ENetPeer::HasPendingCommands()
{
return m_outgoingReliableCommands.empty() && m_outgoingUnreliableCommands.empty() && m_sentReliableCommands.empty();
}
inline bool ENetPeer::IsConnected() const
{
return m_state == ENetPeerState::Connected || m_state == ENetPeerState::DisconnectLater;
}
inline bool ENetPeer::IsSimulationEnabled() const
{
return m_isSimulationEnabled;
}
inline void ENetPeer::ChangeState(ENetPeerState state)
{
if (state == ENetPeerState::Connected || state == ENetPeerState::DisconnectLater)
OnConnect();
else
OnDisconnect();
m_state = state;
}
inline void ENetPeer::QueueOutgoingCommand(ENetProtocol& command)
{
QueueOutgoingCommand(command, ENetPacketRef(), 0, 0);
}
}
#include <Nazara/Network/DebugOff.hpp>

View File

@ -0,0 +1,311 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_ENETPROTOCOL_HPP
#define NAZARA_ENETPROTOCOL_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Network/ENetPacket.hpp>
#include <vector>
namespace Nz
{
constexpr UInt32 ENetTimeOverflow = 24 * 60 * 60 * 1000;
inline UInt32 ENetTimeDifference(UInt32 a, UInt32 b);
inline bool ENetTimeLess(UInt32 a, UInt32 b);
inline bool ENetTimeLessEqual(UInt32 a, UInt32 b);
inline bool ENetTimeGreater(UInt32 a, UInt32 b);
inline bool ENetTimeGreaterEqual(UInt32 a, UInt32 b);
class ENetPeer;
// Constants for the ENet implementation and protocol
enum ENetConstants
{
ENetHost_BandwidthThrottleInterval = 1000,
ENetHost_DefaultMaximumPacketSize = 32 * 1024 * 1024,
ENetHost_DefaultMaximumWaitingData = 32 * 1024 * 1024,
ENetHost_DefaultMTU = 1400,
ENetHost_ReceiveBufferSize = 256 * 1024,
ENetHost_SendBufferSize = 256 * 1024,
ENetPeer_DefaultPacketThrottle = 32,
ENetPeer_DefaultRoundTripTime = 500,
ENetPeer_FreeReliableWindows = 8,
ENetPeer_FreeUnsequencedWindows = 32,
ENetPeer_PacketLossInterval = 10000,
ENetPeer_PacketLossScale = (1 << 16),
ENetPeer_PacketThrottleAcceleration = 2,
ENetPeer_PacketThrottleCounter = 7,
ENetPeer_PacketThrottleDeceleration = 2,
ENetPeer_PacketThrottleInterval = 5000,
ENetPeer_PacketThrottleScale = 32,
ENetPeer_PingInterval = 500,
ENetPeer_ReliableWindows = 16,
ENetPeer_ReliableWindowSize = 0x1000,
ENetPeer_TimeoutLimit = 32,
ENetPeer_TimeoutMaximum = 30000,
ENetPeer_TimeoutMinimum = 5000,
ENetPeer_UnsequencedWindows = 64,
ENetPeer_UnsequencedWindowSize = 1024,
ENetPeer_WindowSizeScale = 64 * 1024,
ENetProtocol_MaximumChannelCount = 255,
ENetProtocol_MaximumFragmentCount = 1024 * 1024,
ENetProtocol_MaximumMTU = 4096,
ENetProtocol_MaximumPacketCommands = 32,
ENetProtocol_MaximumPeerId = 0xFFF,
ENetProtocol_MaximumWindowSize = 65536,
ENetProtocol_MinimumChannelCount = 1,
ENetProtocol_MinimumMTU = 576,
ENetProtocol_MinimumWindowSize = 4096
};
enum class ENetPeerState
{
AcknowledgingConnect = 2,
AcknowledgingDisconnect = 8,
Connecting = 1,
ConnectionPending = 3,
ConnectionSucceeded = 4,
Connected = 5,
Disconnected = 0,
Disconnecting = 7,
DisconnectLater = 6,
Zombie = 9
};
enum ENetProtocolCommand
{
// Keeping the values is important for compatibility with the native ENet protocol
ENetProtocolCommand_Acknowledge = 1,
ENetProtocolCommand_BandwidthLimit = 10,
ENetProtocolCommand_Connect = 2,
ENetProtocolCommand_Disconnect = 4,
ENetProtocolCommand_None = 0,
ENetProtocolCommand_Ping = 5,
ENetProtocolCommand_SendFragment = 8,
ENetProtocolCommand_SendReliable = 6,
ENetProtocolCommand_SendUnreliable = 7,
ENetProtocolCommand_SendUnreliableFragment = 12,
ENetProtocolCommand_SendUnsequenced = 9,
ENetProtocolCommand_ThrottleConfigure = 11,
ENetProtocolCommand_VerifyConnect = 3,
ENetProtocolCommand_Count = 13,
ENetProtocolCommand_Mask = 0x0F
};
enum ENetProtocolFlag
{
ENetProtocolFlag_Acknowledge = (1 << 7),
ENetProtocolFlag_Unsequenced = (1 << 6),
ENetProtocolHeaderFlag_Compressed = (1 << 14),
ENetProtocolHeaderFlag_SentTime = (1 << 15),
ENetProtocolHeaderFlag_Mask = ENetProtocolHeaderFlag_Compressed | ENetProtocolHeaderFlag_SentTime,
ENetProtocolHeaderSessionMask = (3 << 12),
ENetProtocolHeaderSessionShift = 12
};
enum class ENetEventType
{
/** no event occurred within the specified time limit */
None,
/** a peer has disconnected. This event is generated on a successful
* completion of a disconnect initiated by enet_peer_disconnect, if
* a peer has timed out, or if a connection request initialized by
* enet_host_connect has timed out. The peer field contains the peer
* which disconnected. The data field contains user supplied data
* describing the disconnection, or 0, if none is available.
*/
Disconnect,
/** a connection request initiated by enet_host_connect from this host has completed.
* The peer field contains the peer which successfully connected.
*/
OutgoingConnect,
/** a connection request initiated by enet_host_connect from another host has completed.
* The peer field contains the peer which successfully connected.
*/
IncomingConnect,
/** a packet has been received from a peer. The peer field specifies the
* peer which sent the packet. The channelID field specifies the channel
* number upon which the packet was received. The packet field contains
* the packet that was received;
*/
Receive
};
struct ENetEvent
{
ENetEventType type;
ENetPeer* peer;
UInt8 channelId;
UInt32 data;
ENetPacketRef packet;
};
#ifdef _MSC_VER
#pragma pack(push, 1)
#define NAZARA_PACKED
#elif defined(__GNUC__) || defined(__clang__)
#define NAZARA_PACKED __attribute__ ((packed))
#else
#define NAZARA_PACKED
#endif
struct NAZARA_PACKED ENetProtocolHeader
{
UInt16 peerID;
UInt16 sentTime;
};
struct NAZARA_PACKED ENetProtocolCommandHeader
{
UInt8 command;
UInt8 channelID;
UInt16 reliableSequenceNumber;
};
struct NAZARA_PACKED ENetProtocolAcknowledge
{
ENetProtocolCommandHeader header;
UInt16 receivedReliableSequenceNumber;
UInt16 receivedSentTime;
};
struct NAZARA_PACKED ENetProtocolConnect
{
ENetProtocolCommandHeader header;
UInt16 outgoingPeerID;
UInt8 incomingSessionID;
UInt8 outgoingSessionID;
UInt32 mtu;
UInt32 windowSize;
UInt32 channelCount;
UInt32 incomingBandwidth;
UInt32 outgoingBandwidth;
UInt32 packetThrottleInterval;
UInt32 packetThrottleAcceleration;
UInt32 packetThrottleDeceleration;
UInt32 connectID;
UInt32 data;
};
struct NAZARA_PACKED ENetProtocolBandwidthLimit
{
ENetProtocolCommandHeader header;
UInt32 incomingBandwidth;
UInt32 outgoingBandwidth;
};
struct NAZARA_PACKED ENetProtocolDisconnect
{
ENetProtocolCommandHeader header;
UInt32 data;
};
struct NAZARA_PACKED ENetProtocolPing
{
ENetProtocolCommandHeader header;
};
struct NAZARA_PACKED ENetProtocolSendFragment
{
ENetProtocolCommandHeader header;
UInt16 startSequenceNumber;
UInt16 dataLength;
UInt32 fragmentCount;
UInt32 fragmentNumber;
UInt32 totalLength;
UInt32 fragmentOffset;
};
struct NAZARA_PACKED ENetProtocolSendReliable
{
ENetProtocolCommandHeader header;
UInt16 dataLength;
};
struct NAZARA_PACKED ENetProtocolSendUnreliable
{
ENetProtocolCommandHeader header;
UInt16 unreliableSequenceNumber;
UInt16 dataLength;
};
struct NAZARA_PACKED ENetProtocolSendUnsequenced
{
ENetProtocolCommandHeader header;
UInt16 unsequencedGroup;
UInt16 dataLength;
};
struct NAZARA_PACKED ENetProtocolThrottleConfigure
{
ENetProtocolCommandHeader header;
UInt32 packetThrottleInterval;
UInt32 packetThrottleAcceleration;
UInt32 packetThrottleDeceleration;
};
struct NAZARA_PACKED ENetProtocolVerifyConnect
{
ENetProtocolCommandHeader header;
UInt16 outgoingPeerID;
UInt8 incomingSessionID;
UInt8 outgoingSessionID;
UInt32 mtu;
UInt32 windowSize;
UInt32 channelCount;
UInt32 incomingBandwidth;
UInt32 outgoingBandwidth;
UInt32 packetThrottleInterval;
UInt32 packetThrottleAcceleration;
UInt32 packetThrottleDeceleration;
UInt32 connectID;
};
union NAZARA_PACKED ENetProtocol
{
ENetProtocol() = default;
ENetProtocol(UInt8 command, UInt8 channel)
{
header.command = command;
header.channelID = channel;
}
ENetProtocolCommandHeader header;
ENetProtocolAcknowledge acknowledge;
ENetProtocolBandwidthLimit bandwidthLimit;
ENetProtocolConnect connect;
ENetProtocolDisconnect disconnect;
ENetProtocolPing ping;
ENetProtocolSendReliable sendReliable;
ENetProtocolSendUnreliable sendUnreliable;
ENetProtocolSendUnsequenced sendUnsequenced;
ENetProtocolSendFragment sendFragment;
ENetProtocolThrottleConfigure throttleConfigure;
ENetProtocolVerifyConnect verifyConnect;
};
#ifdef _MSC_VER
#pragma pack(pop)
#endif
}
#include <Nazara/Network/ENetProtocol.inl>
#endif // NAZARA_ENETPROTOCOL_HPP

View File

@ -0,0 +1,34 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/ENetProtocol.hpp>
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
UInt32 ENetTimeDifference(UInt32 a, UInt32 b)
{
return (ENetTimeLess(a, b)) ? b - a : a - b;
}
bool ENetTimeLess(UInt32 a, UInt32 b)
{
return (a - b >= ENetTimeOverflow);
}
bool ENetTimeLessEqual(UInt32 a, UInt32 b)
{
return !ENetTimeGreater(a, b);
}
bool ENetTimeGreater(UInt32 a, UInt32 b)
{
return ENetTimeLess(b, a);
}
bool ENetTimeGreaterEqual(UInt32 a, UInt32 b)
{
return !ENetTimeLess(a, b);
}
}

View File

@ -7,7 +7,7 @@
#ifndef NAZARA_ENUMS_NETWORK_HPP
#define NAZARA_ENUMS_NETWORK_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Flags.hpp>
namespace Nz
{
@ -91,6 +91,23 @@ namespace Nz
SocketError_Max = SocketError_UnreachableHost
};
enum SocketPollEvent
{
SocketPollEvent_Read, //< One or more sockets is ready for a read operation
SocketPollEvent_Write, //< One or more sockets is ready for a write operation
SocketPollEvent_Max = SocketPollEvent_Write
};
template<>
struct EnumAsFlags<SocketPollEvent>
{
static constexpr bool value = true;
static constexpr int max = SocketPollEvent_Max;
};
using SocketPollEventFlags = Flags<SocketPollEvent>;
enum SocketState
{
SocketState_Bound, //< The socket is currently bound

View File

@ -155,7 +155,9 @@ namespace Nz
{
InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly);
m_buffer->Resize(HeaderSize + size);
std::memcpy(m_buffer->GetBuffer() + HeaderSize, ptr, size);
if (ptr)
std::memcpy(m_buffer->GetBuffer() + HeaderSize, ptr, size);
m_netCode = netCode;
}

View File

@ -24,10 +24,11 @@ namespace Nz
void Clear();
bool IsReady(const AbstractSocket& socket) const;
bool IsReadyToRead(const AbstractSocket& socket) const;
bool IsReadyToWrite(const AbstractSocket& socket) const;
bool IsRegistered(const AbstractSocket& socket) const;
bool RegisterSocket(AbstractSocket& socket);
bool RegisterSocket(AbstractSocket& socket, SocketPollEventFlags eventFlags);
void UnregisterSocket(AbstractSocket& socket);
bool Wait(UInt64 msTimeout);
@ -41,4 +42,4 @@ namespace Nz
#include <Nazara/Network/SocketPoller.inl>
#endif // NAZARA_SOCKETPOLLER_HPP
#endif // NAZARA_SOCKETPOLLER_HPP

View File

@ -33,7 +33,6 @@ namespace Nz
inline IpAddress GetBoundAddress() const;
inline UInt16 GetBoundPort() const;
inline SocketState GetState() const;
inline bool IsBroadcastingEnabled() const;

View File

@ -103,16 +103,6 @@ namespace Nz
return m_boundAddress.GetPort();
}
/*!
* \brief Gets the state of the socket
* \return State of the socket
*/
inline SocketState UdpSocket::GetState() const
{
return m_state;
}
/*!
* \brief Checks whether the broadcasting is enabled
* \return true If it is the case

View File

@ -40,6 +40,7 @@
#include <Nazara/Utility/Config.hpp>
#include <Nazara/Utility/CubemapParams.hpp>
#include <Nazara/Utility/Cursor.hpp>
#include <Nazara/Utility/CursorController.hpp>
#include <Nazara/Utility/Enums.hpp>
#include <Nazara/Utility/Event.hpp>
#include <Nazara/Utility/EventHandler.hpp>
@ -65,6 +66,7 @@
#include <Nazara/Utility/SimpleTextDrawer.hpp>
#include <Nazara/Utility/SkeletalMesh.hpp>
#include <Nazara/Utility/Skeleton.hpp>
#include <Nazara/Utility/SoftwareBuffer.hpp>
#include <Nazara/Utility/StaticMesh.hpp>
#include <Nazara/Utility/SubMesh.hpp>
#include <Nazara/Utility/TriangleIterator.hpp>

View File

@ -65,7 +65,7 @@ namespace Nz
static inline bool Convert(PixelFormatType srcFormat, PixelFormatType dstFormat, const void* src, void* dst);
static inline bool Convert(PixelFormatType srcFormat, PixelFormatType dstFormat, const void* start, const void* end, void* dst);
static inline bool Flip(PixelFlipping flipping, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst);
static bool Flip(PixelFlipping flipping, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst);
static inline UInt8 GetBitsPerPixel(PixelFormatType format);
static inline PixelFormatContent GetContent(PixelFormatType format);

View File

@ -227,102 +227,6 @@ namespace Nz
return true;
}
inline bool PixelFormat::Flip(PixelFlipping flipping, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid(format))
{
NazaraError("Invalid pixel format");
return false;
}
#endif
auto it = s_flipFunctions[flipping].find(format);
if (it != s_flipFunctions[flipping].end())
it->second(width, height, depth, reinterpret_cast<const UInt8*>(src), reinterpret_cast<UInt8*>(dst));
else
{
// Flipping générique
#if NAZARA_UTILITY_SAFE
if (IsCompressed(format))
{
NazaraError("No function to flip compressed format");
return false;
}
#endif
UInt8 bpp = GetBytesPerPixel(format);
unsigned int lineStride = width*bpp;
switch (flipping)
{
case PixelFlipping_Horizontally:
{
if (src == dst)
{
for (unsigned int z = 0; z < depth; ++z)
{
UInt8* ptr = reinterpret_cast<UInt8*>(dst) + width*height*z;
for (unsigned int y = 0; y < height/2; ++y)
std::swap_ranges(&ptr[y*lineStride], &ptr[(y+1)*lineStride-1], &ptr[(height-y-1)*lineStride]);
}
}
else
{
for (unsigned int z = 0; z < depth; ++z)
{
const UInt8* srcPtr = reinterpret_cast<const UInt8*>(src);
UInt8* dstPtr = reinterpret_cast<UInt8*>(dst) + (width-1)*height*depth*bpp;
for (unsigned int y = 0; y < height; ++y)
{
std::memcpy(dstPtr, srcPtr, lineStride);
srcPtr += lineStride;
dstPtr -= lineStride;
}
}
}
break;
}
case PixelFlipping_Vertically:
{
if (src == dst)
{
for (unsigned int z = 0; z < depth; ++z)
{
UInt8* ptr = reinterpret_cast<UInt8*>(dst) + width*height*z;
for (unsigned int y = 0; y < height; ++y)
{
for (unsigned int x = 0; x < width/2; ++x)
std::swap_ranges(&ptr[x*bpp], &ptr[(x+1)*bpp], &ptr[(width-x)*bpp]);
ptr += lineStride;
}
}
}
else
{
for (unsigned int z = 0; z < depth; ++z)
{
UInt8* ptr = reinterpret_cast<UInt8*>(dst) + width*height*z;
for (unsigned int y = 0; y < height; ++y)
{
for (unsigned int x = 0; x < width; ++x)
std::memcpy(&ptr[x*bpp], &ptr[(width-x)*bpp], bpp);
ptr += lineStride;
}
}
}
break;
}
}
}
return true;
}
inline UInt8 PixelFormat::GetBitsPerPixel(PixelFormatType format)
{
return s_pixelFormatInfos[format].bitsPerPixel;

View File

@ -108,21 +108,21 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
if (parameters.optimizeIndexBuffers)
postProcess |= aiProcess_ImproveCacheLocality;
float smoothingAngle = 80.f;
parameters.custom.GetFloatParameter("AssimpLoader_SmoothingAngle", &smoothingAngle);
double smoothingAngle = 80.f;
parameters.custom.GetDoubleParameter("AssimpLoader_SmoothingAngle", &smoothingAngle);
int triangleLimit = 1'000'000;
long long triangleLimit = 1'000'000;
parameters.custom.GetIntegerParameter("AssimpLoader_TriangleLimit", &triangleLimit);
int vertexLimit = 1'000'000;
long long vertexLimit = 1'000'000;
parameters.custom.GetIntegerParameter("AssimpLoader_VertexLimit", &vertexLimit);
aiPropertyStore* properties = aiCreatePropertyStore();
aiSetImportPropertyFloat(properties, AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, smoothingAngle);
aiSetImportPropertyFloat(properties, AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, float(smoothingAngle));
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_LBW_MAX_WEIGHTS, 4);
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SBP_REMOVE, ~aiPrimitiveType_TRIANGLE); //< We only want triangles
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, triangleLimit);
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_VERTEX_LIMIT, vertexLimit);
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_TRIANGLE_LIMIT, int(triangleLimit));
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_SLM_VERTEX_LIMIT, int(vertexLimit));
aiSetImportPropertyInteger(properties, AI_CONFIG_PP_RVC_FLAGS, aiComponent_COLORS);
const aiScene* scene = aiImportFileExWithProperties(userdata.originalFilePath, postProcess, &fileIO, properties);
@ -276,7 +276,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
break;
}
matData.SetParameter(wrapKey, static_cast<int>(wrap));
matData.SetParameter(wrapKey, static_cast<long long>(wrap));
}
}
};

View File

@ -95,7 +95,7 @@ namespace Nz
}
case ParameterType_Color:
case ParameterType_Float:
case ParameterType_Double:
case ParameterType_None:
case ParameterType_Pointer:
case ParameterType_Userdata:
@ -137,9 +137,9 @@ namespace Nz
return true;
case ParameterType_Boolean:
case ParameterType_Double:
case ParameterType_Integer:
case ParameterType_String:
case ParameterType_Float:
case ParameterType_None:
case ParameterType_Pointer:
case ParameterType_Userdata:
@ -151,19 +151,19 @@ namespace Nz
}
/*!
* \brief Gets a parameter as a float
* \return true if the parameter could be represented as a float
* \brief Gets a parameter as a double
* \return true if the parameter could be represented as a double
*
* \param name Name of the parameter
* \param value Pointer to a float to hold the retrieved value
* \param value Pointer to a double to hold the retrieved value
*
* \remark value must be a valid pointer
* \remark In case of failure, the variable pointed by value keep its value
* \remark If the parameter is not a float, a conversion will be performed, compatibles types are:
Integer: The integer value is converted to its float representation
* \remark If the parameter is not a double, a conversion will be performed, compatibles types are:
Integer: The integer value is converted to its double representation
String: Conversion obeys the rule as described by String::ToDouble
*/
bool ParameterList::GetFloatParameter(const String& name, float* value) const
bool ParameterList::GetDoubleParameter(const String& name, double* value) const
{
NazaraAssert(value, "Invalid pointer");
@ -178,12 +178,12 @@ namespace Nz
switch (it->second.type)
{
case ParameterType_Float:
*value = it->second.value.floatVal;
case ParameterType_Double:
*value = it->second.value.doubleVal;
return true;
case ParameterType_Integer:
*value = static_cast<float>(it->second.value.intVal);
*value = static_cast<double>(it->second.value.intVal);
return true;
case ParameterType_String:
@ -191,7 +191,7 @@ namespace Nz
double converted;
if (it->second.value.stringVal.ToDouble(&converted))
{
*value = static_cast<float>(converted);
*value = converted;
return true;
}
@ -206,7 +206,7 @@ namespace Nz
break;
}
NazaraError("Parameter value is not representable as a float");
NazaraError("Parameter value is not representable as a double");
return false;
}
@ -219,12 +219,12 @@ namespace Nz
*
* \remark value must be a valid pointer
* \remark In case of failure, the variable pointed by value keep its value
* \remark If the parameter is not a float, a conversion will be performed, compatibles types are:
* \remark If the parameter is not an integer, a conversion will be performed, compatibles types are:
Boolean: The boolean is represented as 1 if true and 0 if false
Float: The floating-point value is truncated and converted to a integer
String: Conversion obeys the rule as described by String::ToInteger but fails if the value could not be represented as a int
Double: The floating-point value is truncated and converted to a integer
String: Conversion obeys the rule as described by String::ToInteger
*/
bool ParameterList::GetIntegerParameter(const String& name, int* value) const
bool ParameterList::GetIntegerParameter(const String& name, long long* value) const
{
NazaraAssert(value, "Invalid pointer");
@ -243,8 +243,8 @@ namespace Nz
*value = (it->second.value.boolVal) ? 1 : 0;
return true;
case ParameterType_Float:
*value = static_cast<int>(it->second.value.floatVal);
case ParameterType_Double:
*value = static_cast<long long>(it->second.value.doubleVal);
return true;
case ParameterType_Integer:
@ -256,11 +256,8 @@ namespace Nz
long long converted;
if (it->second.value.stringVal.ToInteger(&converted))
{
if (converted <= std::numeric_limits<int>::max() && converted >= std::numeric_limits<int>::min())
{
*value = static_cast<int>(converted);
return true;
}
*value = converted;
return true;
}
break;
}
@ -335,7 +332,7 @@ namespace Nz
case ParameterType_Boolean:
case ParameterType_Color:
case ParameterType_Float:
case ParameterType_Double:
case ParameterType_Integer:
case ParameterType_None:
case ParameterType_String:
@ -358,7 +355,7 @@ namespace Nz
* \remark If the parameter is not a string, a conversion will be performed, all types are compatibles:
Boolean: Conversion obeys the rules of String::Boolean
Color: Conversion obeys the rules of Color::ToString
Float: Conversion obeys the rules of String::Number
Double: Conversion obeys the rules of String::Number
Integer: Conversion obeys the rules of String::Number
None: An empty string is returned
Pointer: Conversion obeys the rules of String::Pointer
@ -387,8 +384,8 @@ namespace Nz
*value = it->second.value.colorVal.ToString();
return true;
case ParameterType_Float:
*value = String::Number(it->second.value.floatVal);
case ParameterType_Double:
*value = String::Number(it->second.value.doubleVal);
return true;
case ParameterType_Integer:
@ -560,18 +557,18 @@ namespace Nz
}
/*!
* \brief Sets a float parameter named `name`
* \brief Sets a double parameter named `name`
*
* If a parameter already exists with that name, it is destroyed and replaced by this call
*
* \param name Name of the parameter
* \param value The float value
* \param value The double value
*/
void ParameterList::SetParameter(const String& name, float value)
void ParameterList::SetParameter(const String& name, double value)
{
Parameter& parameter = CreateValue(name);
parameter.type = ParameterType_Float;
parameter.value.floatVal = value;
parameter.type = ParameterType_Double;
parameter.value.doubleVal = value;
}
/*!
@ -582,7 +579,7 @@ namespace Nz
* \param name Name of the parameter
* \param value The integer value
*/
void ParameterList::SetParameter(const String& name, int value)
void ParameterList::SetParameter(const String& name, long long value)
{
Parameter& parameter = CreateValue(name);
parameter.type = ParameterType_Integer;
@ -627,8 +624,8 @@ namespace Nz
case ParameterType_Color:
ss << "Color(" << it->second.value.colorVal.ToString() << ")";
break;
case ParameterType_Float:
ss << "Float(" << it->second.value.floatVal << ")";
case ParameterType_Double:
ss << "Double(" << it->second.value.doubleVal << ")";
break;
case ParameterType_Integer:
ss << "Integer(" << it->second.value.intVal << ")";
@ -692,7 +689,7 @@ namespace Nz
{
case ParameterType_Boolean:
case ParameterType_Color:
case ParameterType_Float:
case ParameterType_Double:
case ParameterType_Integer:
case ParameterType_Pointer:
std::memcpy(&parameter, &it->second, sizeof(Parameter));
@ -764,7 +761,7 @@ namespace Nz
case ParameterType_Boolean:
case ParameterType_Color:
case ParameterType_Float:
case ParameterType_Double:
case ParameterType_Integer:
case ParameterType_None:
case ParameterType_Pointer:

View File

@ -114,14 +114,14 @@ namespace Nz
{
Color color;
bool isEnabled;
float fValue;
int iValue;
double dValue;
long long iValue;
String path;
ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled, true);
if (matData.GetFloatParameter(MaterialData::AlphaThreshold, &fValue))
SetAlphaThreshold(fValue);
if (matData.GetDoubleParameter(MaterialData::AlphaThreshold, &dValue))
SetAlphaThreshold(float(dValue));
if (matData.GetBooleanParameter(MaterialData::AlphaTest, &isEnabled))
EnableAlphaTest(isEnabled);
@ -147,17 +147,17 @@ namespace Nz
if (matData.GetIntegerParameter(MaterialData::FaceFilling, &iValue))
SetFaceFilling(static_cast<FaceFilling>(iValue));
if (matData.GetFloatParameter(MaterialData::LineWidth, &fValue))
SetLineWidth(fValue);
if (matData.GetDoubleParameter(MaterialData::LineWidth, &dValue))
SetLineWidth(float(dValue));
if (matData.GetFloatParameter(MaterialData::PointSize, &fValue))
SetPointSize(fValue);
if (matData.GetDoubleParameter(MaterialData::PointSize, &dValue))
SetPointSize(float(dValue));
if (matData.GetColorParameter(MaterialData::SpecularColor, &color))
SetSpecularColor(color);
if (matData.GetFloatParameter(MaterialData::Shininess, &fValue))
SetShininess(fValue);
if (matData.GetDoubleParameter(MaterialData::Shininess, &dValue))
SetShininess(float(dValue));
if (matData.GetIntegerParameter(MaterialData::SrcBlend, &iValue))
SetSrcBlend(static_cast<BlendFunc>(iValue));
@ -277,17 +277,17 @@ namespace Nz
matData->SetParameter(MaterialData::AlphaTest, IsAlphaTestEnabled());
matData->SetParameter(MaterialData::AlphaThreshold, GetAlphaThreshold());
matData->SetParameter(MaterialData::AmbientColor, GetAmbientColor());
matData->SetParameter(MaterialData::CullingSide, int(GetFaceCulling()));
matData->SetParameter(MaterialData::DepthFunc, int(GetDepthFunc()));
matData->SetParameter(MaterialData::CullingSide, static_cast<long long>(GetFaceCulling()));
matData->SetParameter(MaterialData::DepthFunc, static_cast<long long>(GetDepthFunc()));
matData->SetParameter(MaterialData::DepthSorting, IsDepthSortingEnabled());
matData->SetParameter(MaterialData::DiffuseColor, GetDiffuseColor());
matData->SetParameter(MaterialData::DstBlend, int(GetDstBlend()));
matData->SetParameter(MaterialData::FaceFilling, int(GetFaceFilling()));
matData->SetParameter(MaterialData::DstBlend, static_cast<long long>(GetDstBlend()));
matData->SetParameter(MaterialData::FaceFilling, static_cast<long long>(GetFaceFilling()));
matData->SetParameter(MaterialData::LineWidth, GetLineWidth());
matData->SetParameter(MaterialData::PointSize, GetPointSize());
matData->SetParameter(MaterialData::Shininess, GetShininess());
matData->SetParameter(MaterialData::SpecularColor, GetSpecularColor());
matData->SetParameter(MaterialData::SrcBlend, int(GetSrcBlend()));
matData->SetParameter(MaterialData::SrcBlend, static_cast<long long>(GetSrcBlend()));
// RendererParameter
matData->SetParameter(MaterialData::Blending, IsBlendingEnabled());
@ -299,29 +299,29 @@ namespace Nz
matData->SetParameter(MaterialData::StencilTest, IsStencilTestEnabled());
// Samplers
matData->SetParameter(MaterialData::DiffuseAnisotropyLevel, int(GetDiffuseSampler().GetAnisotropicLevel()));
matData->SetParameter(MaterialData::DiffuseFilter, int(GetDiffuseSampler().GetFilterMode()));
matData->SetParameter(MaterialData::DiffuseWrap, int(GetDiffuseSampler().GetWrapMode()));
matData->SetParameter(MaterialData::DiffuseAnisotropyLevel, static_cast<long long>(GetDiffuseSampler().GetAnisotropicLevel()));
matData->SetParameter(MaterialData::DiffuseFilter, static_cast<long long>(GetDiffuseSampler().GetFilterMode()));
matData->SetParameter(MaterialData::DiffuseWrap, static_cast<long long>(GetDiffuseSampler().GetWrapMode()));
matData->SetParameter(MaterialData::SpecularAnisotropyLevel, int(GetSpecularSampler().GetAnisotropicLevel()));
matData->SetParameter(MaterialData::SpecularFilter, int(GetSpecularSampler().GetFilterMode()));
matData->SetParameter(MaterialData::SpecularWrap, int(GetSpecularSampler().GetWrapMode()));
matData->SetParameter(MaterialData::SpecularAnisotropyLevel, static_cast<long long>(GetSpecularSampler().GetAnisotropicLevel()));
matData->SetParameter(MaterialData::SpecularFilter, static_cast<long long>(GetSpecularSampler().GetFilterMode()));
matData->SetParameter(MaterialData::SpecularWrap, static_cast<long long>(GetSpecularSampler().GetWrapMode()));
// Stencil
matData->SetParameter(MaterialData::StencilCompare, int(GetPipelineInfo().stencilCompare.front));
matData->SetParameter(MaterialData::StencilFail, int(GetPipelineInfo().stencilFail.front));
matData->SetParameter(MaterialData::StencilPass, int(GetPipelineInfo().stencilPass.front));
matData->SetParameter(MaterialData::StencilZFail, int(GetPipelineInfo().stencilDepthFail.front));
matData->SetParameter(MaterialData::StencilMask, int(GetPipelineInfo().stencilWriteMask.front));
matData->SetParameter(MaterialData::StencilReference, int(GetPipelineInfo().stencilReference.front));
matData->SetParameter(MaterialData::StencilCompare, static_cast<long long>(GetPipelineInfo().stencilCompare.front));
matData->SetParameter(MaterialData::StencilFail, static_cast<long long>(GetPipelineInfo().stencilFail.front));
matData->SetParameter(MaterialData::StencilPass, static_cast<long long>(GetPipelineInfo().stencilPass.front));
matData->SetParameter(MaterialData::StencilZFail, static_cast<long long>(GetPipelineInfo().stencilDepthFail.front));
matData->SetParameter(MaterialData::StencilMask, static_cast<long long>(GetPipelineInfo().stencilWriteMask.front));
matData->SetParameter(MaterialData::StencilReference, static_cast<long long>(GetPipelineInfo().stencilReference.front));
// Stencil (back)
matData->SetParameter(MaterialData::BackFaceStencilCompare, int(GetPipelineInfo().stencilCompare.back));
matData->SetParameter(MaterialData::BackFaceStencilFail, int(GetPipelineInfo().stencilFail.back));
matData->SetParameter(MaterialData::BackFaceStencilPass, int(GetPipelineInfo().stencilPass.back));
matData->SetParameter(MaterialData::BackFaceStencilZFail, int(GetPipelineInfo().stencilDepthFail.back));
matData->SetParameter(MaterialData::BackFaceStencilMask, int(GetPipelineInfo().stencilWriteMask.back));
matData->SetParameter(MaterialData::BackFaceStencilReference, int(GetPipelineInfo().stencilReference.back));
matData->SetParameter(MaterialData::BackFaceStencilCompare, static_cast<long long>(GetPipelineInfo().stencilCompare.back));
matData->SetParameter(MaterialData::BackFaceStencilFail, static_cast<long long>(GetPipelineInfo().stencilFail.back));
matData->SetParameter(MaterialData::BackFaceStencilPass, static_cast<long long>(GetPipelineInfo().stencilPass.back));
matData->SetParameter(MaterialData::BackFaceStencilZFail, static_cast<long long>(GetPipelineInfo().stencilDepthFail.back));
matData->SetParameter(MaterialData::BackFaceStencilMask, static_cast<long long>(GetPipelineInfo().stencilWriteMask.back));
matData->SetParameter(MaterialData::BackFaceStencilReference, static_cast<long long>(GetPipelineInfo().stencilReference.back));
// Textures
if (HasAlphaMap())

View File

@ -0,0 +1,56 @@
// 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/LuaInstance.hpp>
#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;
}
}

View File

@ -12,6 +12,7 @@
#include <Nazara/Core/MemoryHelper.hpp>
#include <Nazara/Core/MemoryView.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <cassert>
#include <cstdlib>
#include <stdexcept>
#include <unordered_map>
@ -21,117 +22,16 @@ namespace Nz
{
namespace
{
LuaType FromLuaType(int type)
int AtPanic(lua_State* internalState)
{
switch (type)
{
case LUA_TBOOLEAN:
return LuaType_Boolean;
case LUA_TFUNCTION:
return LuaType_Function;
case LUA_TLIGHTUSERDATA:
return LuaType_LightUserdata;
case LUA_TNIL:
return LuaType_Nil;
case LUA_TNONE:
return LuaType_None;
case LUA_TNUMBER:
return LuaType_Number;
case LUA_TSTRING:
return LuaType_String;
case LUA_TTABLE:
return LuaType_Table;
case LUA_TTHREAD:
return LuaType_Thread;
case LUA_TUSERDATA:
return LuaType_Userdata;
default:
return LuaType_None;
}
}
struct StreamData
{
Stream* stream;
char buffer[NAZARA_CORE_FILE_BUFFERSIZE];
};
int AtPanic(lua_State* state)
{
String lastError(lua_tostring(state, -1));
String lastError(lua_tostring(internalState, -1));
throw std::runtime_error("Lua panic: " + lastError);
}
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[] = {
LUA_OPEQ, // LuaComparison_Equality
LUA_OPLT, // LuaComparison_Less
LUA_OPLE // LuaComparison_LessOrEqual
};
static_assert(sizeof(s_comparisons)/sizeof(int) == LuaComparison_Max+1, "Lua comparison array is incomplete");
int s_operations[] = {
LUA_OPADD, // LuaOperation_Addition
LUA_OPBAND, // LuaOperation_BitwiseAnd
LUA_OPSHL, // LuaOperation_BitwiseLeftShift
LUA_OPBNOT, // LuaOperation_BitwiseNot
LUA_OPBOR, // LuaOperation_BitwiseOr
LUA_OPSHR, // LuaOperation_BitwiseRightShift
LUA_OPBXOR, // LuaOperation_BitwiseXOr
LUA_OPDIV, // LuaOperation_Division
LUA_OPPOW, // LuaOperation_Exponentiation
LUA_OPIDIV, // LuaOperation_FloorDivision
LUA_OPMUL, // LuaOperation_Multiplication
LUA_OPMOD, // LuaOperation_Modulo
LUA_OPUNM, // LuaOperation_Negation
LUA_OPSUB // LuaOperation_Substraction
};
static_assert(sizeof(s_operations)/sizeof(int) == LuaOperation_Max+1, "Lua operation array is incomplete");
int s_types[] = {
LUA_TBOOLEAN, // LuaType_Boolean
LUA_TFUNCTION, // LuaType_Function
LUA_TLIGHTUSERDATA, // LuaType_LightUserdata
LUA_TNIL, // LuaType_Nil
LUA_TNUMBER, // LuaType_Number
LUA_TNONE, // LuaType_None
LUA_TSTRING, // LuaType_String
LUA_TTABLE, // LuaType_Table
LUA_TTHREAD, // LuaType_Thread
LUA_TUSERDATA // LuaType_Userdata
};
static_assert(sizeof(s_types)/sizeof(int) == LuaType_Max+1, "Lua type array is incomplete");
}
LuaInstance::LuaInstance() :
LuaState(nullptr),
m_memoryLimit(0),
m_memoryUsage(0),
m_timeLimit(1000),
@ -143,738 +43,28 @@ namespace Nz
luaL_openlibs(m_state);
}
LuaInstance::LuaInstance(LuaInstance&& instance) noexcept :
m_memoryLimit(instance.m_memoryLimit),
m_memoryUsage(instance.m_memoryUsage),
m_timeLimit(instance.m_timeLimit),
m_clock(std::move(instance.m_clock)),
m_lastError(std::move(instance.m_lastError)),
m_state(instance.m_state),
m_level(instance.m_level)
{
instance.m_state = nullptr;
lua_setallocf(m_state, MemoryAllocator, this);
}
LuaInstance::~LuaInstance()
{
if (m_state)
lua_close(m_state);
}
void LuaInstance::ArgCheck(bool condition, unsigned int argNum, const char* error) const
inline void LuaInstance::SetMemoryUsage(std::size_t memoryUsage)
{
luaL_argcheck(m_state, condition, argNum, error);
}
void LuaInstance::ArgCheck(bool condition, unsigned int argNum, const String& error) const
{
luaL_argcheck(m_state, condition, argNum, error.GetConstBuffer());
}
int LuaInstance::ArgError(unsigned int argNum, const char* error) const
{
return luaL_argerror(m_state, argNum, error);
}
int LuaInstance::ArgError(unsigned int argNum, const String& error) const
{
return luaL_argerror(m_state, argNum, error.GetConstBuffer());
}
bool LuaInstance::Call(unsigned int argCount)
{
return Run(argCount, LUA_MULTRET);
}
bool LuaInstance::Call(unsigned int argCount, unsigned int resultCount)
{
return Run(argCount, resultCount);
}
void LuaInstance::CheckAny(int index) const
{
luaL_checkany(m_state, index);
}
bool LuaInstance::CheckBoolean(int index) const
{
if (lua_isnoneornil(m_state, index))
{
const char* msg = lua_pushfstring(m_state, "%s expected, got %s", lua_typename(m_state, LUA_TBOOLEAN), luaL_typename(m_state, index));
luaL_argerror(m_state, index, msg); // Lance une exception
return false;
}
return lua_toboolean(m_state, index) != 0;
}
bool LuaInstance::CheckBoolean(int index, bool defValue) const
{
if (lua_isnoneornil(m_state, index))
return defValue;
return lua_toboolean(m_state, index) != 0;
}
long long LuaInstance::CheckInteger(int index) const
{
return luaL_checkinteger(m_state, index);
}
long long LuaInstance::CheckInteger(int index, long long defValue) const
{
return luaL_optinteger(m_state, index, defValue);
}
double LuaInstance::CheckNumber(int index) const
{
return luaL_checknumber(m_state, index);
}
double LuaInstance::CheckNumber(int index, double defValue) const
{
return luaL_optnumber(m_state, index, defValue);
}
void LuaInstance::CheckStack(int space, const char* error) const
{
luaL_checkstack(m_state, space, error);
}
void LuaInstance::CheckStack(int space, const String& error) const
{
CheckStack(space, error.GetConstBuffer());
}
const char* LuaInstance::CheckString(int index, std::size_t* length) const
{
return luaL_checklstring(m_state, index, length);
}
const char* LuaInstance::CheckString(int index, const char* defValue, std::size_t* length) const
{
return luaL_optlstring(m_state, index, defValue, length);
}
void LuaInstance::CheckType(int index, LuaType type) const
{
#ifdef NAZARA_DEBUG
if (type > LuaType_Max)
{
NazaraError("Lua type out of enum");
return;
}
#endif
luaL_checktype(m_state, index, s_types[type]);
}
void* LuaInstance::CheckUserdata(int index, const char* tname) const
{
return luaL_checkudata(m_state, index, tname);
}
void* LuaInstance::CheckUserdata(int index, const String& tname) const
{
return luaL_checkudata(m_state, index, tname.GetConstBuffer());
}
bool LuaInstance::Compare(int index1, int index2, LuaComparison comparison) const
{
#ifdef NAZARA_DEBUG
if (comparison > LuaComparison_Max)
{
NazaraError("Lua comparison out of enum");
return false;
}
#endif
return (lua_compare(m_state, index1, index2, s_comparisons[comparison]) != 0);
}
void LuaInstance::Compute(LuaOperation operation) const
{
#ifdef NAZARA_DEBUG
if (operation > LuaOperation_Max)
{
NazaraError("Lua operation out of enum");
return;
}
#endif
lua_arith(m_state, s_operations[operation]);
}
void LuaInstance::Concatenate(int count) const
{
lua_concat(m_state, count);
}
int LuaInstance::CreateReference()
{
return luaL_ref(m_state, LUA_REGISTRYINDEX);
}
void LuaInstance::DestroyReference(int ref)
{
luaL_unref(m_state, LUA_REGISTRYINDEX, ref);
}
String LuaInstance::DumpStack() const
{
StringStream stream;
unsigned int stackTop = GetStackTop();
stream << stackTop << " entries\n";
for (unsigned int i = 1; i <= stackTop; ++i)
{
stream << i << ": ";
switch (GetType(i))
{
case LuaType_Boolean:
stream << "Boolean(" << ToBoolean(i) << ')';
break;
case LuaType_Function:
stream << "Function(" << ToPointer(i) << ')';
break;
case LuaType_LightUserdata:
case LuaType_Userdata:
stream << "Userdata(" << ToUserdata(i) << ')';
break;
case LuaType_Nil:
stream << "Nil";
break;
case LuaType_None:
stream << "None";
break;
case LuaType_Number:
stream << "Number(" << ToNumber(i) << ')';
break;
case LuaType_String:
stream << "String(" << ToString(i) << ')';
break;
case LuaType_Table:
stream << "Table(" << ToPointer(i) << ')';
break;
case LuaType_Thread:
stream << "Thread(" << ToPointer(i) << ')';
break;
default:
stream << "Unknown(" << ToPointer(i) << ')';
break;
}
stream << '\n';
}
return stream.ToString();
}
void LuaInstance::Error(const char* message) const
{
luaL_error(m_state, message);
}
void LuaInstance::Error(const String& message) const
{
luaL_error(m_state, message.GetConstBuffer());
}
bool LuaInstance::Execute(const String& 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;
}
return Run(0, 0);
}
bool LuaInstance::ExecuteFromFile(const String& filePath)
{
File file(filePath);
if (!file.Open(OpenMode_ReadOnly | OpenMode_Text))
{
NazaraError("Failed to open file");
return false;
}
std::size_t length = static_cast<std::size_t>(file.GetSize());
String source(length, '\0');
if (file.Read(&source[0], length) != length)
{
NazaraError("Failed to read file");
return false;
}
file.Close();
return Execute(source);
}
bool LuaInstance::ExecuteFromMemory(const void* data, std::size_t size)
{
MemoryView stream(data, size);
return ExecuteFromStream(stream);
}
bool LuaInstance::ExecuteFromStream(Stream& 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(0, 0);
}
int LuaInstance::GetAbsIndex(int index) const
{
return lua_absindex(m_state, index);
}
LuaType LuaInstance::GetField(const char* fieldName, int tableIndex) const
{
return FromLuaType(lua_getfield(m_state, tableIndex, fieldName));
}
LuaType LuaInstance::GetField(const String& fieldName, int tableIndex) const
{
return FromLuaType(lua_getfield(m_state, tableIndex, fieldName.GetConstBuffer()));
}
LuaType LuaInstance::GetGlobal(const char* name) const
{
return FromLuaType(lua_getglobal(m_state, name));
}
LuaType LuaInstance::GetGlobal(const String& name) const
{
return FromLuaType(lua_getglobal(m_state, name.GetConstBuffer()));
}
LuaType LuaInstance::GetMetatable(const char* tname) const
{
return FromLuaType(luaL_getmetatable(m_state, tname));
}
LuaType LuaInstance::GetMetatable(const String& tname) const
{
return FromLuaType(luaL_getmetatable(m_state, tname.GetConstBuffer()));
}
bool LuaInstance::GetMetatable(int index) const
{
return lua_getmetatable(m_state, index) != 0;
}
unsigned int LuaInstance::GetStackTop() const
{
return static_cast<int>(lua_gettop(m_state));
}
LuaType LuaInstance::GetTable(int index) const
{
return FromLuaType(lua_gettable(m_state, index));
}
LuaType LuaInstance::GetType(int index) const
{
return FromLuaType(lua_type(m_state, index));
}
const char* LuaInstance::GetTypeName(LuaType type) const
{
#ifdef NAZARA_DEBUG
if (type > LuaType_Max)
{
NazaraError("Lua type out of enum");
return nullptr;
}
#endif
return lua_typename(m_state, s_types[type]);
}
void LuaInstance::Insert(int index) const
{
lua_insert(m_state, index);
}
bool LuaInstance::IsOfType(int index, LuaType type) const
{
switch (type)
{
case LuaType_Boolean:
return lua_isboolean(m_state, index) != 0;
case LuaType_Function:
return lua_isfunction(m_state, index) != 0;
case LuaType_LightUserdata:
return lua_islightuserdata(m_state, index) != 0;
case LuaType_Nil:
return lua_isnil(m_state, index) != 0;
case LuaType_None:
return lua_isnone(m_state, index) != 0;
case LuaType_Number:
return lua_isnumber(m_state, index) != 0;
case LuaType_String:
return lua_isstring(m_state, index) != 0;
case LuaType_Table:
return lua_istable(m_state, index) != 0;
case LuaType_Thread:
return lua_isthread(m_state, index) != 0;
case LuaType_Userdata:
return lua_isuserdata(m_state, index) != 0;
}
NazaraError("Lua type not handled (0x" + String::Number(type, 16) + ')');
return false;
}
bool LuaInstance::IsOfType(int index, const char* tname) const
{
void* ud = luaL_testudata(m_state, index, tname);
return ud != nullptr;
}
bool LuaInstance::IsOfType(int index, const String& tname) const
{
return IsOfType(index, tname.GetConstBuffer());
}
bool LuaInstance::IsValid(int index) const
{
return lua_isnoneornil(m_state, index) == 0;
}
long long LuaInstance::Length(int index) const
{
return luaL_len(m_state, index);
}
void LuaInstance::MoveTo(LuaInstance* instance, int n) const
{
lua_xmove(m_state, instance->m_state, n);
}
bool LuaInstance::NewMetatable(const char* str)
{
return luaL_newmetatable(m_state, str) != 0;
}
bool LuaInstance::NewMetatable(const String& str)
{
return luaL_newmetatable(m_state, str.GetConstBuffer()) != 0;
}
bool LuaInstance::Next(int index) const
{
return lua_next(m_state, index) != 0;
}
void LuaInstance::Pop(unsigned int n) const
{
lua_pop(m_state, static_cast<int>(n));
}
void LuaInstance::PushBoolean(bool value) const
{
lua_pushboolean(m_state, (value) ? 1 : 0);
}
void LuaInstance::PushCFunction(LuaCFunction func, unsigned int upvalueCount) const
{
lua_pushcclosure(m_state, func, upvalueCount);
}
void LuaInstance::PushFunction(LuaFunction func) const
{
LuaFunction* luaFunc = static_cast<LuaFunction*>(lua_newuserdata(m_state, sizeof(LuaFunction)));
PlacementNew(luaFunc, std::move(func));
lua_pushcclosure(m_state, ProxyFunc, 1);
}
void LuaInstance::PushInteger(long long value) const
{
lua_pushinteger(m_state, value);
}
void LuaInstance::PushLightUserdata(void* value) const
{
lua_pushlightuserdata(m_state, value);
}
void LuaInstance::PushMetatable(const char* str) const
{
luaL_getmetatable(m_state, str);
}
void LuaInstance::PushMetatable(const String& str) const
{
luaL_getmetatable(m_state, str.GetConstBuffer());
}
void LuaInstance::PushNil() const
{
lua_pushnil(m_state);
}
void LuaInstance::PushNumber(double value) const
{
lua_pushnumber(m_state, value);
}
void LuaInstance::PushReference(int ref) const
{
lua_rawgeti(m_state, LUA_REGISTRYINDEX, ref);
}
void LuaInstance::PushString(const char* str) const
{
lua_pushstring(m_state, str);
}
void LuaInstance::PushString(const char* str, std::size_t size) const
{
lua_pushlstring(m_state, str, size);
}
void LuaInstance::PushString(const String& str) const
{
lua_pushlstring(m_state, str.GetConstBuffer(), str.GetSize());
}
void LuaInstance::PushTable(std::size_t sequenceElementCount, std::size_t arrayElementCount) const
{
constexpr std::size_t maxInt = std::numeric_limits<int>::max();
lua_createtable(m_state, static_cast<int>(std::min(sequenceElementCount, maxInt)), static_cast<int>(std::min(arrayElementCount, maxInt)));
}
void* LuaInstance::PushUserdata(std::size_t size) const
{
return lua_newuserdata(m_state, size);
}
void LuaInstance::PushValue(int index) const
{
lua_pushvalue(m_state, index);
}
void LuaInstance::Remove(int index) const
{
lua_remove(m_state, index);
}
void LuaInstance::Replace(int index) const
{
lua_replace(m_state, index);
}
void LuaInstance::SetField(const char* name, int tableIndex) const
{
lua_setfield(m_state, tableIndex, name);
}
void LuaInstance::SetField(const String& name, int tableIndex) const
{
lua_setfield(m_state, tableIndex, name.GetConstBuffer());
}
void LuaInstance::SetGlobal(const char* name)
{
lua_setglobal(m_state, name);
}
void LuaInstance::SetGlobal(const String& name)
{
lua_setglobal(m_state, name.GetConstBuffer());
}
void LuaInstance::SetMetatable(const char* tname) const
{
luaL_setmetatable(m_state, tname);
}
void LuaInstance::SetMetatable(const String& tname) const
{
luaL_setmetatable(m_state, tname.GetConstBuffer());
}
void LuaInstance::SetMetatable(int index) const
{
lua_setmetatable(m_state, index);
}
void LuaInstance::SetMemoryLimit(std::size_t memoryLimit)
{
m_memoryLimit = memoryLimit;
}
void LuaInstance::SetTable(int index) const
{
lua_settable(m_state, index);
}
void LuaInstance::SetTimeLimit(UInt32 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 LuaInstance::ToBoolean(int index) const
{
return lua_toboolean(m_state, index) != 0;
}
long long LuaInstance::ToInteger(int index, bool* succeeded) const
{
int success;
long long result = lua_tointegerx(m_state, index, &success);
if (succeeded)
*succeeded = (success != 0);
return result;
}
double LuaInstance::ToNumber(int index, bool* succeeded) const
{
int success;
double result = lua_tonumberx(m_state, index, &success);
if (succeeded)
*succeeded = (success != 0);
return result;
}
const void* LuaInstance::ToPointer(int index) const
{
return lua_topointer(m_state, index);
}
const char* LuaInstance::ToString(int index, std::size_t* length) const
{
return lua_tolstring(m_state, index, length);
}
void* LuaInstance::ToUserdata(int index) const
{
return lua_touserdata(m_state, index);
}
void* LuaInstance::ToUserdata(int index, const char* tname) const
{
return luaL_testudata(m_state, index, tname);
}
void* LuaInstance::ToUserdata(int index, const String& tname) const
{
return luaL_testudata(m_state, index, tname.GetConstBuffer());
}
LuaInstance& LuaInstance::operator=(LuaInstance&& instance) noexcept
{
m_clock = std::move(instance.m_clock);
m_lastError = std::move(instance.m_lastError);
m_level = instance.m_level;
m_memoryLimit = instance.m_memoryLimit;
m_memoryUsage = instance.m_memoryUsage;
m_state = instance.m_state;
m_timeLimit = instance.m_timeLimit;
instance.m_state = nullptr;
// Update allocator pointer
lua_setallocf(m_state, MemoryAllocator, this);
return *this;
}
int LuaInstance::GetIndexOfUpValue(int upValue)
{
return lua_upvalueindex(upValue);
}
LuaInstance* LuaInstance::GetInstance(lua_State* state)
{
LuaInstance* instance;
lua_getallocf(state, reinterpret_cast<void**>(&instance));
return instance;
}
bool LuaInstance::Run(int argCount, int resultCount)
{
if (m_level++ == 0)
m_clock.Restart();
int status = lua_pcall(m_state, argCount, resultCount, 0);
m_level--;
if (status != 0)
{
m_lastError = lua_tostring(m_state, -1);
lua_pop(m_state, 1);
return false;
}
return true;
m_memoryUsage = memoryUsage;
}
void* LuaInstance::MemoryAllocator(void* ud, void* ptr, std::size_t osize, std::size_t nsize)
{
LuaInstance* instance = static_cast<LuaInstance*>(ud);
std::size_t& memoryLimit = instance->m_memoryLimit;
std::size_t& memoryUsage = instance->m_memoryUsage;
std::size_t memoryLimit = instance->GetMemoryLimit();
std::size_t memoryUsage = instance->GetMemoryUsage();
if (nsize == 0)
{
memoryUsage -= osize;
assert(memoryUsage >= osize);
instance->SetMemoryUsage(memoryUsage - osize);
std::free(ptr);
return nullptr;
@ -891,24 +81,20 @@ namespace Nz
return nullptr;
}
memoryUsage = usage;
instance->SetMemoryUsage(usage);
return std::realloc(ptr, nsize);
}
}
int LuaInstance::ProxyFunc(lua_State* state)
{
LuaFunction& func = *static_cast<LuaFunction*>(lua_touserdata(state, lua_upvalueindex(1)));
return func(*GetInstance(state));
}
void LuaInstance::TimeLimiter(lua_State* state, lua_Debug* debug)
void LuaInstance::TimeLimiter(lua_State* internalState, lua_Debug* debug)
{
NazaraUnused(debug);
LuaInstance* instance = GetInstance(state);
if (instance->m_clock.GetMilliseconds() > instance->m_timeLimit)
luaL_error(state, "maximum execution time exceeded");
LuaInstance* instance;
lua_getallocf(internalState, reinterpret_cast<void**>(&instance));
if (instance->m_clock.GetMilliseconds() > instance->GetTimeLimit())
luaL_error(internalState, "maximum execution time exceeded");
}
}

843
src/Nazara/Lua/LuaState.cpp Normal file
View File

@ -0,0 +1,843 @@
// 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/LuaState.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/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>
#include <unordered_map>
#include <Nazara/Lua/Debug.hpp>
namespace Nz
{
namespace
{
LuaType FromLuaType(int type)
{
switch (type)
{
case LUA_TBOOLEAN:
return LuaType_Boolean;
case LUA_TFUNCTION:
return LuaType_Function;
case LUA_TLIGHTUSERDATA:
return LuaType_LightUserdata;
case LUA_TNIL:
return LuaType_Nil;
case LUA_TNONE:
return LuaType_None;
case LUA_TNUMBER:
return LuaType_Number;
case LUA_TSTRING:
return LuaType_String;
case LUA_TTABLE:
return LuaType_Table;
case LUA_TTHREAD:
return LuaType_Thread;
case LUA_TUSERDATA:
return LuaType_Userdata;
default:
return LuaType_None;
}
}
struct StreamData
{
Stream* stream;
char buffer[NAZARA_CORE_FILE_BUFFERSIZE];
};
const char* StreamReader(lua_State* internalState, void* data, std::size_t* size)
{
NazaraUnused(internalState);
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[] = {
LUA_OPEQ, // LuaComparison_Equality
LUA_OPLT, // LuaComparison_Less
LUA_OPLE // LuaComparison_LessOrEqual
};
static_assert(sizeof(s_comparisons)/sizeof(int) == LuaComparison_Max+1, "Lua comparison array is incomplete");
int s_operations[] = {
LUA_OPADD, // LuaOperation_Addition
LUA_OPBAND, // LuaOperation_BitwiseAnd
LUA_OPSHL, // LuaOperation_BitwiseLeftShift
LUA_OPBNOT, // LuaOperation_BitwiseNot
LUA_OPBOR, // LuaOperation_BitwiseOr
LUA_OPSHR, // LuaOperation_BitwiseRightShift
LUA_OPBXOR, // LuaOperation_BitwiseXOr
LUA_OPDIV, // LuaOperation_Division
LUA_OPPOW, // LuaOperation_Exponentiation
LUA_OPIDIV, // LuaOperation_FloorDivision
LUA_OPMUL, // LuaOperation_Multiplication
LUA_OPMOD, // LuaOperation_Modulo
LUA_OPUNM, // LuaOperation_Negation
LUA_OPSUB // LuaOperation_Substraction
};
static_assert(sizeof(s_operations)/sizeof(int) == LuaOperation_Max+1, "Lua operation array is incomplete");
int s_types[] = {
LUA_TBOOLEAN, // LuaType_Boolean
LUA_TFUNCTION, // LuaType_Function
LUA_TLIGHTUSERDATA, // LuaType_LightUserdata
LUA_TNIL, // LuaType_Nil
LUA_TNUMBER, // LuaType_Number
LUA_TNONE, // LuaType_None
LUA_TSTRING, // LuaType_String
LUA_TTABLE, // LuaType_Table
LUA_TTHREAD, // LuaType_Thread
LUA_TUSERDATA // LuaType_Userdata
};
static_assert(sizeof(s_types)/sizeof(int) == LuaType_Max+1, "Lua type array is incomplete");
}
LuaState::LuaState(LuaState&& state) noexcept :
m_lastError(state.m_lastError),
m_state(state.m_state)
{
}
void LuaState::ArgCheck(bool condition, unsigned int argNum, const char* error) const
{
luaL_argcheck(m_state, condition, argNum, error);
}
void LuaState::ArgCheck(bool condition, unsigned int argNum, const String& error) const
{
luaL_argcheck(m_state, condition, argNum, error.GetConstBuffer());
}
int LuaState::ArgError(unsigned int argNum, const char* error) const
{
return luaL_argerror(m_state, argNum, error);
}
int LuaState::ArgError(unsigned int argNum, const String& error) const
{
return luaL_argerror(m_state, argNum, error.GetConstBuffer());
}
bool LuaState::Call(unsigned int argCount)
{
return Run(argCount, LUA_MULTRET);
}
bool LuaState::Call(unsigned int argCount, unsigned int resultCount)
{
return Run(argCount, resultCount);
}
void LuaState::CheckAny(int index) const
{
luaL_checkany(m_state, index);
}
bool LuaState::CheckBoolean(int index) const
{
if (lua_isnoneornil(m_state, index))
{
const char* msg = lua_pushfstring(m_state, "%s expected, got %s", lua_typename(m_state, LUA_TBOOLEAN), luaL_typename(m_state, index));
luaL_argerror(m_state, index, msg); // Lance une exception
return false;
}
return lua_toboolean(m_state, index) != 0;
}
bool LuaState::CheckBoolean(int index, bool defValue) const
{
if (lua_isnoneornil(m_state, index))
return defValue;
return lua_toboolean(m_state, index) != 0;
}
long long LuaState::CheckInteger(int index) const
{
return luaL_checkinteger(m_state, index);
}
long long LuaState::CheckInteger(int index, long long defValue) const
{
return luaL_optinteger(m_state, index, defValue);
}
double LuaState::CheckNumber(int index) const
{
return luaL_checknumber(m_state, index);
}
double LuaState::CheckNumber(int index, double defValue) const
{
return luaL_optnumber(m_state, index, defValue);
}
void LuaState::CheckStack(int space, const char* error) const
{
luaL_checkstack(m_state, space, error);
}
void LuaState::CheckStack(int space, const String& error) const
{
CheckStack(space, error.GetConstBuffer());
}
const char* LuaState::CheckString(int index, std::size_t* length) const
{
return luaL_checklstring(m_state, index, length);
}
const char* LuaState::CheckString(int index, const char* defValue, std::size_t* length) const
{
return luaL_optlstring(m_state, index, defValue, length);
}
void LuaState::CheckType(int index, LuaType type) const
{
#ifdef NAZARA_DEBUG
if (type > LuaType_Max)
{
NazaraError("Lua type out of enum");
return;
}
#endif
luaL_checktype(m_state, index, s_types[type]);
}
void* LuaState::CheckUserdata(int index, const char* tname) const
{
return luaL_checkudata(m_state, index, tname);
}
void* LuaState::CheckUserdata(int index, const String& tname) const
{
return luaL_checkudata(m_state, index, tname.GetConstBuffer());
}
bool LuaState::Compare(int index1, int index2, LuaComparison comparison) const
{
#ifdef NAZARA_DEBUG
if (comparison > LuaComparison_Max)
{
NazaraError("Lua comparison out of enum");
return false;
}
#endif
return (lua_compare(m_state, index1, index2, s_comparisons[comparison]) != 0);
}
void LuaState::Compute(LuaOperation operation) const
{
#ifdef NAZARA_DEBUG
if (operation > LuaOperation_Max)
{
NazaraError("Lua operation out of enum");
return;
}
#endif
lua_arith(m_state, s_operations[operation]);
}
void LuaState::Concatenate(int count) const
{
lua_concat(m_state, count);
}
int LuaState::CreateReference()
{
return luaL_ref(m_state, LUA_REGISTRYINDEX);
}
void LuaState::DestroyReference(int ref)
{
luaL_unref(m_state, LUA_REGISTRYINDEX, ref);
}
String LuaState::DumpStack() const
{
StringStream stream;
unsigned int stackTop = GetStackTop();
stream << stackTop << " entries\n";
for (unsigned int i = 1; i <= stackTop; ++i)
{
stream << i << ": ";
switch (GetType(i))
{
case LuaType_Boolean:
stream << "Boolean(" << ToBoolean(i) << ')';
break;
case LuaType_Function:
stream << "Function(" << ToPointer(i) << ')';
break;
case LuaType_LightUserdata:
case LuaType_Userdata:
stream << "Userdata(" << ToUserdata(i) << ')';
break;
case LuaType_Nil:
stream << "Nil";
break;
case LuaType_None:
stream << "None";
break;
case LuaType_Number:
stream << "Number(" << ToNumber(i) << ')';
break;
case LuaType_String:
stream << "String(" << ToString(i) << ')';
break;
case LuaType_Table:
stream << "Table(" << ToPointer(i) << ')';
break;
case LuaType_Thread:
stream << "Thread(" << ToPointer(i) << ')';
break;
default:
stream << "Unknown(" << ToPointer(i) << ')';
break;
}
stream << '\n';
}
return stream.ToString();
}
void LuaState::Error(const char* message) const
{
luaL_error(m_state, message);
}
void LuaState::Error(const String& message) const
{
luaL_error(m_state, message.GetConstBuffer());
}
bool LuaState::Execute(const String& 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;
}
return Run(0, 0);
}
bool LuaState::ExecuteFromFile(const String& filePath)
{
File file(filePath);
if (!file.Open(OpenMode_ReadOnly | OpenMode_Text))
{
NazaraError("Failed to open file");
return false;
}
std::size_t length = static_cast<std::size_t>(file.GetSize());
String source(length, '\0');
if (file.Read(&source[0], length) != length)
{
NazaraError("Failed to read file");
return false;
}
file.Close();
return Execute(source);
}
bool LuaState::ExecuteFromMemory(const void* data, std::size_t size)
{
MemoryView stream(data, size);
return ExecuteFromStream(stream);
}
bool LuaState::ExecuteFromStream(Stream& 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(0, 0);
}
int LuaState::GetAbsIndex(int index) const
{
return lua_absindex(m_state, index);
}
LuaType LuaState::GetField(const char* fieldName, int tableIndex) const
{
return FromLuaType(lua_getfield(m_state, tableIndex, fieldName));
}
LuaType LuaState::GetField(const String& fieldName, int tableIndex) const
{
return FromLuaType(lua_getfield(m_state, tableIndex, fieldName.GetConstBuffer()));
}
LuaType LuaState::GetGlobal(const char* name) const
{
return FromLuaType(lua_getglobal(m_state, name));
}
LuaType LuaState::GetGlobal(const String& name) const
{
return FromLuaType(lua_getglobal(m_state, name.GetConstBuffer()));
}
LuaType LuaState::GetMetatable(const char* tname) const
{
return FromLuaType(luaL_getmetatable(m_state, tname));
}
LuaType LuaState::GetMetatable(const String& tname) const
{
return FromLuaType(luaL_getmetatable(m_state, tname.GetConstBuffer()));
}
bool LuaState::GetMetatable(int index) const
{
return lua_getmetatable(m_state, index) != 0;
}
unsigned int LuaState::GetStackTop() const
{
return static_cast<int>(lua_gettop(m_state));
}
LuaType LuaState::GetTable(int index) const
{
return FromLuaType(lua_gettable(m_state, index));
}
LuaType LuaState::GetTableRaw(int index) const
{
return FromLuaType(lua_rawget(m_state, index));
}
LuaType LuaState::GetType(int index) const
{
return FromLuaType(lua_type(m_state, index));
}
const char* LuaState::GetTypeName(LuaType type) const
{
#ifdef NAZARA_DEBUG
if (type > LuaType_Max)
{
NazaraError("Lua type out of enum");
return nullptr;
}
#endif
return lua_typename(m_state, s_types[type]);
}
void LuaState::Insert(int index) const
{
lua_insert(m_state, index);
}
bool LuaState::IsOfType(int index, LuaType type) const
{
switch (type)
{
case LuaType_Boolean:
return lua_isboolean(m_state, index) != 0;
case LuaType_Function:
return lua_isfunction(m_state, index) != 0;
case LuaType_LightUserdata:
return lua_islightuserdata(m_state, index) != 0;
case LuaType_Nil:
return lua_isnil(m_state, index) != 0;
case LuaType_None:
return lua_isnone(m_state, index) != 0;
case LuaType_Number:
return lua_isnumber(m_state, index) != 0;
case LuaType_String:
return lua_isstring(m_state, index) != 0;
case LuaType_Table:
return lua_istable(m_state, index) != 0;
case LuaType_Thread:
return lua_isthread(m_state, index) != 0;
case LuaType_Userdata:
return lua_isuserdata(m_state, index) != 0;
}
NazaraError("Lua type not handled (0x" + String::Number(type, 16) + ')');
return false;
}
bool LuaState::IsOfType(int index, const char* tname) const
{
void* ud = luaL_testudata(m_state, index, tname);
return ud != nullptr;
}
bool LuaState::IsOfType(int index, const String& tname) const
{
return IsOfType(index, tname.GetConstBuffer());
}
bool LuaState::IsValid(int index) const
{
return lua_isnoneornil(m_state, index) == 0;
}
long long LuaState::Length(int index) const
{
return luaL_len(m_state, index);
}
std::size_t LuaState::LengthRaw(int index) const
{
return lua_rawlen(m_state, index);
}
void LuaState::MoveTo(LuaState* instance, int n) const
{
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;
}
bool LuaState::NewMetatable(const String& str)
{
return luaL_newmetatable(m_state, str.GetConstBuffer()) != 0;
}
bool LuaState::Next(int index) const
{
return lua_next(m_state, index) != 0;
}
void LuaState::Pop(unsigned int n) const
{
lua_pop(m_state, static_cast<int>(n));
}
void LuaState::PushBoolean(bool value) const
{
lua_pushboolean(m_state, (value) ? 1 : 0);
}
void LuaState::PushCFunction(LuaCFunction func, unsigned int upvalueCount) const
{
lua_pushcclosure(m_state, func, upvalueCount);
}
void LuaState::PushFunction(LuaFunction func) const
{
LuaFunction* luaFunc = static_cast<LuaFunction*>(lua_newuserdata(m_state, sizeof(LuaFunction)));
PlacementNew(luaFunc, std::move(func));
lua_pushcclosure(m_state, ProxyFunc, 1);
}
void LuaState::PushInteger(long long value) const
{
lua_pushinteger(m_state, value);
}
void LuaState::PushLightUserdata(void* value) const
{
lua_pushlightuserdata(m_state, value);
}
void LuaState::PushMetatable(const char* str) const
{
luaL_getmetatable(m_state, str);
}
void LuaState::PushMetatable(const String& str) const
{
luaL_getmetatable(m_state, str.GetConstBuffer());
}
void LuaState::PushNil() const
{
lua_pushnil(m_state);
}
void LuaState::PushNumber(double value) const
{
lua_pushnumber(m_state, value);
}
void LuaState::PushReference(int ref) const
{
lua_rawgeti(m_state, LUA_REGISTRYINDEX, ref);
}
void LuaState::PushString(const char* str) const
{
lua_pushstring(m_state, str);
}
void LuaState::PushString(const char* str, std::size_t size) const
{
lua_pushlstring(m_state, str, size);
}
void LuaState::PushString(const String& str) const
{
lua_pushlstring(m_state, str.GetConstBuffer(), str.GetSize());
}
void LuaState::PushTable(std::size_t sequenceElementCount, std::size_t arrayElementCount) const
{
constexpr std::size_t maxInt = std::numeric_limits<int>::max();
lua_createtable(m_state, static_cast<int>(std::min(sequenceElementCount, maxInt)), static_cast<int>(std::min(arrayElementCount, maxInt)));
}
void* LuaState::PushUserdata(std::size_t size) const
{
return lua_newuserdata(m_state, size);
}
void LuaState::PushValue(int index) const
{
lua_pushvalue(m_state, index);
}
void LuaState::Remove(int index) const
{
lua_remove(m_state, index);
}
void LuaState::Replace(int index) const
{
lua_replace(m_state, index);
}
void LuaState::SetField(const char* name, int tableIndex) const
{
lua_setfield(m_state, tableIndex, name);
}
void LuaState::SetField(const String& name, int tableIndex) const
{
lua_setfield(m_state, tableIndex, name.GetConstBuffer());
}
void LuaState::SetGlobal(const char* name)
{
lua_setglobal(m_state, name);
}
void LuaState::SetGlobal(const String& name)
{
lua_setglobal(m_state, name.GetConstBuffer());
}
void LuaState::SetMetatable(const char* tname) const
{
luaL_setmetatable(m_state, tname);
}
void LuaState::SetMetatable(const String& tname) const
{
luaL_setmetatable(m_state, tname.GetConstBuffer());
}
void LuaState::SetMetatable(int index) const
{
lua_setmetatable(m_state, index);
}
void LuaState::SetTable(int index) const
{
lua_settable(m_state, index);
}
void LuaState::SetTableRaw(int index) const
{
lua_rawset(m_state, index);
}
bool LuaState::ToBoolean(int index) const
{
return lua_toboolean(m_state, index) != 0;
}
long long LuaState::ToInteger(int index, bool* succeeded) const
{
int success;
long long result = lua_tointegerx(m_state, index, &success);
if (succeeded)
*succeeded = (success != 0);
return result;
}
double LuaState::ToNumber(int index, bool* succeeded) const
{
int success;
double result = lua_tonumberx(m_state, index, &success);
if (succeeded)
*succeeded = (success != 0);
return result;
}
const void* LuaState::ToPointer(int index) const
{
return lua_topointer(m_state, index);
}
const char* LuaState::ToString(int index, std::size_t* length) const
{
return lua_tolstring(m_state, index, length);
}
void* LuaState::ToUserdata(int index) const
{
return lua_touserdata(m_state, index);
}
void* LuaState::ToUserdata(int index, const char* tname) const
{
return luaL_testudata(m_state, index, tname);
}
void* LuaState::ToUserdata(int index, const String& tname) const
{
return luaL_testudata(m_state, index, tname.GetConstBuffer());
}
LuaState& LuaState::operator=(LuaState&& state) noexcept
{
m_lastError = std::move(state.m_lastError);
m_state = state.m_state;
return *this;
}
bool LuaState::Run(int argCount, int resultCount)
{
LuaInstance& instance = GetInstance(m_state);
if (instance.m_level++ == 0)
instance.m_clock.Restart();
int status = lua_pcall(m_state, argCount, resultCount, 0);
instance.m_level--;
if (status != 0)
{
m_lastError = lua_tostring(m_state, -1);
lua_pop(m_state, 1);
return false;
}
return true;
}
int LuaState::GetIndexOfUpValue(int upValue)
{
return lua_upvalueindex(upValue);
}
LuaInstance& LuaState::GetInstance(lua_State* internalState)
{
LuaInstance* instance;
lua_getallocf(internalState, reinterpret_cast<void**>(&instance));
return *instance;
}
int LuaState::ProxyFunc(lua_State* internalState)
{
LuaFunction& func = *static_cast<LuaFunction*>(lua_touserdata(internalState, lua_upvalueindex(1)));
LuaState state = GetState(internalState);
return func(state);
}
}

View File

@ -19,7 +19,6 @@ namespace Nz
* \param number Optional argument to return the number parsed
* \param endOfRead Optional argument to determine where parsing stopped
*/
bool ParseDecimal(const char* str, unsigned int* number, const char** endOfRead)
{
const char* ptr = str;
@ -52,7 +51,6 @@ namespace Nz
* \param number Optional argument to return the number parsed
* \param endOfRead Optional argument to determine where parsing stopped
*/
bool ParseHexadecimal(const char* str, unsigned int* number, const char** endOfRead)
{
const char* ptr = str;
@ -78,8 +76,113 @@ namespace Nz
}
}
/*!
* \ingroup network
* \ingroup network
* \brief Returns the text representation of an error
* \return Text representation of an error
*
* \param resolveError Error enumeration
*/
const char* ErrorToString(Nz::ResolveError resolveError)
{
switch (resolveError)
{
case Nz::ResolveError_NoError:
return "No error";
case Nz::ResolveError_Internal:
return "An internal error occurred";
case Nz::ResolveError_ResourceError:
return "The operating system lacks the resources to proceed";
case Nz::ResolveError_NonRecoverable:
return "A nonrecoverable error occurred";
case Nz::ResolveError_NotFound:
return "No such host is known";
case Nz::ResolveError_NotInitialized:
return "Nazara Network has not been initialized";
case Nz::ResolveError_ProtocolNotSupported:
return "A specified protocol is not supported by the server";
case Nz::ResolveError_TemporaryFailure:
return "A temporary failure occurred, try again";
case Nz::ResolveError_Unknown:
return "An unknown error occurred";
default:
return "Invalid error value";
}
}
/*!
* \ingroup network
* \brief Returns the text representation of an error
* \return Text representation of an error
*
* \param socketError Error enumeration
*/
const char* ErrorToString(Nz::SocketError socketError)
{
switch (socketError)
{
case Nz::SocketError_NoError:
return "No error";
case Nz::SocketError_AddressNotAvailable:
return "The address is already in use";
case Nz::SocketError_ConnectionClosed:
return "The connection has been closed";
case Nz::SocketError_ConnectionRefused:
return "The connection attempt was refused";
case Nz::SocketError_DatagramSize:
return "The datagram size is over the system limit";
case Nz::SocketError_Internal:
return "An internal error occurred";
case Nz::SocketError_Packet:
return "Packet encoding or decoding failed";
case Nz::SocketError_NetworkError:
return "Networking subsystem failed";
case Nz::SocketError_NotInitialized:
return "Network module has not been initialized";
case Nz::SocketError_NotSupported:
return "This operation is not supported";
case Nz::SocketError_ResolveError:
return "The hostname couldn't be resolved";
case Nz::SocketError_ResourceError:
return "The operating system lacks the resources to proceed";
case Nz::SocketError_TimedOut:
return "The operation timed out";
case Nz::SocketError_Unknown:
return "An unknown error occurred";
case Nz::SocketError_UnreachableHost:
return "The host is not reachable";
default:
return "Invalid error value";
}
}
/*!
* \ingroup network
* \brief Parse a textual IPv4 or IPv6 address
* \return true If successful
*
@ -97,7 +200,6 @@ namespace Nz
* \remark Produces a NazaraAssert if addressPtr is invalid
* \remark Produces a NazaraAssert if result is invalid
*/
bool ParseIPAddress(const char* addressPtr, UInt8 result[16], UInt16* port, bool* isIPv6, const char** endOfRead)
{
NazaraAssert(addressPtr, "Invalid address string");

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Network/ENetPacket.hpp>
#include <Nazara/Core/MemoryPool.hpp>
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
/// Temporary
void ENetPacketRef::Reset(ENetPacket* packet)
{
if (m_packet)
{
if (--m_packet->referenceCount == 0)
m_packet->owner->Delete(m_packet);
}
m_packet = packet;
if (m_packet)
m_packet->referenceCount++;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -23,13 +23,19 @@ namespace Nz
void SocketPollerImpl::Clear()
{
m_activeSockets.clear();
m_readyToReadSockets.clear();
m_readyToWriteSockets.clear();
m_sockets.clear();
}
bool SocketPollerImpl::IsReady(SocketHandle socket) const
bool SocketPollerImpl::IsReadyToRead(SocketHandle socket) const
{
return m_activeSockets.count(socket) != 0;
return m_readyToReadSockets.count(socket) != 0;
}
bool SocketPollerImpl::IsReadyToWrite(SocketHandle socket) const
{
return m_readyToWriteSockets.count(socket) != 0;
}
bool SocketPollerImpl::IsRegistered(SocketHandle socket) const
@ -37,15 +43,21 @@ namespace Nz
return m_sockets.count(socket) != 0;
}
bool SocketPollerImpl::RegisterSocket(SocketHandle socket)
bool SocketPollerImpl::RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags)
{
NazaraAssert(!IsRegistered(socket), "Socket is already registered");
epoll_event event;
event.events = EPOLLIN;
event.data.fd = socket;
epoll_event entry;
entry.events = 0;
entry.data.fd = socket;
if (epoll_ctl(m_handle, EPOLL_CTL_ADD, socket, &event) != 0)
if (eventFlags & SocketPollEvent_Read)
entry.events |= EPOLLIN;
if (eventFlags & SocketPollEvent_Write)
entry.events |= EPOLLOUT;
if (epoll_ctl(m_handle, EPOLL_CTL_ADD, socket, &entry) != 0)
{
NazaraError("Failed to add socket to epoll structure (errno " + String::Number(errno) + ": " + Error::GetLastSystemError() + ')');
return false;
@ -60,7 +72,8 @@ namespace Nz
{
NazaraAssert(IsRegistered(socket), "Socket is not registered");
m_activeSockets.erase(socket);
m_readyToReadSockets.erase(socket);
m_readyToWriteSockets.erase(socket);
m_sockets.erase(socket);
if (epoll_ctl(m_handle, EPOLL_CTL_DEL, socket, nullptr) != 0)
@ -84,21 +97,27 @@ namespace Nz
return 0;
}
m_activeSockets.clear();
m_readyToReadSockets.clear();
m_readyToWriteSockets.clear();
if (activeSockets > 0)
{
int socketCount = activeSockets;
for (int i = 0; i < socketCount; ++i)
{
if (m_events[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR))
if (m_events[i].events & (EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLERR))
{
m_activeSockets.insert(m_events[i].data.fd);
if (m_events[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR))
m_readyToReadSockets.insert(m_events[i].data.fd);
if (m_events[i].events & (EPOLLOUT | EPOLLERR))
m_readyToWriteSockets.insert(m_events[i].data.fd);
if (m_events[i].events & EPOLLERR)
NazaraWarning("Descriptor " + String::Number(m_events[i].data.fd) + " was returned by epoll with EPOLLERR status");
}
else
{
NazaraWarning("Descriptor " + String::Number(m_events[i].data.fd) + " was returned by epoll without EPOLLIN (events: 0x" + String::Number(m_events[i].events, 16) + ')');
NazaraWarning("Descriptor " + String::Number(m_events[i].data.fd) + " was returned by epoll without EPOLLIN nor EPOLLOUT flags (events: 0x" + String::Number(m_events[i].events, 16) + ')');
activeSockets--;
}
}

View File

@ -23,16 +23,18 @@ namespace Nz
void Clear();
bool IsReady(SocketHandle socket) const;
bool IsReadyToRead(SocketHandle socket) const;
bool IsReadyToWrite(SocketHandle socket) const;
bool IsRegistered(SocketHandle socket) const;
bool RegisterSocket(SocketHandle socket);
bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
private:
std::unordered_set<SocketHandle> m_activeSockets;
std::unordered_set<SocketHandle> m_readyToReadSockets;
std::unordered_set<SocketHandle> m_readyToWriteSockets;
std::unordered_set<SocketHandle> m_sockets;
std::vector<epoll_event> m_events;
int m_handle;

View File

@ -10,14 +10,20 @@ namespace Nz
{
void SocketPollerImpl::Clear()
{
m_activeSockets.clear();
m_readyToReadSockets.clear();
m_readyToWriteSockets.clear();
m_allSockets.clear();
m_sockets.clear();
}
bool SocketPollerImpl::IsReady(SocketHandle socket) const
bool SocketPollerImpl::IsReadyToRead(SocketHandle socket) const
{
return m_activeSockets.count(socket) != 0;
return m_readyToReadSockets.count(socket) != 0;
}
bool SocketPollerImpl::IsReadyToWrite(SocketHandle socket) const
{
return m_readyToWriteSockets.count(socket) != 0;
}
bool SocketPollerImpl::IsRegistered(SocketHandle socket) const
@ -25,16 +31,22 @@ namespace Nz
return m_allSockets.count(socket) != 0;
}
bool SocketPollerImpl::RegisterSocket(SocketHandle socket)
bool SocketPollerImpl::RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags)
{
NazaraAssert(!IsRegistered(socket), "Socket is already registered");
PollSocket entry = {
socket,
POLLRDNORM,
0,
0
};
if (eventFlags & SocketPollEvent_Read)
entry.events |= POLLRDNORM;
if (eventFlags & SocketPollEvent_Write)
entry.events |= POLLWRNORM;
m_allSockets[socket] = m_sockets.size();
m_sockets.emplace_back(entry);
@ -57,10 +69,11 @@ namespace Nz
// Now move it properly (lastElement is invalid after the following line) and pop it
m_sockets[entry] = std::move(m_sockets.back());
}
m_sockets.pop_back();
m_activeSockets.erase(socket);
m_allSockets.erase(socket);
m_readyToReadSockets.erase(socket);
m_readyToWriteSockets.erase(socket);
}
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
@ -68,20 +81,25 @@ namespace Nz
int activeSockets;
// Reset status of sockets
for (PollSocket& entry : m_sockets)
entry.revents = 0;
activeSockets = SocketImpl::Poll(m_sockets.data(), m_sockets.size(), static_cast<int>(msTimeout), error);
m_activeSockets.clear();
if (activeSockets > 0)
m_readyToReadSockets.clear();
m_readyToWriteSockets.clear();
if (activeSockets > 0U)
{
int socketRemaining = activeSockets;
for (PollSocket& entry : m_sockets)
{
if (entry.revents & POLLRDNORM)
if (entry.revents != 0)
{
m_activeSockets.insert(entry.fd);
if (entry.revents & POLLRDNORM)
m_readyToReadSockets.insert(entry.fd);
if (entry.revents & POLLWRNORM)
m_readyToWriteSockets.insert(entry.fd);
entry.revents = 0;
if (--socketRemaining == 0)
break;
}

View File

@ -27,13 +27,14 @@ namespace Nz
bool IsReady(SocketHandle socket) const;
bool IsRegistered(SocketHandle socket) const;
bool RegisterSocket(SocketHandle socket);
bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
private:
std::unordered_set<SocketHandle> m_activeSockets;
std::unordered_set<SocketHandle> m_readyToReadSockets;
std::unordered_set<SocketHandle> m_readyToWriteSockets;
std::unordered_map<SocketHandle, std::size_t> m_allSockets;
std::vector<PollSocket> m_sockets;
};

View File

@ -57,12 +57,13 @@ namespace Nz
/*!
* \brief Checks if a specific socket is ready to read data
*
* This function allows you to read the results of the last Wait operation and if a specific socket is ready.
* This function allows you to read the results of the last Wait operation and if a specific socket is ready to read (has incoming data).
*
* A socket in the ready state (with the exception of TcpServer) has incoming data and can be read without blocking.
* A socket in the ready to read state (with the exception of TcpServer) has incoming data and can be read without blocking.
*
* \remark When used on a TcpServer socket, this function returns true if the server is ready to accept a new client.
* \remark You must call Wait before using this function in order to refresh the state.
* \remark You must call Wait before using this function in order to refresh the read state.
* \remark A socket must be registered with SocketPollerEvent_Read event flag for its read state to be watched
* \remark A TcpServer socket becomes ready to read when it is ready to accept a new client.
*
* \param socket Reference to the socket to check
*
@ -70,11 +71,32 @@ namespace Nz
*
* \see Wait
*/
bool SocketPoller::IsReady(const AbstractSocket& socket) const
bool SocketPoller::IsReadyToRead(const AbstractSocket& socket) const
{
NazaraAssert(IsRegistered(socket), "Socket is not registered in the poller");
return m_impl->IsReady(socket.GetNativeHandle());
return m_impl->IsReadyToRead(socket.GetNativeHandle());
}
/*!
* \brief Checks if a specific socket is ready to write data
*
* This function allows you to read the results of the last Wait operation and if a specific socket is ready to write (can be written to without blocking).
*
* \remark You must call Wait before using this function in order to refresh the read state.
* \remark A socket must be registered with SocketPollerEvent_Write event flag for its read state to be watched
*
* \param socket Reference to the socket to check
*
* \return True if the socket is available for writing without blocking, false otherwise
*
* \see Wait
*/
bool SocketPoller::IsReadyToWrite(const AbstractSocket& socket) const
{
NazaraAssert(IsRegistered(socket), "Socket is not registered in the poller");
return m_impl->IsReadyToWrite(socket.GetNativeHandle());
}
/*!
@ -97,7 +119,7 @@ namespace Nz
/*!
* \brief Register a socket in the SocketPoller
*
* A registered socket is part of the SocketPoller and will be checked by the next Wait operations.
* A registered socket is part of the SocketPoller and will be checked by the next Wait operations according to the event flags passed when registered.
*
* The SocketPoller keeps a reference to the internal handle of registered socket, which should not be freed while it is registered in the SocketPooler.
*
@ -107,17 +129,18 @@ namespace Nz
* \remark The socket should not be freed while it is registered in the SocketPooler.
*
* \param socket Reference to the socket to register
* \param eventFlags Socket events to watch
*
* \return True if the socket is registered, false otherwise
*
* \see IsRegistered
* \see UnregisterSocket
*/
bool SocketPoller::RegisterSocket(AbstractSocket& socket)
bool SocketPoller::RegisterSocket(AbstractSocket& socket, SocketPollEventFlags eventFlags)
{
NazaraAssert(!IsRegistered(socket), "This socket is already registered in this SocketPoller");
return m_impl->RegisterSocket(socket.GetNativeHandle());
return m_impl->RegisterSocket(socket.GetNativeHandle(), eventFlags);
}
/*!
@ -145,7 +168,7 @@ namespace Nz
* \brief Wait until any registered socket switches to a ready state.
*
* Waits a specific/undetermined amount of time until at least one socket part of the SocketPoller becomes ready.
* To query the ready state of the registered socket, use the IsReady function.
* To query the ready state of the registered socket, use the IsReadyToRead or IsReadyToWrite functions.
*
* \param msTimeout Maximum time to wait in milliseconds, 0 for infinity
*

View File

@ -10,29 +10,43 @@ namespace Nz
SocketPollerImpl::SocketPollerImpl()
{
#if !NAZARA_NETWORK_POLL_SUPPORT
FD_ZERO(&m_activeSockets);
FD_ZERO(&m_sockets);
FD_ZERO(&m_readSockets);
FD_ZERO(&m_readyToReadSockets);
FD_ZERO(&m_readyToWriteSockets);
FD_ZERO(&m_writeSockets);
#endif
}
void SocketPollerImpl::Clear()
{
#if NAZARA_NETWORK_POLL_SUPPORT
m_activeSockets.clear();
m_allSockets.clear();
m_readyToReadSockets.clear();
m_readyToWriteSockets.clear();
m_sockets.clear();
#else
FD_ZERO(&m_activeSockets);
FD_ZERO(&m_sockets);
FD_ZERO(&m_readSockets);
FD_ZERO(&m_readyToReadSockets);
FD_ZERO(&m_readyToWriteSockets);
FD_ZERO(&m_writeSockets);
#endif
}
bool SocketPollerImpl::IsReady(SocketHandle socket) const
bool SocketPollerImpl::IsReadyToRead(SocketHandle socket) const
{
#if NAZARA_NETWORK_POLL_SUPPORT
return m_activeSockets.count(socket) != 0;
return m_readyToReadSockets.count(socket) != 0;
#else
return FD_ISSET(socket, &m_activeSockets) != 0;
return FD_ISSET(socket, &m_readyToReadSockets) != 0;
#endif
}
bool SocketPollerImpl::IsReadyToWrite(SocketHandle socket) const
{
#if NAZARA_NETWORK_POLL_SUPPORT
return m_readyToWriteSockets.count(socket) != 0;
#else
return FD_ISSET(socket, &m_readyToWriteSockets) != 0;
#endif
}
@ -41,31 +55,45 @@ namespace Nz
#if NAZARA_NETWORK_POLL_SUPPORT
return m_allSockets.count(socket) != 0;
#else
return FD_ISSET(socket, &m_sockets) != 0;
return FD_ISSET(socket, &m_readSockets) != 0 ||
FD_ISSET(socket, &m_writeSockets) != 0;
#endif
}
bool SocketPollerImpl::RegisterSocket(SocketHandle socket)
bool SocketPollerImpl::RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags)
{
NazaraAssert(!IsRegistered(socket), "Socket is already registered");
#if NAZARA_NETWORK_POLL_SUPPORT
PollSocket entry = {
socket,
POLLRDNORM,
0,
0
};
if (eventFlags & SocketPollEvent_Read)
entry.events |= POLLRDNORM;
if (eventFlags & SocketPollEvent_Write)
entry.events |= POLLWRNORM;
m_allSockets[socket] = m_sockets.size();
m_sockets.emplace_back(entry);
#else
if (m_sockets.fd_count > FD_SETSIZE)
for (std::size_t i = 0; i < 2; ++i)
{
NazaraError("Socket count exceeding FD_SETSIZE (" + String::Number(FD_SETSIZE) + ")");
return false;
}
if ((eventFlags & ((i == 0) ? SocketPollEvent_Read : SocketPollEvent_Write)) == 0)
continue;
FD_SET(socket, &m_sockets);
fd_set& targetSet = (i == 0) ? m_readSockets : m_writeSockets;
if (targetSet.fd_count > FD_SETSIZE)
{
NazaraError("Socket count exceeding hard-coded FD_SETSIZE (" + String::Number(FD_SETSIZE) + ")");
return false;
}
FD_SET(socket, &targetSet);
}
#endif
return true;
@ -88,13 +116,16 @@ namespace Nz
// Now move it properly (lastElement is invalid after the following line) and pop it
m_sockets[entry] = std::move(m_sockets.back());
}
m_sockets.pop_back();
m_activeSockets.erase(socket);
m_allSockets.erase(socket);
m_readyToReadSockets.erase(socket);
m_readyToWriteSockets.erase(socket);
#else
FD_CLR(socket, &m_activeSockets);
FD_CLR(socket, &m_sockets);
FD_CLR(socket, &m_readSockets);
FD_CLR(socket, &m_readyToReadSockets);
FD_CLR(socket, &m_readyToWriteSockets);
FD_CLR(socket, &m_writeSockets);
#endif
}
@ -103,35 +134,28 @@ namespace Nz
int activeSockets;
#if NAZARA_NETWORK_POLL_SUPPORT
// Reset status of sockets
for (PollSocket& entry : m_sockets)
entry.revents = 0;
activeSockets = SocketImpl::Poll(m_sockets.data(), m_sockets.size(), static_cast<int>(msTimeout), error);
m_activeSockets.clear();
if (activeSockets > 0U)
{
int socketRemaining = activeSockets;
for (PollSocket& entry : m_sockets)
{
if (entry.revents & POLLRDNORM)
{
m_activeSockets.insert(entry.fd);
if (--socketRemaining == 0)
break;
}
}
}
#else
fd_set* readSet = nullptr;
fd_set* writeSet = nullptr;
m_activeSockets = m_sockets;
if (m_readSockets.fd_count > 0)
{
m_readyToReadSockets = m_readSockets;
readSet = &m_readyToReadSockets;
}
if (m_writeSockets.fd_count > 0)
{
m_readyToWriteSockets = m_writeSockets;
readSet = &m_readyToWriteSockets;
}
timeval tv;
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
tv.tv_usec = static_cast<long>((msTimeout % 1000ULL) * 1000ULL);
activeSockets = ::select(0xDEADBEEF, &m_activeSockets, nullptr, nullptr, (msTimeout > 0) ? &tv : nullptr); //< The first argument is ignored on Windows
activeSockets = ::select(0xDEADBEEF, readSet, writeSet, nullptr, (msTimeout > 0) ? &tv : nullptr); //< The first argument is ignored on Windows
if (activeSockets == SOCKET_ERROR)
{
if (error)

View File

@ -25,24 +25,28 @@ namespace Nz
void Clear();
bool IsReady(SocketHandle socket) const;
bool IsReadyToRead(SocketHandle socket) const;
bool IsReadyToWrite(SocketHandle socket) const;
bool IsRegistered(SocketHandle socket) const;
bool RegisterSocket(SocketHandle socket);
bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
private:
#if NAZARA_NETWORK_POLL_SUPPORT
std::unordered_set<SocketHandle> m_activeSockets;
std::unordered_set<SocketHandle> m_readyToReadSockets;
std::unordered_set<SocketHandle> m_readyToWriteSockets;
std::unordered_map<SocketHandle, std::size_t> m_allSockets;
std::vector<PollSocket> m_sockets;
#else
fd_set m_sockets;
fd_set m_activeSockets;
fd_set m_readSockets;
fd_set m_readyToReadSockets;
fd_set m_readyToWriteSockets;
fd_set m_writeSockets;
#endif
};
}
#endif // NAZARA_SOCKETPOLLERIMPL_HPP
#endif // NAZARA_SOCKETPOLLERIMPL_HPP

View File

@ -124,8 +124,8 @@ namespace Nz
// Some default settings
data.SetParameter(MaterialData::Blending, true);
data.SetParameter(MaterialData::DepthWrite, true);
data.SetParameter(MaterialData::DstBlend, static_cast<int>(BlendFunc_InvSrcAlpha));
data.SetParameter(MaterialData::SrcBlend, static_cast<int>(BlendFunc_SrcAlpha));
data.SetParameter(MaterialData::DstBlend, static_cast<long long>(BlendFunc_InvSrcAlpha));
data.SetParameter(MaterialData::SrcBlend, static_cast<long long>(BlendFunc_SrcAlpha));
}
it = materialCache.emplace(matName, std::move(data)).first;
@ -139,7 +139,7 @@ namespace Nz
bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
{
int reservedVertexCount;
long long reservedVertexCount;
if (!parameters.custom.GetIntegerParameter("NativeOBJLoader_VertexCount", &reservedVertexCount))
reservedVertexCount = 100;

View File

@ -128,7 +128,7 @@ namespace Nz
else
{
Color colorVal;
float fValue;
double dValue;
if (matData.GetColorParameter(MaterialData::AmbientColor, &colorVal))
material->ambient = colorVal;
@ -139,8 +139,8 @@ namespace Nz
if (matData.GetColorParameter(MaterialData::SpecularColor, &colorVal))
material->specular = colorVal;
if (matData.GetFloatParameter(MaterialData::Shininess, &fValue))
material->shininess = fValue;
if (matData.GetDoubleParameter(MaterialData::Shininess, &dValue))
material->shininess = float(dValue);
if (matData.GetStringParameter(MaterialData::AlphaTexturePath, &strVal))
material->alphaMap = strVal;
@ -176,7 +176,7 @@ namespace Nz
UInt32 faceIndex = 0;
TriangleIterator triangle(staticMesh);
do
do
{
OBJParser::Face& face = meshes[i].faces[faceIndex];
face.firstVertex = faceIndex * 3;

View File

@ -1268,6 +1268,102 @@ namespace Nz
}
}
bool PixelFormat::Flip(PixelFlipping flipping, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid(format))
{
NazaraError("Invalid pixel format");
return false;
}
#endif
auto it = s_flipFunctions[flipping].find(format);
if (it != s_flipFunctions[flipping].end())
it->second(width, height, depth, reinterpret_cast<const UInt8*>(src), reinterpret_cast<UInt8*>(dst));
else
{
// Flipping générique
#if NAZARA_UTILITY_SAFE
if (IsCompressed(format))
{
NazaraError("No function to flip compressed format");
return false;
}
#endif
UInt8 bpp = GetBytesPerPixel(format);
unsigned int lineStride = width*bpp;
switch (flipping)
{
case PixelFlipping_Horizontally:
{
if (src == dst)
{
for (unsigned int z = 0; z < depth; ++z)
{
UInt8* ptr = reinterpret_cast<UInt8*>(dst) + width*height*z;
for (unsigned int y = 0; y < height / 2; ++y)
std::swap_ranges(&ptr[y*lineStride], &ptr[(y + 1)*lineStride - 1], &ptr[(height - y - 1)*lineStride]);
}
}
else
{
for (unsigned int z = 0; z < depth; ++z)
{
const UInt8* srcPtr = reinterpret_cast<const UInt8*>(src);
UInt8* dstPtr = reinterpret_cast<UInt8*>(dst) + (width - 1)*height*depth*bpp;
for (unsigned int y = 0; y < height; ++y)
{
std::memcpy(dstPtr, srcPtr, lineStride);
srcPtr += lineStride;
dstPtr -= lineStride;
}
}
}
break;
}
case PixelFlipping_Vertically:
{
if (src == dst)
{
for (unsigned int z = 0; z < depth; ++z)
{
UInt8* ptr = reinterpret_cast<UInt8*>(dst) + width*height*z;
for (unsigned int y = 0; y < height; ++y)
{
for (unsigned int x = 0; x < width / 2; ++x)
std::swap_ranges(&ptr[x*bpp], &ptr[(x + 1)*bpp], &ptr[(width - x)*bpp]);
ptr += lineStride;
}
}
}
else
{
for (unsigned int z = 0; z < depth; ++z)
{
UInt8* ptr = reinterpret_cast<UInt8*>(dst) + width*height*z;
for (unsigned int y = 0; y < height; ++y)
{
for (unsigned int x = 0; x < width; ++x)
std::memcpy(&ptr[x*bpp], &ptr[(width - x)*bpp], bpp);
ptr += lineStride;
}
}
}
break;
}
}
}
return true;
}
PixelFormatType PixelFormat::IdentifyFormat(const PixelFormatInfo& info)
{
for (unsigned int i = 0; i <= PixelFormatType_Max; ++i)

View File

@ -24,13 +24,13 @@ SCENARIO("ParameterList", "[CORE][PARAMETERLIST]")
WHEN("We add Float '3.f'")
{
float fl = 3.f;
parameterList.SetParameter("float", fl);
double fl = 3.f;
parameterList.SetParameter("double", fl);
THEN("We can get it back")
{
float newFl;
REQUIRE(parameterList.GetFloatParameter("float", &newFl));
double newFl;
REQUIRE(parameterList.GetDoubleParameter("double", &newFl));
REQUIRE(newFl == fl);
}
}

View File

@ -27,7 +27,7 @@ SCENARIO("SocketPoller", "[NETWORK][SOCKETPOLLER]")
WHEN("We register the server socket to the poller")
{
REQUIRE(serverPoller.RegisterSocket(server));
REQUIRE(serverPoller.RegisterSocket(server, Nz::SocketPollEvent_Read));
THEN("The poller should have registered our socket")
{
@ -48,7 +48,7 @@ SCENARIO("SocketPoller", "[NETWORK][SOCKETPOLLER]")
WHEN("We register the client socket to the poller")
{
REQUIRE(serverPoller.RegisterSocket(serverToClient));
REQUIRE(serverPoller.RegisterSocket(serverToClient, Nz::SocketPollEvent_Read));
THEN("The poller should have registered our socket")
{
@ -65,7 +65,7 @@ SCENARIO("SocketPoller", "[NETWORK][SOCKETPOLLER]")
REQUIRE(serverPoller.Wait(1000));
CHECK(serverPoller.IsReady(serverToClient));
CHECK(serverPoller.IsReadyToRead(serverToClient));
CHECK(serverToClient.Read(buffer.data(), buffer.size()) == sent);
@ -73,7 +73,7 @@ SCENARIO("SocketPoller", "[NETWORK][SOCKETPOLLER]")
{
REQUIRE_FALSE(serverPoller.Wait(100));
REQUIRE_FALSE(serverPoller.IsReady(serverToClient));
REQUIRE_FALSE(serverPoller.IsReadyToRead(serverToClient));
}
}
}

View File

@ -11,7 +11,7 @@ SCENARIO("ListenerSystem", "[NDK][LISTENERSYSTEM]")
GIVEN("A world and an entity with listener & node components")
{
Ndk::World world;
const Ndk::EntityHandle& entity = world.CreateEntity();
Ndk::EntityHandle entity = world.CreateEntity();
Ndk::ListenerComponent& listenerComponent = entity->AddComponent<Ndk::ListenerComponent>();
Ndk::NodeComponent& nodeComponent = entity->AddComponent<Ndk::NodeComponent>();