diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index bcec7a3b3..16cdd164d 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -10,6 +10,7 @@ #include "Log.h" #include "MameNames.h" #include "platform.h" +#include "Scripting.h" #include "SystemData.h" #include "VolumeControl.h" #include "Window.h" @@ -282,6 +283,8 @@ void FileData::launchGame(Window* window) command = Utils::String::replace(command, "%BASENAME%", basename); command = Utils::String::replace(command, "%ROM_RAW%", rom_raw); + Scripting::fireEvent("game-start", rom, basename); + LOG(LogInfo) << " " << command; int exitCode = runSystemCommand(command); @@ -290,6 +293,8 @@ void FileData::launchGame(Window* window) LOG(LogWarning) << "...launch terminated with nonzero exit code " << exitCode << "!"; } + Scripting::fireEvent("game-end"); + window->init(); VolumeControl::getInstance()->init(); window->normalizeNextUpdate(); diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 534b4c437..59d8ae415 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -13,6 +13,7 @@ #include "views/ViewController.h" #include "CollectionSystemManager.h" #include "EmulationStation.h" +#include "Scripting.h" #include "SystemData.h" #include "VolumeControl.h" #include @@ -296,13 +297,15 @@ void GuiMenu::openUISettings() s->addSaveFunc([window, theme_set] { bool needReload = false; - if(Settings::getInstance()->getString("ThemeSet") != theme_set->getSelected()) + std::string oldTheme = Settings::getInstance()->getString("ThemeSet"); + if(oldTheme != theme_set->getSelected()) needReload = true; Settings::getInstance()->setString("ThemeSet", theme_set->getSelected()); if(needReload) { + Scripting::fireEvent("theme-changed", theme_set->getSelected(), oldTheme); CollectionSystemManager::get()->updateSystemsList(); ViewController::get()->goToStart(); ViewController::get()->reloadAll(); // TODO - replace this with some sort of signal-based implementation @@ -472,6 +475,7 @@ void GuiMenu::openQuitMenu() row.makeAcceptInputHandler([window] { window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES", [] { + Scripting::fireEvent("quit"); if(quitES("/tmp/es-restart") != 0) LOG(LogWarning) << "Restart terminated with non-zero result!"; }, "NO", nullptr)); @@ -487,9 +491,8 @@ void GuiMenu::openQuitMenu() row.makeAcceptInputHandler([window] { window->pushGui(new GuiMsgBox(window, "REALLY QUIT?", "YES", [] { - SDL_Event ev; - ev.type = SDL_QUIT; - SDL_PushEvent(&ev); + Scripting::fireEvent("quit"); + quitES(""); }, "NO", nullptr)); }); row.addElement(std::make_shared(window, "QUIT EMULATIONSTATION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true); @@ -500,6 +503,8 @@ void GuiMenu::openQuitMenu() row.makeAcceptInputHandler([window] { window->pushGui(new GuiMsgBox(window, "REALLY RESTART?", "YES", [] { + Scripting::fireEvent("quit", "reboot"); + Scripting::fireEvent("reboot"); if (quitES("/tmp/es-sysrestart") != 0) LOG(LogWarning) << "Restart terminated with non-zero result!"; }, "NO", nullptr)); @@ -511,6 +516,8 @@ void GuiMenu::openQuitMenu() row.makeAcceptInputHandler([window] { window->pushGui(new GuiMsgBox(window, "REALLY SHUTDOWN?", "YES", [] { + Scripting::fireEvent("quit", "shutdown"); + Scripting::fireEvent("shutdown"); if (quitES("/tmp/es-shutdown") != 0) LOG(LogWarning) << "Shutdown terminated with non-zero result!"; }, "NO", nullptr)); diff --git a/es-core/CMakeLists.txt b/es-core/CMakeLists.txt index 468884929..9e4302f1e 100644 --- a/es-core/CMakeLists.txt +++ b/es-core/CMakeLists.txt @@ -92,6 +92,7 @@ set(CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/PowerSaver.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer_draw_gl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Renderer_init_sdlgl.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/Scripting.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Settings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/Sound.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/ThemeData.cpp diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index dbf6e5788..93026c5ea 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -4,6 +4,7 @@ #include "CECInput.h" #include "Log.h" #include "platform.h" +#include "Scripting.h" #include "Window.h" #include #include @@ -396,6 +397,9 @@ void InputManager::writeDeviceConfig(InputConfig* config) config->writeToXML(root); doc.save_file(path.c_str()); + + Scripting::fireEvent("config-changed"); + Scripting::fireEvent("controls-changed"); // execute any onFinish commands and re-load the config for changes doOnFinish(); diff --git a/es-core/src/Scripting.cpp b/es-core/src/Scripting.cpp new file mode 100644 index 000000000..3038db0a4 --- /dev/null +++ b/es-core/src/Scripting.cpp @@ -0,0 +1,36 @@ +#include "Scripting.h" +#include "Log.h" +#include "platform.h" +#include "utils/FileSystemUtil.h" + +namespace Scripting +{ + void fireEvent(const std::string& eventName, const std::string& arg1, const std::string& arg2) + { + LOG(LogDebug) << "fireEvent: " << eventName << " " << arg1 << " " << arg2; + + std::list scriptDirList; + std::string test; + + // check in exepath + test = Utils::FileSystem::getExePath() + "/scripts/" + eventName; + if(Utils::FileSystem::exists(test)) + scriptDirList.push_back(test); + + // check in homepath + test = Utils::FileSystem::getHomePath() + "/.emulationstation/scripts/" + eventName; + if(Utils::FileSystem::exists(test)) + scriptDirList.push_back(test); + + for(std::list::const_iterator dirIt = scriptDirList.cbegin(); dirIt != scriptDirList.cend(); ++dirIt) { + std::list scripts = Utils::FileSystem::getDirContent(*dirIt); + for (std::list::const_iterator it = scripts.cbegin(); it != scripts.cend(); ++it) { + // append folder to path + std::string script = *it + " \"" + arg1 + "\" \"" + arg2 + "\""; + LOG(LogDebug) << " executing: " << script; + runSystemCommand(script); + } + } + } + +} // Scripting:: diff --git a/es-core/src/Scripting.h b/es-core/src/Scripting.h new file mode 100644 index 000000000..3089a538c --- /dev/null +++ b/es-core/src/Scripting.h @@ -0,0 +1,12 @@ +#pragma once +#ifndef ES_CORE_SCRIPTING_H +#define ES_CORE_SCRIPTING_H + +#include + +namespace Scripting +{ + void fireEvent(const std::string& eventName, const std::string& arg1="", const std::string& arg2=""); +} // Scripting:: + +#endif //ES_CORE_SCRIPTING_H diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 4a0c24630..13c09a84a 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -2,6 +2,7 @@ #include "utils/FileSystemUtil.h" #include "Log.h" +#include "Scripting.h" #include "platform.h" #include #include @@ -193,6 +194,9 @@ void Settings::saveFile() } doc.save_file(path.c_str()); + + Scripting::fireEvent("config-changed"); + Scripting::fireEvent("settings-changed"); } void Settings::loadFile() diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index 2716792a0..39489494f 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -7,6 +7,7 @@ #include "InputManager.h" #include "Log.h" #include "Renderer.h" +#include "Scripting.h" #include #include @@ -277,8 +278,10 @@ void Window::render() if (!isProcessing() && mAllowSleep && (!mScreenSaver || mScreenSaver->allowSleep())) { // go to sleep - mSleeping = true; - onSleep(); + if (mSleeping == false) { + mSleeping = true; + onSleep(); + } } } } @@ -401,11 +404,12 @@ void Window::setHelpPrompts(const std::vector& prompts, const HelpSt void Window::onSleep() { + Scripting::fireEvent("sleep"); } void Window::onWake() { - + Scripting::fireEvent("wake"); } bool Window::isProcessing() diff --git a/es-core/src/platform.cpp b/es-core/src/platform.cpp index 0319cf88f..81722a549 100644 --- a/es-core/src/platform.cpp +++ b/es-core/src/platform.cpp @@ -42,7 +42,8 @@ int runSystemCommand(const std::string& cmd_utf8) int quitES(const std::string& filename) { - touch(filename); + if (!filename.empty()) + touch(filename); SDL_Event* quit = new SDL_Event(); quit->type = SDL_QUIT; SDL_PushEvent(quit);