(iOS Thread) Use an event queue to pass events (reset, state load, etc) to the retroarch thread
This commit is contained in:
parent
1ab77945da
commit
c778844852
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dispatch/dispatch.h>
|
#include <dispatch/dispatch.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "../ios/RetroArch/rarch_wrapper.h"
|
#include "../ios/RetroArch/rarch_wrapper.h"
|
||||||
#include "../general.h"
|
#include "../general.h"
|
||||||
|
@ -25,6 +26,42 @@
|
||||||
#include "../frontend/menu/rgui.h"
|
#include "../frontend/menu/rgui.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static pthread_mutex_t ios_event_queue_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
void (*function)(void*);
|
||||||
|
void* userdata;
|
||||||
|
} ios_event_queue[16];
|
||||||
|
static uint32_t ios_event_queue_size;
|
||||||
|
|
||||||
|
void ios_frontend_post_event(void (*fn)(void*), void* userdata)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&ios_event_queue_lock);
|
||||||
|
|
||||||
|
if (ios_event_queue_size < 16)
|
||||||
|
{
|
||||||
|
ios_event_queue[ios_event_queue_size].function = fn;
|
||||||
|
ios_event_queue[ios_event_queue_size].userdata = userdata;
|
||||||
|
ios_event_queue_size ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&ios_event_queue_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void process_events()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&ios_event_queue_lock);
|
||||||
|
|
||||||
|
for (int i = 0; i < ios_event_queue_size; i ++)
|
||||||
|
ios_event_queue[i].function(ios_event_queue[i].userdata);
|
||||||
|
|
||||||
|
ios_event_queue_size = 0;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&ios_event_queue_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ios_free_main_wrap(struct rarch_main_wrap* wrap)
|
static void ios_free_main_wrap(struct rarch_main_wrap* wrap)
|
||||||
{
|
{
|
||||||
if (wrap)
|
if (wrap)
|
||||||
|
@ -59,7 +96,9 @@ void rarch_main_ios(void* args)
|
||||||
{
|
{
|
||||||
if (g_extern.lifecycle_mode_state & (1ULL << MODE_GAME))
|
if (g_extern.lifecycle_mode_state & (1ULL << MODE_GAME))
|
||||||
{
|
{
|
||||||
while ((g_extern.is_paused && !g_extern.is_oneshot) ? rarch_main_idle_iterate() : rarch_main_iterate());
|
while ((g_extern.is_paused && !g_extern.is_oneshot) ? rarch_main_idle_iterate() : rarch_main_iterate())
|
||||||
|
process_events();
|
||||||
|
|
||||||
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME);
|
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME);
|
||||||
}
|
}
|
||||||
else if (g_extern.lifecycle_mode_state & (1ULL << MODE_INIT))
|
else if (g_extern.lifecycle_mode_state & (1ULL << MODE_INIT))
|
||||||
|
@ -93,7 +132,8 @@ void rarch_main_ios(void* args)
|
||||||
else if (g_extern.lifecycle_mode_state & (1ULL << MODE_MENU))
|
else if (g_extern.lifecycle_mode_state & (1ULL << MODE_MENU))
|
||||||
{
|
{
|
||||||
g_extern.lifecycle_mode_state |= 1ULL << MODE_MENU_PREINIT;
|
g_extern.lifecycle_mode_state |= 1ULL << MODE_MENU_PREINIT;
|
||||||
while (menu_iterate());
|
while (menu_iterate())
|
||||||
|
process_events();
|
||||||
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU);
|
g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -30,6 +30,48 @@
|
||||||
|
|
||||||
// From frontend/frontend_ios.c
|
// From frontend/frontend_ios.c
|
||||||
extern void rarch_main_ios(void* args);
|
extern void rarch_main_ios(void* args);
|
||||||
|
extern void ios_frontend_post_event(void (*fn)(void*), void* userdata);
|
||||||
|
|
||||||
|
static void event_game_reset(void* userdata)
|
||||||
|
{
|
||||||
|
rarch_game_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void event_load_state(void* userdata)
|
||||||
|
{
|
||||||
|
rarch_load_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void event_save_state(void* userdata)
|
||||||
|
{
|
||||||
|
rarch_save_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void event_set_state_slot(void* userdata)
|
||||||
|
{
|
||||||
|
g_extern.state_slot = (uint32_t)userdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void event_init_drivers(void* userdata)
|
||||||
|
{
|
||||||
|
init_drivers();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void event_uninit_drivers(void* userdata)
|
||||||
|
{
|
||||||
|
uninit_drivers();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void event_reload_config(void* userdata)
|
||||||
|
{
|
||||||
|
// Need to clear these otherwise stale versions may be used!
|
||||||
|
memset(g_settings.input.overlay, 0, sizeof(g_settings.input.overlay));
|
||||||
|
memset(g_settings.video.xml_shader_path, 0, sizeof(g_settings.video.xml_shader_path));
|
||||||
|
|
||||||
|
uninit_drivers();
|
||||||
|
config_load();
|
||||||
|
init_drivers();
|
||||||
|
}
|
||||||
|
|
||||||
@implementation RetroArch_iOS
|
@implementation RetroArch_iOS
|
||||||
{
|
{
|
||||||
|
@ -68,22 +110,18 @@ extern void rarch_main_ios(void* args);
|
||||||
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||||
_window.rootViewController = self;
|
_window.rootViewController = self;
|
||||||
[_window makeKeyAndVisible];
|
[_window makeKeyAndVisible];
|
||||||
|
|
||||||
// RetroArch init
|
|
||||||
rarch_init_msg_queue();
|
|
||||||
menu_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationWillEnterForeground:(UIApplication *)application
|
- (void)applicationWillEnterForeground:(UIApplication *)application
|
||||||
{
|
{
|
||||||
if (_isRunning)
|
if (_isRunning)
|
||||||
init_drivers();
|
ios_frontend_post_event(&event_init_drivers, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||||
{
|
{
|
||||||
if (_isRunning)
|
if (_isRunning)
|
||||||
uninit_drivers();
|
ios_frontend_post_event(&event_uninit_drivers, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// UINavigationControllerDelegate
|
// UINavigationControllerDelegate
|
||||||
|
@ -165,18 +203,14 @@ extern void rarch_main_ios(void* args);
|
||||||
|
|
||||||
- (void)refreshConfig
|
- (void)refreshConfig
|
||||||
{
|
{
|
||||||
// Need to clear these otherwise stale versions may be used!
|
|
||||||
memset(g_settings.input.overlay, 0, sizeof(g_settings.input.overlay));
|
|
||||||
memset(g_settings.video.xml_shader_path, 0, sizeof(g_settings.video.xml_shader_path));
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (_isRunning)
|
if (_isRunning)
|
||||||
|
ios_frontend_post_event(&event_reload_config, 0);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
uninit_drivers();
|
// Need to clear these otherwise stale versions may be used!
|
||||||
config_load();
|
memset(g_settings.input.overlay, 0, sizeof(g_settings.input.overlay));
|
||||||
init_drivers();
|
memset(g_settings.video.xml_shader_path, 0, sizeof(g_settings.video.xml_shader_path));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark PAUSE MENU
|
#pragma mark PAUSE MENU
|
||||||
|
@ -191,25 +225,32 @@ extern void rarch_main_ios(void* args);
|
||||||
|
|
||||||
- (IBAction)resetGame:(id)sender
|
- (IBAction)resetGame:(id)sender
|
||||||
{
|
{
|
||||||
if (_isRunning) rarch_game_reset();
|
if (_isRunning)
|
||||||
|
ios_frontend_post_event(&event_game_reset, 0);
|
||||||
|
|
||||||
[self closePauseMenu:sender];
|
[self closePauseMenu:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)loadState:(id)sender
|
- (IBAction)loadState:(id)sender
|
||||||
{
|
{
|
||||||
if (_isRunning) rarch_load_state();
|
if (_isRunning)
|
||||||
|
ios_frontend_post_event(&event_load_state, 0);
|
||||||
|
|
||||||
[self closePauseMenu:sender];
|
[self closePauseMenu:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)saveState:(id)sender
|
- (IBAction)saveState:(id)sender
|
||||||
{
|
{
|
||||||
if (_isRunning) rarch_save_state();
|
if (_isRunning)
|
||||||
|
ios_frontend_post_event(&event_save_state, 0);
|
||||||
|
|
||||||
[self closePauseMenu:sender];
|
[self closePauseMenu:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)chooseState:(id)sender
|
- (IBAction)chooseState:(id)sender
|
||||||
{
|
{
|
||||||
g_extern.state_slot = ((UISegmentedControl*)sender).selectedSegmentIndex;
|
if (_isRunning)
|
||||||
|
ios_frontend_post_event(event_set_state_slot, (void*)((UISegmentedControl*)sender).selectedSegmentIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)closePauseMenu:(id)sender
|
- (IBAction)closePauseMenu:(id)sender
|
||||||
|
|
Loading…
Reference in New Issue