(iOS Thread) Use an event queue to pass events (reset, state load, etc) to the retroarch thread

This commit is contained in:
meancoot 2013-04-02 22:38:33 -04:00
parent 1ab77945da
commit c778844852
2 changed files with 102 additions and 21 deletions

View File

@ -15,6 +15,7 @@
*/
#include <dispatch/dispatch.h>
#include <pthread.h>
#include "../ios/RetroArch/rarch_wrapper.h"
#include "../general.h"
@ -25,6 +26,42 @@
#include "../frontend/menu/rgui.h"
#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)
{
if (wrap)
@ -59,7 +96,9 @@ void rarch_main_ios(void* args)
{
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);
}
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))
{
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);
}
else

View File

@ -30,6 +30,48 @@
// From frontend/frontend_ios.c
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
{
@ -68,22 +110,18 @@ extern void rarch_main_ios(void* args);
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_window.rootViewController = self;
[_window makeKeyAndVisible];
// RetroArch init
rarch_init_msg_queue();
menu_init();
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
if (_isRunning)
init_drivers();
ios_frontend_post_event(&event_init_drivers, 0);
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
if (_isRunning)
uninit_drivers();
ios_frontend_post_event(&event_uninit_drivers, 0);
}
// UINavigationControllerDelegate
@ -165,18 +203,14 @@ extern void rarch_main_ios(void* args);
- (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)
ios_frontend_post_event(&event_reload_config, 0);
else
{
uninit_drivers();
config_load();
init_drivers();
// 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));
}
#endif
}
#pragma mark PAUSE MENU
@ -191,25 +225,32 @@ extern void rarch_main_ios(void* args);
- (IBAction)resetGame:(id)sender
{
if (_isRunning) rarch_game_reset();
if (_isRunning)
ios_frontend_post_event(&event_game_reset, 0);
[self closePauseMenu:sender];
}
- (IBAction)loadState:(id)sender
{
if (_isRunning) rarch_load_state();
if (_isRunning)
ios_frontend_post_event(&event_load_state, 0);
[self closePauseMenu:sender];
}
- (IBAction)saveState:(id)sender
{
if (_isRunning) rarch_save_state();
if (_isRunning)
ios_frontend_post_event(&event_save_state, 0);
[self closePauseMenu: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