Lua: Pass name of method to various lua class methods

This commit is contained in:
Ilari Liusvaara 2013-08-22 22:34:17 +03:00
parent 1909357f99
commit 6a0f9750b2
7 changed files with 96 additions and 106 deletions

View file

@ -616,7 +616,7 @@ template<class T> struct lua_class_bind_data
/**
* The pointer to call.
*/
int (T::*fn)(lua_state& state);
int (T::*fn)(lua_state& state, const std::string& _fname);
/**
* The state to call it in.
*/
@ -643,7 +643,7 @@ template<class T> struct lua_class_binding
/**
* Function.
*/
int (T::*fn)(lua_state& LS);
int (T::*fn)(lua_state& LS, const std::string& fname);
};
/**
@ -667,7 +667,7 @@ template<class T> class lua_class
lua_class_bind_data<T>* b = (lua_class_bind_data<T>*)lua_touserdata(LS, lua_upvalueindex(1));
lua_state L(*b->state, LS);
T* p = lua_class<T>::get(L, 1, b->fname);
return (p->*(b->fn))(L);
return (p->*(b->fn))(L, b->fname);
} catch(std::exception& e) {
std::string err = e.what();
lua_pushlstring(LS, err.c_str(), err.length());
@ -745,16 +745,17 @@ public:
* Parameter fn: The method to call.
* Parameter force: If true, overwrite existing method.
*/
void bind(lua_state& state, const char* keyname, int (T::*fn)(lua_state& LS))
void bind(lua_state& state, const char* keyname, int (T::*fn)(lua_state& LS, const std::string& fname))
{
load_metatable(state);
state.pushstring(keyname);
std::string fname = std::string("Method ") + keyname;
std::string fname = name + std::string("::") + keyname;
void* ptr = state.newuserdata(sizeof(lua_class_bind_data<T>) + fname.length() + 1);
lua_class_bind_data<T>* bdata = reinterpret_cast<lua_class_bind_data<T>*>(ptr);
bdata->fn = fn;
bdata->state = &state.get_master();
std::copy(fname.begin(), fname.end(), bdata->fname);
bdata->fname[fname.length()] = 0;
state.pushcclosure(class_bind_trampoline, 1);
state.rawset(-3);
state.pop(1);

View file

@ -8,17 +8,17 @@ namespace
{
public:
lua_callbacks_list(lua_state& L);
int index(lua_state& L);
int newindex(lua_state& L);
int index(lua_state& L, const std::string& fname);
int newindex(lua_state& L, const std::string& fname);
};
class lua_callback_obj
{
public:
lua_callback_obj(lua_state& L, const std::string& name);
int _register(lua_state& L);
int _unregister(lua_state& L);
int _call(lua_state& L);
int _register(lua_state& L, const std::string& fname);
int _unregister(lua_state& L, const std::string& fname);
int _call(lua_state& L, const std::string& fname);
private:
lua_state::lua_callback_list* callback;
int special;
@ -38,14 +38,14 @@ namespace
});
}
int lua_callbacks_list::index(lua_state& L)
int lua_callbacks_list::index(lua_state& L, const std::string& fname)
{
std::string name = L.get_string(2, "CALLBACKS_LIST::__index");
std::string name = L.get_string(2, fname.c_str());
lua_class<lua_callback_obj>::create(L, name);
return 1;
}
int lua_callbacks_list::newindex(lua_state& L)
int lua_callbacks_list::newindex(lua_state& L, const std::string& fname)
{
throw std::runtime_error("Writing is not allowed");
}
@ -74,7 +74,7 @@ namespace
throw std::runtime_error("Unknown callback type '" + name + "' for callback.<foo>");
}
int lua_callback_obj::_register(lua_state& L)
int lua_callback_obj::_register(lua_state& L, const std::string& fname)
{
if(!callback)
throw std::runtime_error("callback.{,un}register.register not valid");
@ -87,7 +87,7 @@ namespace
return 1;
}
int lua_callback_obj::_unregister(lua_state& L)
int lua_callback_obj::_unregister(lua_state& L, const std::string& fname)
{
if(!callback)
throw std::runtime_error("callback.{,un}register.unregister not valid");
@ -100,7 +100,7 @@ namespace
return 1;
}
int lua_callback_obj::_call(lua_state& L)
int lua_callback_obj::_call(lua_state& L, const std::string& fname)
{
if(!special)
throw std::runtime_error("Need to specify operation to do to callback");

View file

@ -14,7 +14,7 @@ namespace
public:
lua_customfont(lua_state& L, const std::string& filename);
~lua_customfont() throw();
int draw(lua_state& L);
int draw(lua_state& L, const std::string& fname);
const custom_font& get_font() { return font; }
private:
custom_font font;
@ -98,9 +98,8 @@ namespace
render_kill_request(this);
}
int lua_customfont::draw(lua_state& L)
int lua_customfont::draw(lua_state& L, const std::string& fname)
{
std::string fname = "CUSTOMFONT::__call";
if(!lua_render_ctx)
return 0;
int64_t fgc = 0xFFFFFFU;

View file

@ -16,54 +16,54 @@ namespace
friend class lua_inputmovie;
public:
lua_inputframe(lua_state& L, controller_frame _f);
int get_button(lua_state& L)
int get_button(lua_state& L, const std::string& fname)
{
unsigned port = L.get_numeric_argument<unsigned>(2, "INPUTFRAME::get_button");
unsigned controller = L.get_numeric_argument<unsigned>(3, "INPUTFRAME::get_button");
unsigned button = L.get_numeric_argument<unsigned>(4, "INPUTFRAME::get_button");
unsigned port = L.get_numeric_argument<unsigned>(2, fname.c_str());
unsigned controller = L.get_numeric_argument<unsigned>(3, fname.c_str());
unsigned button = L.get_numeric_argument<unsigned>(4, fname.c_str());
short value = getbutton(port, controller, button);
L.pushboolean(value ? 1 : 0);
return 1;
}
int get_axis(lua_state& L)
int get_axis(lua_state& L, const std::string& fname)
{
unsigned port = L.get_numeric_argument<unsigned>(2, "INPUTFRAME::get_axis");
unsigned controller = L.get_numeric_argument<unsigned>(3, "INPUTFRAME::get_axis");
unsigned button = L.get_numeric_argument<unsigned>(4, "INPUTFRAME::get_axis");
unsigned port = L.get_numeric_argument<unsigned>(2, fname.c_str());
unsigned controller = L.get_numeric_argument<unsigned>(3, fname.c_str());
unsigned button = L.get_numeric_argument<unsigned>(4, fname.c_str());
short value = getbutton(port, controller, button);
L.pushnumber(value);
return 1;
}
int set_axis(lua_state& L)
int set_axis(lua_state& L, const std::string& fname)
{
unsigned port = L.get_numeric_argument<unsigned>(2, "INPUTFRAME::set_axis");
unsigned controller = L.get_numeric_argument<unsigned>(3, "INPUTFRAME::set_axis");
unsigned button = L.get_numeric_argument<unsigned>(4, "INPUTFRAME::set_axis");
unsigned port = L.get_numeric_argument<unsigned>(2, fname.c_str());
unsigned controller = L.get_numeric_argument<unsigned>(3, fname.c_str());
unsigned button = L.get_numeric_argument<unsigned>(4, fname.c_str());
short value;
if(L.type(5) == LUA_TBOOLEAN)
value = L.toboolean(5);
else if(L.type(5) == LUA_TNUMBER)
value = L.get_numeric_argument<short>(5, "INPUTFRAME::set_axis");
value = L.get_numeric_argument<short>(5, fname.c_str());
else
(stringfmt() << "Expected argument 5 of INPUTFRAME::set_axis to be boolean or "
(stringfmt() << "Expected argument 5 of " << fname << " to be boolean or "
<< "number").throwex();
setbutton(port, controller, button, value);
return 0;
}
int serialize(lua_state& L)
int serialize(lua_state& L, const std::string& fname)
{
char buf[MAX_SERIALIZED_SIZE];
f.serialize(buf);
L.pushstring(buf);
return 1;
}
int unserialize(lua_state& L)
int unserialize(lua_state& L, const std::string& fname)
{
std::string buf = L.get_string(2, "INPUTFRAME::unserialize");
std::string buf = L.get_string(2, fname.c_str());
f.deserialize(buf.c_str());
return 0;
}
int get_stride(lua_state& L)
int get_stride(lua_state& L, const std::string& fname)
{
L.pushnumber(f.size());
return 1;
@ -412,59 +412,59 @@ namespace
public:
lua_inputmovie(lua_state& L, const controller_frame_vector& _v);
lua_inputmovie(lua_state& L, controller_frame& _f);
int copy_movie(lua_state& L)
int copy_movie(lua_state& L, const std::string& fname)
{
return _copy_movie(L, "INPUTMOVIE::copy_movie");
return _copy_movie(L, fname.c_str());
}
int get_frame(lua_state& L)
int get_frame(lua_state& L, const std::string& fname)
{
return _get_frame(L, "INPUTMOVIE::get_frame");
return _get_frame(L, fname.c_str());
}
int set_frame(lua_state& L)
int set_frame(lua_state& L, const std::string& fname)
{
return _set_frame(L, "INPUTMOVIE::set_frame");
return _set_frame(L, fname.c_str());
}
int get_size(lua_state& L)
int get_size(lua_state& L, const std::string& fname)
{
return _get_size(L, "INPUTMOVIE::get_size");
return _get_size(L, fname.c_str());
}
int count_frames(lua_state& L)
int count_frames(lua_state& L, const std::string& fname)
{
return _count_frames(L, "INPUTMOVIE::count_frames");
return _count_frames(L, fname.c_str());
}
int find_frame(lua_state& L)
int find_frame(lua_state& L, const std::string& fname)
{
return _find_frame(L, "INPUTMOVIE::find_frame");
return _find_frame(L, fname.c_str());
}
int blank_frame(lua_state& L)
int blank_frame(lua_state& L, const std::string& fname)
{
return _blank_frame(L, "INPUTMOVIE::blank_frame");
return _blank_frame(L, fname.c_str());
}
int append_frames(lua_state& L)
int append_frames(lua_state& L, const std::string& fname)
{
return _append_frames(L, "INPUTMOVIE::append_frames");
return _append_frames(L, fname.c_str());
}
int append_frame(lua_state& L)
int append_frame(lua_state& L, const std::string& fname)
{
return _append_frame(L, "INPUTMOVIE::append_frame");
return _append_frame(L, fname.c_str());
}
int truncate(lua_state& L)
int truncate(lua_state& L, const std::string& fname)
{
return _truncate(L, "INPUTMOVIE::truncate");
return _truncate(L, fname.c_str());
}
int edit(lua_state& L)
int edit(lua_state& L, const std::string& fname)
{
return _edit(L, "INPUTMOVIE::edit");
return _edit(L, fname.c_str());
}
int copy_frames(lua_state& L)
int copy_frames(lua_state& L, const std::string& fname)
{
return _copy_frames<true>(L, "INPUTMOVIE::copy_frames");
return _copy_frames<true>(L, fname.c_str());
}
int serialize(lua_state& L)
int serialize(lua_state& L, const std::string& fname)
{
return _serialize(L, "INPUTMOVIE::serialize");
return _serialize(L, fname.c_str());
}
int debugdump(lua_state& L)
int debugdump(lua_state& L, const std::string& fname)
{
char buf[MAX_SERIALIZED_SIZE];
for(uint64_t i = 0; i < v.size(); i++) {

View file

@ -154,11 +154,11 @@ namespace
{
delete &s;
}
int read(lua_state& L)
int read(lua_state& L, const std::string& fname)
{
if(L.type(2) == LUA_TNUMBER) {
//Read specified number of bytes.
size_t sz = L.get_numeric_argument<size_t>(2, "FILEREADER::read");
size_t sz = L.get_numeric_argument<size_t>(2, fname.c_str());
std::vector<char> buf;
buf.resize(sz);
s.read(&buf[0], sz);
@ -180,10 +180,9 @@ namespace
L.pushlstring(tmp);
return 1;
} else
throw std::runtime_error("Expected number or nil as the 2nd argument of "
"FILEREADER::read");
(stringfmt() << "Expected number or nil as the 2nd argument of " << fname).throwex();
}
int lines(lua_state& L)
int lines(lua_state& L, const std::string& fname)
{
L.pushlightuserdata(this);
L.pushcclosure(lua_file_reader::lines_helper2, 1);

View file

@ -94,7 +94,7 @@ public:
{
}
int index(lua_state& L)
int index(lua_state& L, const std::string& fname)
{
const char* c = L.tostring(2);
if(!c) {
@ -110,7 +110,7 @@ public:
x.first->read(L, x.second);
return 1;
}
int newindex(lua_state& L)
int newindex(lua_state& L, const std::string& fname)
{
const char* c = L.tostring(2);
if(!c)
@ -123,7 +123,7 @@ public:
return 0;
}
int map(lua_state& L);
int map(lua_state& L, const std::string& fname);
private:
std::map<std::string, std::pair<mmap_base*, uint64_t>> mappings;
};
@ -423,27 +423,21 @@ namespace
}
int lua_mmap_struct::map(lua_state& L)
int lua_mmap_struct::map(lua_state& L, const std::string& fname)
{
const char* name = L.tostring(2);
int base = 0;
uint64_t vmabase = 0;
if(L.type(3) == LUA_TSTRING) {
vmabase = get_vmabase(L, L.get_string(3, "lua_mmap_struct::map"));
vmabase = get_vmabase(L, L.get_string(3, fname.c_str()));
base = 1;
}
uint64_t addr = L.get_numeric_argument<uint64_t>(base + 3, "lua_mmap_struct::map");
uint64_t addr = L.get_numeric_argument<uint64_t>(base + 3, fname.c_str());
const char* type = L.tostring(base + 4);
if(!name) {
L.pushstring("lua_mmap_struct::map: Bad name");
L.error();
return 0;
}
if(!type) {
L.pushstring("lua_mmap_struct::map: Bad type");
L.error();
return 0;
}
if(!name)
(stringfmt() << fname << ": Bad name").throwex();
if(!type)
(stringfmt() << fname << ": Bad type").throwex();
std::string name2(name);
std::string type2(type);
if(type2 == "byte")
@ -462,11 +456,8 @@ int lua_mmap_struct::map(lua_state& L)
mappings[name2] = std::make_pair(&mhuq, addr);
else if(type2 == "sqword")
mappings[name2] = std::make_pair(&mhsq, addr);
else {
L.pushstring("lua_mmap_struct::map: Bad type");
L.error();
return 0;
}
else
(stringfmt() << fname << ": Bad type").throwex();
return 0;
}

View file

@ -51,8 +51,8 @@ namespace
{
public:
lua_vma(lua_state& L, memory_region* r);
int info(lua_state& L);
template<class T, bool _bswap> int rw(lua_state& L);
int info(lua_state& L, const std::string& fname);
template<class T, bool _bswap> int rw(lua_state& L, const std::string& fname);
private:
std::string vma;
uint64_t vmabase;
@ -64,9 +64,9 @@ namespace
{
public:
lua_vma_list(lua_state& L);
int index(lua_state& L);
int newindex(lua_state& L);
int call(lua_state& L);
int index(lua_state& L, const std::string& fname);
int newindex(lua_state& L, const std::string& fname);
int call(lua_state& L, const std::string& fname);
};
}
@ -102,17 +102,17 @@ namespace
ro = r->readonly;
}
int lua_vma::info(lua_state& L)
int lua_vma::info(lua_state& L, const std::string& fname)
{
for(auto i : lsnes_memory.get_regions())
if(i->name == vma)
return handle_push_vma(L, *i);
throw std::runtime_error("VMA::info: Stale region");
(stringfmt() << fname << ": Stale region").throwex();
}
template<class T, bool _bswap> int lua_vma::rw(lua_state& L)
template<class T, bool _bswap> int lua_vma::rw(lua_state& L, const std::string& fname)
{
uint64_t addr = L.get_numeric_argument<uint64_t>(2, "VMA::rw<T>");
uint64_t addr = L.get_numeric_argument<uint64_t>(2, fname.c_str());
if(addr > vmasize || addr > vmasize - sizeof(T))
throw std::runtime_error("VMA::rw<T>: Address outside VMA bounds");
if(L.type(3) == LUA_TNIL || L.type(3) == LUA_TNONE) {
@ -124,13 +124,13 @@ namespace
} else if(L.type(3) == LUA_TNUMBER) {
//Write.
if(ro)
throw std::runtime_error("VMA::rw<T>: VMA is read-only");
(stringfmt() << fname << ": VMA is read-only").throwex();
T val = L.get_numeric_argument<T>(3, "VMA::rw<T>");
if(_bswap) val = bswap(val);
lsnes_memory.write<T>(addr + vmabase, val);
return 0;
} else
throw std::runtime_error("VMA::rw<T>: Parameter #3 must be integer if present");
(stringfmt() << fname << ": Parameter #3 must be integer if present").throwex();
}
lua_vma_list::lua_vma_list(lua_state& L)
@ -142,7 +142,7 @@ namespace
});
}
int lua_vma_list::call(lua_state& L)
int lua_vma_list::call(lua_state& L, const std::string& fname)
{
L.newtable();
size_t key = 1;
@ -154,9 +154,9 @@ namespace
return 1;
}
int lua_vma_list::index(lua_state& L)
int lua_vma_list::index(lua_state& L, const std::string& fname)
{
std::string vma = L.get_string(2, "VMALIST::__index");
std::string vma = L.get_string(2, fname.c_str());
auto l = lsnes_memory.get_regions();
size_t j;
std::list<memory_region*>::iterator i;
@ -165,10 +165,10 @@ namespace
lua_class<lua_vma>::create(L, *i);
return 1;
}
throw std::runtime_error("VMALIST::__index: No such VMA");
(stringfmt() << fname << ": No such VMA").throwex();
}
int lua_vma_list::newindex(lua_state& L)
int lua_vma_list::newindex(lua_state& L, const std::string& fname)
{
throw std::runtime_error("Writing is not allowed");
}