From 0066dcd522c585f5b450952915592fb8359bcc5d Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Wed, 25 Sep 2019 15:04:03 +0200 Subject: [PATCH] [ion/simulator] Rename platform APIs --- ion/src/simulator/android/Makefile | 5 +- ion/src/simulator/android/src/cpp/images.cpp | 2 +- .../simulator/android/src/cpp/language.cpp | 7 --- .../simulator/android/src/cpp/telemetry.cpp | 6 +- ion/src/simulator/ios/images.m | 2 +- ion/src/simulator/ios/telemetry.m | 6 +- ion/src/simulator/macos/Makefile | 2 +- ion/src/simulator/macos/images.m | 2 +- ion/src/simulator/shared/apple/language.m | 2 +- ion/src/simulator/shared/dummy/callback.cpp | 7 +++ ion/src/simulator/shared/dummy/language.cpp | 5 ++ ion/src/simulator/shared/dummy/telemetry.cpp | 10 +++ .../shared/events_keyboard_platform.cpp | 62 ++++++++++++++++++- ion/src/simulator/shared/keyboard.cpp | 40 +++++++----- ion/src/simulator/shared/language_dummy.cpp | 5 -- ion/src/simulator/shared/main.cpp | 12 ++-- ion/src/simulator/shared/platform.h | 22 +++++-- ion/src/simulator/shared/telemetry_dummy.cpp | 10 --- ion/src/simulator/web/Makefile | 11 +++- ion/src/simulator/web/callback.cpp | 19 ++++++ ion/src/simulator/windows/Makefile | 2 +- ion/src/simulator/windows/images.cpp | 2 +- ion/src/simulator/windows/language.cpp | 2 +- 23 files changed, 175 insertions(+), 68 deletions(-) delete mode 100644 ion/src/simulator/android/src/cpp/language.cpp create mode 100644 ion/src/simulator/shared/dummy/callback.cpp create mode 100644 ion/src/simulator/shared/dummy/language.cpp create mode 100644 ion/src/simulator/shared/dummy/telemetry.cpp delete mode 100644 ion/src/simulator/shared/language_dummy.cpp delete mode 100644 ion/src/simulator/shared/telemetry_dummy.cpp create mode 100644 ion/src/simulator/web/callback.cpp diff --git a/ion/src/simulator/android/Makefile b/ion/src/simulator/android/Makefile index e00f37d71..82215b413 100644 --- a/ion/src/simulator/android/Makefile +++ b/ion/src/simulator/android/Makefile @@ -1,9 +1,12 @@ ion_src += $(addprefix ion/src/simulator/android/src/cpp/, \ images.cpp \ - language.cpp \ telemetry.cpp \ ) +ion_src += $(addprefix ion/src/simulator/shared/, \ + language_dummy.cpp \ +) + $(call object_for,ion/src/simulator/shared/main.cpp) : SFLAGS += -DEPSILON_SDL_FULLSCREEN=1 LDFLAGS += -ljnigraphics -llog diff --git a/ion/src/simulator/android/src/cpp/images.cpp b/ion/src/simulator/android/src/cpp/images.cpp index 638bd77e5..45a1f5c5f 100644 --- a/ion/src/simulator/android/src/cpp/images.cpp +++ b/ion/src/simulator/android/src/cpp/images.cpp @@ -3,7 +3,7 @@ #include #include -SDL_Texture * IonSDLPlatformLoadImage(SDL_Renderer * renderer, const char * identifier) { +SDL_Texture * IonSimulatorLoadImage(SDL_Renderer * renderer, const char * identifier) { JNIEnv * env = static_cast(SDL_AndroidGetJNIEnv()); jobject activity = static_cast(SDL_AndroidGetActivity()); diff --git a/ion/src/simulator/android/src/cpp/language.cpp b/ion/src/simulator/android/src/cpp/language.cpp deleted file mode 100644 index f8cba9556..000000000 --- a/ion/src/simulator/android/src/cpp/language.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "../../../shared/platform.h" - -char * IonSDLPlatformGetLanguageCode() { - // The Android NDK cannot retrieve the current locale - // This will be handled by the Java side - return nullptr; -} diff --git a/ion/src/simulator/android/src/cpp/telemetry.cpp b/ion/src/simulator/android/src/cpp/telemetry.cpp index d081ea88d..62e7b8967 100644 --- a/ion/src/simulator/android/src/cpp/telemetry.cpp +++ b/ion/src/simulator/android/src/cpp/telemetry.cpp @@ -2,7 +2,7 @@ #include #include -void IonSDLPlatformTelemetryInit() { +void IonSimulatorTelemetryInit() { JNIEnv * env = static_cast(SDL_AndroidGetJNIEnv()); jobject activity = static_cast(SDL_AndroidGetActivity()); @@ -12,7 +12,7 @@ void IonSDLPlatformTelemetryInit() { env->CallVoidMethod(activity, j_methodId); } -void IonSDLPlatformTelemetryEvent(const char * eventName) { +void IonSimulatorTelemetryEvent(const char * eventName) { JNIEnv * env = static_cast(SDL_AndroidGetJNIEnv()); jobject activity = static_cast(SDL_AndroidGetActivity()); @@ -24,5 +24,5 @@ void IonSDLPlatformTelemetryEvent(const char * eventName) { env->CallVoidMethod(activity, j_methodId, j_eventName); } -void IonSDLPlatformTelemetryDeinit() { +void IonSimulatorTelemetryDeinit() { } diff --git a/ion/src/simulator/ios/images.m b/ion/src/simulator/ios/images.m index 4e691b419..c255aec61 100644 --- a/ion/src/simulator/ios/images.m +++ b/ion/src/simulator/ios/images.m @@ -3,7 +3,7 @@ #include #include -SDL_Texture * IonSDLPlatformLoadImage(SDL_Renderer * renderer, const char * identifier) { +SDL_Texture * IonSimulatorLoadImage(SDL_Renderer * renderer, const char * identifier) { CGImageRef cgImage = [[UIImage imageNamed:[NSString stringWithUTF8String:identifier]] CGImage]; if (cgImage == NULL) { return NULL; diff --git a/ion/src/simulator/ios/telemetry.m b/ion/src/simulator/ios/telemetry.m index e09aa2199..8b7af6b40 100644 --- a/ion/src/simulator/ios/telemetry.m +++ b/ion/src/simulator/ios/telemetry.m @@ -4,15 +4,15 @@ #import #import -void IonSDLPlatformTelemetryInit() { +void IonSimulatorTelemetryInit() { [[GAI sharedInstance] trackerWithTrackingId:@"UA-93775823-3"]; } -void IonSDLPlatformTelemetryEvent(const char * eventName) { +void IonSimulatorTelemetryEvent(const char * eventName) { id tracker = [GAI sharedInstance].defaultTracker; [tracker set:kGAIScreenName value:[NSString stringWithUTF8String:eventName]]; [tracker send:[[GAIDictionaryBuilder createScreenView] build]]; } -void IonSDLPlatformTelemetryDeinit() { +void IonSimulatorTelemetryDeinit() { } diff --git a/ion/src/simulator/macos/Makefile b/ion/src/simulator/macos/Makefile index 12d221703..0b86abe03 100644 --- a/ion/src/simulator/macos/Makefile +++ b/ion/src/simulator/macos/Makefile @@ -4,7 +4,7 @@ ion_src += $(addprefix ion/src/simulator/macos/, \ ion_src += $(addprefix ion/src/simulator/shared/, \ apple/language.m \ - telemetry_dummy.cpp \ + dummy/telemetry.cpp \ ) # App resources diff --git a/ion/src/simulator/macos/images.m b/ion/src/simulator/macos/images.m index a96396d20..8e19b3b49 100644 --- a/ion/src/simulator/macos/images.m +++ b/ion/src/simulator/macos/images.m @@ -3,7 +3,7 @@ #include #include -SDL_Texture * IonSDLPlatformLoadImage(SDL_Renderer * renderer, const char * identifier) { +SDL_Texture * IonSimulatorLoadImage(SDL_Renderer * renderer, const char * identifier) { NSImage * nsImage = [NSImage imageNamed:[NSString stringWithUTF8String:identifier]]; CGImageRef cgImage = [nsImage CGImageForProposedRect:NULL context:NULL diff --git a/ion/src/simulator/shared/apple/language.m b/ion/src/simulator/shared/apple/language.m index 0268c0a3f..1fcefe08b 100644 --- a/ion/src/simulator/shared/apple/language.m +++ b/ion/src/simulator/shared/apple/language.m @@ -2,7 +2,7 @@ #include -char * IonSDLPlatformGetLanguageCode() { +char * IonSimulatorGetLanguageCode() { static char buffer[4] = {0}; if (buffer[0] == 0) { NSString * preferredLanguage = [[NSLocale preferredLanguages] firstObject]; diff --git a/ion/src/simulator/shared/dummy/callback.cpp b/ion/src/simulator/shared/dummy/callback.cpp new file mode 100644 index 000000000..d5851e650 --- /dev/null +++ b/ion/src/simulator/shared/dummy/callback.cpp @@ -0,0 +1,7 @@ +#include "../platform.h" + +void IonSimulatorCallbackDidRefresh() { +} + +void IonSimulatorCallbackDidScanKeyboard() { +} diff --git a/ion/src/simulator/shared/dummy/language.cpp b/ion/src/simulator/shared/dummy/language.cpp new file mode 100644 index 000000000..ac672ab47 --- /dev/null +++ b/ion/src/simulator/shared/dummy/language.cpp @@ -0,0 +1,5 @@ +#include "../platform.h" + +char * IonSimulatorGetLanguageCode() { + return nullptr; +} diff --git a/ion/src/simulator/shared/dummy/telemetry.cpp b/ion/src/simulator/shared/dummy/telemetry.cpp new file mode 100644 index 000000000..aa1dff5f0 --- /dev/null +++ b/ion/src/simulator/shared/dummy/telemetry.cpp @@ -0,0 +1,10 @@ +#include "../platform.h" + +void IonSimulatorTelemetryInit() { +} + +void IonSimulatorTelemetryEvent(const char * eventName) { +} + +void IonSimulatorTelemetryDeinit() { +} diff --git a/ion/src/simulator/shared/events_keyboard_platform.cpp b/ion/src/simulator/shared/events_keyboard_platform.cpp index b72bdc9ce..ebd67ba29 100644 --- a/ion/src/simulator/shared/events_keyboard_platform.cpp +++ b/ion/src/simulator/shared/events_keyboard_platform.cpp @@ -6,6 +6,60 @@ #include #include +#if EPSILON_SDL_SCREEN_ONLY + +template +class Queue { +public: + Queue() : m_first(&m_elements[0]), m_last(&m_elements[0]) {} + int size() { + if (m_last >= m_first) { + return m_last - m_first; + } else { + return m_last - (m_first - N); + } + } + + void enqueue(T element) { + if (size() > N) { + // Queue is full + return; + } + *m_last = element; + m_last = next(m_last); + } + + T dequeue() { + if (size() <= 0) { + // Dequeueing an empty queue + return T(); + } + T e = *m_first; + m_first = next(m_first); + return e; + } + +private: + T * next(T * p) { + if (p >= m_elements + N) { + return m_elements; + } else { + return p + 1; + } + } + T * m_first; + T * m_last; + T m_elements[N]; +}; + +static Queue sEventQueue; + +void IonSimulatorEventsPushEvent(int eventNumber) { + sEventQueue.enqueue(Ion::Events::Event(eventNumber)); +} + +#endif + namespace Ion { namespace Events { @@ -120,6 +174,12 @@ static Event eventFromSDLTextInputEvent(SDL_TextInputEvent event) { } Event getPlatformEvent() { +#if EPSILON_SDL_SCREEN_ONLY + if (sEventQueue.size() > 0) { + Event event = sEventQueue.dequeue(); + return event; + } +#endif SDL_Event event; while (SDL_PollEvent(&event)) { // The while is important: it'll do a fast-pass over all useless SDL events @@ -138,7 +198,7 @@ Event getPlatformEvent() { return eventFromSDLTextInputEvent(event.text); } if (event.type == SDL_APP_WILLENTERFOREGROUND) { - IonSDLPlatformTelemetryEvent("Calculator"); + IonSimulatorTelemetryEvent("Calculator"); return None; } } diff --git a/ion/src/simulator/shared/keyboard.cpp b/ion/src/simulator/shared/keyboard.cpp index ed416c889..911957051 100644 --- a/ion/src/simulator/shared/keyboard.cpp +++ b/ion/src/simulator/shared/keyboard.cpp @@ -1,9 +1,24 @@ #include "main.h" +#include "platform.h" #include "layout.h" #include #include +#if EPSILON_SDL_SCREEN_ONLY +static Ion::Keyboard::State sKeyboardState; + +void IonSimulatorKeyboardKeyDown(int keyNumber) { + Ion::Keyboard::Key key = static_cast(keyNumber); + sKeyboardState.setKey(key); +} + +void IonSimulatorKeyboardKeyUp(int keyNumber) { + Ion::Keyboard::Key key = static_cast(keyNumber); + sKeyboardState.clearKey(key); +} +#endif + namespace Ion { namespace Keyboard { @@ -11,9 +26,16 @@ State scan() { // We need to tell SDL to get new state from the host OS SDL_PumpEvents(); + // Notify callbacks in case we need to do something + IonSimulatorCallbackDidScanKeyboard(); + // Grab this opportunity to refresh the display if needed SDL::Main::refresh(); +#if EPSILON_SDL_SCREEN_ONLY + // In this case, keyboard states will be sent over another channel + return sKeyboardState; +#else // Start with a "clean" state State state; @@ -25,24 +47,8 @@ State scan() { state.setKey(k); } -#if 0 - // SDL exposes the first finger as a mouse! - // Register a key for each finger, if any - int numberOfTouchDevices = SDL_GetNumTouchDevices(); - for (int i=0; i arguments(argv, argv + argc); - char * language = IonSDLPlatformGetLanguageCode(); + char * language = IonSimulatorGetLanguageCode(); if (language != nullptr) { arguments.push_back("--language"); arguments.push_back(language); } - IonSDLPlatformTelemetryInit(); + IonSimulatorTelemetryInit(); Ion::SDL::Main::init(); - IonSDLPlatformTelemetryEvent("Calculator"); + IonSimulatorTelemetryEvent("Calculator"); ion_main(arguments.size(), &arguments[0]); Ion::SDL::Main::quit(); - IonSDLPlatformTelemetryDeinit(); + IonSimulatorTelemetryDeinit(); return 0; } @@ -82,7 +82,7 @@ void init() { Display::init(sRenderer); #if !EPSILON_SDL_SCREEN_ONLY - sBackgroundTexture = IonSDLPlatformLoadImage(sRenderer, "background.jpg"); + sBackgroundTexture = IonSimulatorLoadImage(sRenderer, "background.jpg"); #endif relayout(); @@ -133,6 +133,8 @@ void refresh() { Display::draw(sRenderer, &screenRect); #endif SDL_RenderPresent(sRenderer); + + IonSimulatorCallbackDidRefresh(); } void quit() { diff --git a/ion/src/simulator/shared/platform.h b/ion/src/simulator/shared/platform.h index 45b2b5d54..ae23ef68e 100644 --- a/ion/src/simulator/shared/platform.h +++ b/ion/src/simulator/shared/platform.h @@ -10,12 +10,24 @@ extern "C" { /* Those functions should be implemented per-platform. * They are defined as C function for easier interop. */ -SDL_Texture * IonSDLPlatformLoadImage(SDL_Renderer * renderer, const char * identifier); -char * IonSDLPlatformGetLanguageCode(); +SDL_Texture * IonSimulatorLoadImage(SDL_Renderer * renderer, const char * identifier); +char * IonSimulatorGetLanguageCode(); -void IonSDLPlatformTelemetryInit(); -void IonSDLPlatformTelemetryEvent(const char * eventName); -void IonSDLPlatformTelemetryDeinit(); +void IonSimulatorTelemetryInit(); +void IonSimulatorTelemetryEvent(const char * eventName); +void IonSimulatorTelemetryDeinit(); + +#if EPSILON_SDL_SCREEN_ONLY + +void IonSimulatorKeyboardKeyDown(int keyNumber); +void IonSimulatorKeyboardKeyUp(int keyNumber); + +void IonSimulatorEventsPushEvent(int eventNumber); + +#endif + +void IonSimulatorCallbackDidRefresh(); +void IonSimulatorCallbackDidScanKeyboard(); #ifdef __cplusplus } diff --git a/ion/src/simulator/shared/telemetry_dummy.cpp b/ion/src/simulator/shared/telemetry_dummy.cpp deleted file mode 100644 index 034d8d8af..000000000 --- a/ion/src/simulator/shared/telemetry_dummy.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "../shared/platform.h" - -void IonSDLPlatformTelemetryInit() { -} - -void IonSDLPlatformTelemetryEvent(const char * eventName) { -} - -void IonSDLPlatformTelemetryDeinit() { -} diff --git a/ion/src/simulator/web/Makefile b/ion/src/simulator/web/Makefile index 20b638dec..34ea0af7c 100644 --- a/ion/src/simulator/web/Makefile +++ b/ion/src/simulator/web/Makefile @@ -8,9 +8,14 @@ SFLAGS += -DUSING_GENERATED_CONFIG_H SFLAGS += -Iion/src/simulator/web/include # Only render the screen, not the whole calculator which will be drawn in HTML -$(call object_for,ion/src/simulator/shared/main.cpp) : SFLAGS += -DEPSILON_SDL_SCREEN_ONLY=1 +SFLAGS += -DEPSILON_SDL_SCREEN_ONLY=1 + +ion_src += $(addprefix ion/src/simulator/web/, \ + callback.cpp \ + helpers.cpp \ +) ion_src += $(addprefix ion/src/simulator/shared/, \ - language_dummy.cpp \ - telemetry_dummy.cpp \ + dummy/language.cpp \ + dummy/telemetry.cpp \ ) diff --git a/ion/src/simulator/web/callback.cpp b/ion/src/simulator/web/callback.cpp new file mode 100644 index 000000000..6c5254a8d --- /dev/null +++ b/ion/src/simulator/web/callback.cpp @@ -0,0 +1,19 @@ +#include "../shared/platform.h" +#include + +void IonSimulatorCallbackDidRefresh() { + /* Notify JS that the display has been refreshed. + * This gives us a chance to mirror the display in fullscreen mode. */ + EM_ASM(if (typeof Module.onDisplayRefresh === "function") { Module.onDisplayRefresh(); }); +} + +void IonSimulatorCallbackDidScanKeyboard() { + /* The following call to emscripten_sleep gives the JS VM a chance to do a run + * loop iteration. This in turns gives the browser an opportunity to call the + * IonEventsEmscriptenPushKey function, therefore modifying the sKeyboardState + * global variable before it is returned by this Ion::Keyboard::scan. + * On Emterpreter-async, emscripten_sleep is actually a wrapper around the JS + * function setTimeout, which can be called with a value of zero. Doing so + * puts the callback at the end of the queue of callbacks to be processed. */ + emscripten_sleep(0); +} diff --git a/ion/src/simulator/windows/Makefile b/ion/src/simulator/windows/Makefile index c30d6254f..758563870 100644 --- a/ion/src/simulator/windows/Makefile +++ b/ion/src/simulator/windows/Makefile @@ -4,7 +4,7 @@ ion_src += $(addprefix ion/src/simulator/windows/, \ resources.rc \ ) ion_src += $(addprefix ion/src/simulator/shared/, \ - telemetry_dummy.cpp \ + dummy/telemetry.cpp \ ) LDFLAGS += -lgdiplus diff --git a/ion/src/simulator/windows/images.cpp b/ion/src/simulator/windows/images.cpp index d95f828b9..60a6c7cdb 100644 --- a/ion/src/simulator/windows/images.cpp +++ b/ion/src/simulator/windows/images.cpp @@ -34,7 +34,7 @@ HRESULT CreateStreamOnResource(const char * name, LPSTREAM * stream) { return hr; } -SDL_Texture * IonSDLPlatformLoadImage(SDL_Renderer * renderer, const char * identifier) { +SDL_Texture * IonSimulatorLoadImage(SDL_Renderer * renderer, const char * identifier) { Gdiplus::GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr); diff --git a/ion/src/simulator/windows/language.cpp b/ion/src/simulator/windows/language.cpp index 9b3d41744..22d7909f8 100644 --- a/ion/src/simulator/windows/language.cpp +++ b/ion/src/simulator/windows/language.cpp @@ -2,7 +2,7 @@ #include -char * IonSDLPlatformGetLanguageCode() { +char * IonSimulatorGetLanguageCode() { /* Per documentation, the maximum number of characters allowed for the * language string is nine, including a terminating null character. */ static char buffer[9] = {0};