Actually call on_reset callback
[lsnes.git] / include / library / lua-pin.hpp
blobc36451c9897a9443ceb4cbb24b7e7e247577a9ab
1 #ifndef _library__lua_pin__hpp__included__
2 #define _library__lua_pin__hpp__included__
4 #include "lua-base.hpp"
6 namespace lua
8 /**
9 * Pin of an object against Lua GC.
11 template<typename T> struct objpin
13 /**
14 * Create a null pin.
16 objpin()
18 _state = NULL;
19 obj = NULL;
21 /**
22 * Create a new pin.
24 * Parameter _state: The state to pin the object in.
25 * Parameter _object: The object to pin.
27 objpin(state& lstate, T* _object)
28 : _state(&lstate.get_master())
30 _state->pushlightuserdata(this);
31 _state->pushvalue(-2);
32 _state->rawset(LUA_REGISTRYINDEX);
33 obj = _object;
35 /**
36 * Delete a pin.
38 ~objpin() throw()
40 if(obj) {
41 _state->pushlightuserdata(this);
42 _state->pushnil();
43 _state->rawset(LUA_REGISTRYINDEX);
46 /**
47 * Copy ctor.
49 objpin(const objpin& p)
51 _state = p._state;
52 obj = p.obj;
53 if(obj) {
54 _state->pushlightuserdata(this);
55 _state->pushlightuserdata(const_cast<objpin*>(&p));
56 _state->rawget(LUA_REGISTRYINDEX);
57 _state->rawset(LUA_REGISTRYINDEX);
60 /**
61 * Assignment operator.
63 objpin& operator=(const objpin& p)
65 if(_state == p._state && obj == p.obj)
66 return *this;
67 if(obj == p.obj)
68 throw std::logic_error("A Lua object can't be in two lua states at once");
69 if(obj) {
70 _state->pushlightuserdata(this);
71 _state->pushnil();
72 _state->rawset(LUA_REGISTRYINDEX);
74 _state = p._state;
75 if(p.obj) {
76 _state->pushlightuserdata(this);
77 _state->pushlightuserdata(const_cast<objpin*>(&p));
78 _state->rawget(LUA_REGISTRYINDEX);
79 _state->rawset(LUA_REGISTRYINDEX);
81 obj = p.obj;
82 return *this;
84 /**
85 * Clear a pinned object.
87 void clear()
89 if(obj) {
90 _state->pushlightuserdata(this);
91 _state->pushnil();
92 _state->rawset(LUA_REGISTRYINDEX);
94 _state = NULL;
95 obj = NULL;
97 /**
98 * Get pointer to pinned object.
100 * Returns: The pinned object.
102 T* object() { return obj; }
104 * Is non-null?
106 operator bool() { return obj != NULL; }
108 * Smart pointer.
110 T& operator*() { if(obj) return *obj; throw std::runtime_error("Attempted to reference NULL Lua pin"); }
111 T* operator->() { if(obj) return obj; throw std::runtime_error("Attempted to reference NULL Lua pin"); }
113 * Push Lua value.
115 void luapush(state& lstate)
117 lstate.pushlightuserdata(this);
118 lstate.rawget(LUA_REGISTRYINDEX);
120 private:
121 T* obj;
122 state* _state;
125 template<typename T> void* unbox_any_pin(struct objpin<T>* pin)
127 return pin ? pin->object() : NULL;
132 #endif