diff options
author | 2020-12-11 21:06:38 -0500 | |
---|---|---|
committer | 2020-12-12 13:06:38 +1100 | |
commit | 94421d749c0ed99536faff498b8d77698d17ee92 (patch) | |
tree | 1b4281793c38a1ce989d58e50b4576d31df1a3aa /src/frontend/mame/luaengine.cpp | |
parent | 7f22d342658bbde72184c12caa8a62bd28ba4ed4 (diff) |
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
Diffstat (limited to 'src/frontend/mame/luaengine.cpp')
-rw-r--r-- | src/frontend/mame/luaengine.cpp | 106 |
1 files changed, 106 insertions, 0 deletions
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 <typename T> +struct lua_engine::object_ptr_vector_wrapper +{ + object_ptr_vector_wrapper(std::vector<std::unique_ptr<T>> const &v) : vec(v) { } + + std::vector<std::unique_ptr<T>> const &vec; +}; + + namespace sol { @@ -171,6 +180,78 @@ public: static int ipairs(lua_State *L) { return start_pairs<true>(L); } }; + +template <typename T> +struct usertype_container<lua_engine::object_ptr_vector_wrapper<T> > : lua_engine::immutable_container_helper<lua_engine::object_ptr_vector_wrapper<T>, std::vector<std::unique_ptr<T>> const, typename std::vector<std::unique_ptr<T>>::const_iterator> +{ +private: + static int next_pairs(lua_State *L) + { + typename usertype_container::indexed_iterator &i(stack::unqualified_get<user<typename usertype_container::indexed_iterator> >(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<T> &self(usertype_container::get_self(L)); + std::ptrdiff_t const index(stack::unqualified_get<std::ptrdiff_t>(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<T> &self(usertype_container::get_self(L)); + T &target(stack::unqualified_get<T>(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<T> &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<T> &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<T> &self(usertype_container::get_self(L)); + stack::push(L, next_pairs); + stack::push<user<typename usertype_container::indexed_iterator> >(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<device_image_interface>("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_device_format>(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_device_format>("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 |