// license:BSD-3-Clause // copyright-holders:Miodrag Milanovic /*************************************************************************** luaengine.h Controls execution of the core MAME system. ***************************************************************************/ #ifndef MAME_FRONTEND_MAME_LUAENGINE_H #define MAME_FRONTEND_MAME_LUAENGINE_H #pragma once #ifndef __EMU_H__ #error Dont include this file directly; include emu.h instead. #endif #if defined(__GNUC__) && (__GNUC__ > 6) #pragma GCC diagnostic ignored "-Wnoexcept-type" #endif #include #include #define SOL_SAFE_USERTYPE //#define SOL_CHECK_ARGUMENTS #include "sol2/sol.hpp" struct lua_State; class lua_engine { public: // construction/destruction lua_engine(); ~lua_engine(); void initialize(); void load_script(const char *filename); void load_string(const char *value); bool frame_hook(); void menu_populate(const std::string &menu, std::vector> &menu_list); bool menu_callback(const std::string &menu, int index, const std::string &event); void set_machine(running_machine *machine) { m_machine = machine; } std::vector &get_menu() { return m_menu; } void attach_notifiers(); void on_frame_done(); void on_periodic(); template bool call_plugin(const std::string &name, const T in, U &out) { bool ret = false; sol::object outobj = call_plugin(name, sol::make_object(sol(), in)); if(outobj.is()) { out = outobj.as(); ret = true; } return ret; } template bool call_plugin(const std::string &name, const T in, std::vector &out) { bool ret = false; sol::object outobj = call_plugin(name, sol::make_object(sol(), in)); if(outobj.is()) { for(auto &entry : outobj.as()) { if(entry.second.template is()) { out.push_back(entry.second.template as()); ret = true; } } } return ret; } // this can also check if a returned table contains type T template bool call_plugin_check(const std::string &name, const U in, bool table = false) { bool ret = false; sol::object outobj = call_plugin(name, sol::make_object(sol(), in)); if(outobj.is() && !table) ret = true; else if(outobj.is() && table) { // check just one entry, checking the whole thing shouldn't be necessary as this only supports homogeneous tables if(outobj.as().begin().operator*().second.template is()) ret = true; } return ret; } template void call_plugin_set(const std::string &name, const T in) { call_plugin(name, sol::make_object(sol(), in)); } sol::state_view &sol() const { return *m_sol_state; } private: // internal state lua_State *m_lua_state; std::unique_ptr m_sol_state; running_machine *m_machine; std::vector m_menu; running_machine &machine() const { return *m_machine; } void on_machine_prestart(); void on_machine_start(); void on_machine_stop(); void on_machine_pause(); void on_machine_resume(); void on_machine_frame(); void resume(void *ptr, int nparam); void register_function(sol::function func, const char *id); bool execute_function(const char *id); sol::object call_plugin(const std::string &name, sol::object in); struct addr_space { addr_space(address_space &space, device_memory_interface &dev) : space(space), dev(dev) {} template T mem_read(offs_t address); template void mem_write(offs_t address, T val); template T log_mem_read(offs_t address); template void log_mem_write(offs_t address, T val); template T direct_mem_read(offs_t address); template void direct_mem_write(offs_t address, T val); address_space &space; device_memory_interface &dev; }; template static T share_read(memory_share &share, offs_t address); template static void share_write(memory_share &share, offs_t address, T val); template static T region_read(memory_region ®ion, offs_t address); template static void region_write(memory_region ®ion, offs_t address, T val); struct save_item { void *base; unsigned int size; unsigned int count; }; void close(); void run(sol::load_result res); struct context { context() { busy = false; yield = false; } std::string result; std::condition_variable sync; bool busy; bool yield; }; }; #endif // MAME_FRONTEND_MAME_LUAENGINE_H