lsnes rr2-β24
[lsnes.git] / src / lua / callback.cpp
blob878b38ca39d4937f6fcb2977bfa0874b0cdcef62
1 #include "lua/internal.hpp"
2 #include "library/minmax.hpp"
3 #include <stdexcept>
5 namespace
7 class lua_callbacks_list
9 public:
10 lua_callbacks_list(lua::state& L);
11 static size_t overcommit() { return 0; }
12 static int create(lua::state& L, lua::parameters& P);
13 int index(lua::state& L, lua::parameters& P);
14 int newindex(lua::state& L, lua::parameters& P);
17 class lua_callback_obj
19 public:
20 lua_callback_obj(lua::state& L, const std::string& name);
21 static size_t overcommit(const std::string& name) { return 0; }
22 int _register(lua::state& L, lua::parameters& P);
23 int _unregister(lua::state& L, lua::parameters& P);
24 int _call(lua::state& L, lua::parameters& P);
25 std::string print()
27 if(special == 1)
28 return "global register";
29 else if(special == 2)
30 return "global unregister";
31 else if(callback)
32 return callback->get_name();
33 else
34 return "(null)";
36 private:
37 lua::state::callback_list* callback;
38 int special;
41 lua::_class<lua_callbacks_list> LUA_class_callbacks_list(lua_class_callback, "CALLBACKS_LIST", {
42 {"new", lua_callbacks_list::create},
43 }, {
44 {"__index", &lua_callbacks_list::index},
45 {"__newindex", &lua_callbacks_list::newindex},
46 });
47 lua::_class<lua_callback_obj> LUA_class_callback_obj(lua_class_callback, "CALLBACK_OBJ", {}, {
48 {"register", &lua_callback_obj::_register},
49 {"unregister", &lua_callback_obj::_unregister},
50 {"__call", &lua_callback_obj::_call},
51 }, &lua_callback_obj::print);
53 lua_callbacks_list::lua_callbacks_list(lua::state& L)
57 int lua_callbacks_list::create(lua::state& L, lua::parameters& P)
59 lua::_class<lua_callbacks_list>::create(L);
60 return 1;
63 int lua_callbacks_list::index(lua::state& L, lua::parameters& P)
65 std::string name;
67 P(P.skipped(), name);
69 lua::_class<lua_callback_obj>::create(L, name);
70 return 1;
73 int lua_callbacks_list::newindex(lua::state& L, lua::parameters& P)
75 throw std::runtime_error("Writing is not allowed");
78 lua_callback_obj::lua_callback_obj(lua::state& L, const std::string& name)
80 callback = NULL;
81 special = 0;
82 for(auto i : L.get_callbacks())
83 if(i->get_name() == name)
84 callback = i;
85 if(name == "register") {
86 special = 1;
87 return;
89 if(name == "unregister") {
90 special = 2;
91 return;
93 if(!callback && !special)
94 throw std::runtime_error("Unknown callback type '" + name + "' for callback.<foo>");
97 int lua_callback_obj::_register(lua::state& L, lua::parameters& P)
99 int lfn;
101 if(!callback) throw std::runtime_error(P.get_fname() + ": not valid");
103 P(P.skipped(), P.function(lfn));
105 L.pushvalue(lfn);
106 callback->_register(L);
107 L.pop(1);
108 L.pushvalue(lfn);
109 return 1;
112 int lua_callback_obj::_unregister(lua::state& L, lua::parameters& P)
114 int lfn;
116 if(!callback) throw std::runtime_error(P.get_fname() + ": not valid");
118 P(P.skipped(), P.function(lfn));
120 L.pushvalue(lfn);
121 callback->_unregister(L);
122 L.pop(1);
123 L.pushvalue(lfn);
124 return 1;
127 int lua_callback_obj::_call(lua::state& L, lua::parameters& P)
129 std::string name;
130 int lfn;
132 if(!special) throw std::runtime_error("Need to specify operation to do to callback");
134 P(P.skipped(), name, P.function(lfn));
136 bool any = false;
137 for(auto i : L.get_callbacks()) {
138 if(i->get_name() == name) {
139 L.pushvalue(lfn);
140 if(special == 1)
141 i->_register(L);
142 else if(special == 2)
143 i->_unregister(L);
144 L.pop(1);
145 any = true;
148 if(!any)
149 throw std::runtime_error("Unknown callback type '" + name + "' for callback.register");
150 L.pushvalue(lfn);
151 return 1;