94114f1e2e
- Split lua-base.hpp into number of files. - New Lua function parameters parser. - Convert some Lua code files in order to test the stuff
132 lines
2.4 KiB
C++
132 lines
2.4 KiB
C++
#ifndef _library__lua_pin__hpp__included__
|
|
#define _library__lua_pin__hpp__included__
|
|
|
|
#include "lua-base.hpp"
|
|
|
|
namespace lua
|
|
{
|
|
/**
|
|
* Pin of an object against Lua GC.
|
|
*/
|
|
template<typename T> struct objpin
|
|
{
|
|
/**
|
|
* Create a null pin.
|
|
*/
|
|
objpin()
|
|
{
|
|
_state = NULL;
|
|
obj = NULL;
|
|
}
|
|
/**
|
|
* Create a new pin.
|
|
*
|
|
* Parameter _state: The state to pin the object in.
|
|
* Parameter _object: The object to pin.
|
|
*/
|
|
objpin(state& lstate, T* _object)
|
|
: _state(&lstate.get_master())
|
|
{
|
|
_state->pushlightuserdata(this);
|
|
_state->pushvalue(-2);
|
|
_state->rawset(LUA_REGISTRYINDEX);
|
|
obj = _object;
|
|
}
|
|
/**
|
|
* Delete a pin.
|
|
*/
|
|
~objpin() throw()
|
|
{
|
|
if(obj) {
|
|
_state->pushlightuserdata(this);
|
|
_state->pushnil();
|
|
_state->rawset(LUA_REGISTRYINDEX);
|
|
}
|
|
}
|
|
/**
|
|
* Copy ctor.
|
|
*/
|
|
objpin(const objpin& p)
|
|
{
|
|
_state = p._state;
|
|
obj = p.obj;
|
|
if(obj) {
|
|
_state->pushlightuserdata(this);
|
|
_state->pushlightuserdata(const_cast<objpin*>(&p));
|
|
_state->rawget(LUA_REGISTRYINDEX);
|
|
_state->rawset(LUA_REGISTRYINDEX);
|
|
}
|
|
}
|
|
/**
|
|
* Assignment operator.
|
|
*/
|
|
objpin& operator=(const objpin& p)
|
|
{
|
|
if(_state == p._state && obj == p.obj)
|
|
return *this;
|
|
if(obj == p.obj)
|
|
throw std::logic_error("A Lua object can't be in two lua states at once");
|
|
if(obj) {
|
|
_state->pushlightuserdata(this);
|
|
_state->pushnil();
|
|
_state->rawset(LUA_REGISTRYINDEX);
|
|
}
|
|
_state = p._state;
|
|
if(p.obj) {
|
|
_state->pushlightuserdata(this);
|
|
_state->pushlightuserdata(const_cast<objpin*>(&p));
|
|
_state->rawget(LUA_REGISTRYINDEX);
|
|
_state->rawset(LUA_REGISTRYINDEX);
|
|
}
|
|
obj = p.obj;
|
|
return *this;
|
|
}
|
|
/**
|
|
* Clear a pinned object.
|
|
*/
|
|
void clear()
|
|
{
|
|
if(obj) {
|
|
_state->pushlightuserdata(this);
|
|
_state->pushnil();
|
|
_state->rawset(LUA_REGISTRYINDEX);
|
|
}
|
|
_state = NULL;
|
|
obj = NULL;
|
|
}
|
|
/**
|
|
* Get pointer to pinned object.
|
|
*
|
|
* Returns: The pinned object.
|
|
*/
|
|
T* object() { return obj; }
|
|
/**
|
|
* Is non-null?
|
|
*/
|
|
operator bool() { return obj != NULL; }
|
|
/**
|
|
* Smart pointer.
|
|
*/
|
|
T& operator*() { if(obj) return *obj; throw std::runtime_error("Attempted to reference NULL Lua pin"); }
|
|
T* operator->() { if(obj) return obj; throw std::runtime_error("Attempted to reference NULL Lua pin"); }
|
|
/**
|
|
* Push Lua value.
|
|
*/
|
|
void luapush(state& lstate)
|
|
{
|
|
lstate.pushlightuserdata(this);
|
|
lstate.rawget(LUA_REGISTRYINDEX);
|
|
}
|
|
private:
|
|
T* obj;
|
|
state* _state;
|
|
};
|
|
|
|
template<typename T> void* unbox_any_pin(struct objpin<T>* pin)
|
|
{
|
|
return pin ? pin->object() : NULL;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|