From 94421d749c0ed99536faff498b8d77698d17ee92 Mon Sep 17 00:00:00 2001 From: npwoods Date: Fri, 11 Dec 2020 21:06:38 -0500 Subject: Exposing image format information to LUA (#7508) * Exposing image format information to LUA * crazyc feedback * Addressing what I expect would become Vas feedback * Vas feedback, minus making image formats a container wrapper * Changed image formats to have a proper container wrapper. Now indexed by an integer index --- src/frontend/mame/luaengine.cpp | 106 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'src/frontend/mame/luaengine.cpp') diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index da7a6e9ea41..488bd2bc571 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -55,6 +55,15 @@ struct lua_engine::devenum }; +template +struct lua_engine::object_ptr_vector_wrapper +{ + object_ptr_vector_wrapper(std::vector> const &v) : vec(v) { } + + std::vector> const &vec; +}; + + namespace sol { @@ -171,6 +180,78 @@ public: static int ipairs(lua_State *L) { return start_pairs(L); } }; + +template +struct usertype_container > : lua_engine::immutable_container_helper, std::vector> const, typename std::vector>::const_iterator> +{ +private: + static int next_pairs(lua_State *L) + { + typename usertype_container::indexed_iterator &i(stack::unqualified_get >(L, 1)); + if (i.src.end() == i.it) + return stack::push(L, lua_nil); + int result; + result = stack::push(L, i.ix + 1); + result += stack::push_reference(L, i.it->get()); + ++i; + return result; + } + +public: + static int at(lua_State *L) + { + lua_engine::object_ptr_vector_wrapper &self(usertype_container::get_self(L)); + std::ptrdiff_t const index(stack::unqualified_get(L, 2)); + if ((0 >= index) || (self.vec.size() < index)) + return stack::push(L, lua_nil); + return stack::push_reference(L, self.vec[index - 1].get()); + } + + static int get(lua_State *L) { return at(L); } + static int index_get(lua_State *L) { return at(L); } + + static int index_of(lua_State *L) + { + lua_engine::object_ptr_vector_wrapper &self(usertype_container::get_self(L)); + T &target(stack::unqualified_get(L, 2)); + auto it(self.vec.begin()); + std::ptrdiff_t ix(0); + while ((self.vec.end() != it) && (it->get() != &target)) + { + ++it; + ++ix; + } + if (self.vec.end() == it) + return stack::push(L, lua_nil); + else + return stack::push(L, ix + 1); + } + + static int size(lua_State *L) + { + lua_engine::object_ptr_vector_wrapper &self(usertype_container::get_self(L)); + return stack::push(L, self.vec.size()); + } + + static int empty(lua_State *L) + { + lua_engine::object_ptr_vector_wrapper &self(usertype_container::get_self(L)); + return stack::push(L, self.vec.empty()); + } + + static int next(lua_State *L) { return stack::push(L, next_pairs); } + static int pairs(lua_State *L) { return ipairs(L); } + + static int ipairs(lua_State *L) + { + lua_engine::object_ptr_vector_wrapper &self(usertype_container::get_self(L)); + stack::push(L, next_pairs); + stack::push >(L, self.vec, self.vec.begin()); + stack::push(L, lua_nil); + return 3; + } +}; + } // namespace sol @@ -1787,6 +1868,7 @@ void lua_engine::initialize() * image.is_creatable * image.is_reset_on_load * image.must_be_loaded + * image.formatlist */ auto image_type = sol().registry().new_usertype("image", "new", sol::no_constructor); @@ -1815,6 +1897,30 @@ void lua_engine::initialize() image_type.set("is_creatable", sol::property(&device_image_interface::is_creatable)); image_type.set("is_reset_on_load", sol::property(&device_image_interface::is_reset_on_load)); image_type.set("must_be_loaded", sol::property(&device_image_interface::must_be_loaded)); + image_type.set("formatlist", sol::property([](const device_image_interface &image) { return object_ptr_vector_wrapper(image.formatlist()); })); + + +/* image_device_format library + * + * manager:machine().images[tag].formatlist[index] + * + * format.name - name of the format (e.g. - "dsk") + * format.description - the description of the format + * format.extensions - all of the extensions, as an array + * format.optspec - the option spec associated with the format + * + */ + auto format_type = sol().registry().new_usertype("image_format", sol::no_constructor); + format_type["name"] = sol::property(&image_device_format::name); + format_type["description"] = sol::property(&image_device_format::description); + format_type["optspec"] = sol::property(&image_device_format::optspec); + format_type["extensions"] = sol::property([this](const image_device_format &format) { + int index = 1; + sol::table option_table = sol().create_table(); + for (const std::string &ext : format.extensions()) + option_table[index++] = ext; + return option_table; + }); /* device_slot_interface library -- cgit v1.2.3-70-g09d2