almost finished with a generalized coroutine solution
parent
681f53fae1
commit
e4a4608007
64
4ed.cpp
64
4ed.cpp
|
@ -304,9 +304,9 @@ restore_state(Application_Links *app, App_Coroutine_State state){
|
|||
app->type_coroutine = state.type;
|
||||
}
|
||||
|
||||
inline Coroutine*
|
||||
app_launch_coroutine(System_Functions *system, Application_Links *app, Coroutine_Type type, Coroutine *co, void *in, void *out){
|
||||
Coroutine* result = 0;
|
||||
inline Coroutine_Head*
|
||||
app_launch_coroutine(System_Functions *system, Application_Links *app, Coroutine_Type type, Coroutine_Head *co, void *in, void *out){
|
||||
Coroutine_Head *result = 0;
|
||||
|
||||
App_Coroutine_State prev_state = get_state(app);
|
||||
|
||||
|
@ -318,9 +318,9 @@ app_launch_coroutine(System_Functions *system, Application_Links *app, Coroutine
|
|||
return(result);
|
||||
}
|
||||
|
||||
inline Coroutine*
|
||||
app_resume_coroutine(System_Functions *system, Application_Links *app, Coroutine_Type type, Coroutine *co, void *in, void *out){
|
||||
Coroutine* result = 0;
|
||||
inline Coroutine_Head*
|
||||
app_resume_coroutine(System_Functions *system, Application_Links *app, Coroutine_Type type, Coroutine_Head *co, void *in, void *out){
|
||||
Coroutine_Head *result = 0;
|
||||
|
||||
App_Coroutine_State prev_state = get_state(app);
|
||||
|
||||
|
@ -614,7 +614,7 @@ struct Command_In{
|
|||
};
|
||||
|
||||
internal void
|
||||
command_caller(Coroutine *coroutine){
|
||||
command_caller(Coroutine_Head *coroutine){
|
||||
Command_In *cmd_in = (Command_In*)coroutine->in;
|
||||
Command_Data *command = cmd_in->cmd;
|
||||
Models *models = command->models;
|
||||
|
@ -778,19 +778,19 @@ enum Command_Line_Mode{
|
|||
};
|
||||
|
||||
internal void
|
||||
init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, Command_Line_Parameters clparams){
|
||||
init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, i32 argc, char **argv){
|
||||
char *arg = 0;
|
||||
Command_Line_Mode mode = CLMode_App;
|
||||
Command_Line_Action action = CLAct_Nothing;
|
||||
b32 strict = false;
|
||||
|
||||
settings->init_files_max = ArrayCount(settings->init_files);
|
||||
for (i32 i = 1; i <= clparams.argc; ++i){
|
||||
if (i == clparams.argc){
|
||||
for (i32 i = 1; i <= argc; ++i){
|
||||
if (i == argc){
|
||||
arg = "";
|
||||
}
|
||||
else{
|
||||
arg = clparams.argv[i];
|
||||
arg = argv[i];
|
||||
}
|
||||
|
||||
if (arg[0] == '-' && arg[1] == '-'){
|
||||
|
@ -838,27 +838,27 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
|
|||
case CLAct_CustomDLL:
|
||||
{
|
||||
plat_settings->custom_dll_is_strict = (b8)strict;
|
||||
if (i < clparams.argc){
|
||||
plat_settings->custom_dll = clparams.argv[i];
|
||||
if (i < argc){
|
||||
plat_settings->custom_dll = argv[i];
|
||||
}
|
||||
action = CLAct_Nothing;
|
||||
}break;
|
||||
|
||||
case CLAct_InitialFilePosition:
|
||||
{
|
||||
if (i < clparams.argc){
|
||||
settings->initial_line = str_to_int_c(clparams.argv[i]);
|
||||
if (i < argc){
|
||||
settings->initial_line = str_to_int_c(argv[i]);
|
||||
}
|
||||
action = CLAct_Nothing;
|
||||
}break;
|
||||
|
||||
case CLAct_WindowSize:
|
||||
{
|
||||
if (i + 1 < clparams.argc){
|
||||
if (i + 1 < argc){
|
||||
plat_settings->set_window_size = true;
|
||||
|
||||
i32 w = str_to_int_c(clparams.argv[i]);
|
||||
i32 h = str_to_int_c(clparams.argv[i+1]);
|
||||
i32 w = str_to_int_c(argv[i]);
|
||||
i32 h = str_to_int_c(argv[i+1]);
|
||||
if (w > 0){
|
||||
plat_settings->window_w = w;
|
||||
}
|
||||
|
@ -880,11 +880,11 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
|
|||
|
||||
case CLAct_WindowPosition:
|
||||
{
|
||||
if (i + 1 < clparams.argc){
|
||||
if (i + 1 < argc){
|
||||
plat_settings->set_window_pos = true;
|
||||
|
||||
i32 x = str_to_int_c(clparams.argv[i]);
|
||||
i32 y = str_to_int_c(clparams.argv[i+1]);
|
||||
i32 x = str_to_int_c(argv[i]);
|
||||
i32 y = str_to_int_c(argv[i+1]);
|
||||
if (x > 0){
|
||||
plat_settings->window_x = x;
|
||||
}
|
||||
|
@ -906,8 +906,8 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
|
|||
|
||||
case CLAct_FontSize:
|
||||
{
|
||||
if (i < clparams.argc){
|
||||
plat_settings->font_size = str_to_int_c(clparams.argv[i]);
|
||||
if (i < argc){
|
||||
plat_settings->font_size = str_to_int_c(argv[i]);
|
||||
plat_settings->font_size = clamp_bottom(8, plat_settings->font_size);
|
||||
}
|
||||
action = CLAct_Nothing;
|
||||
|
@ -935,9 +935,9 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
|
|||
|
||||
case CLMode_Custom:
|
||||
{
|
||||
settings->custom_flags = clparams.argv + i;
|
||||
settings->custom_flags_count = clparams.argc - i;
|
||||
i = clparams.argc;
|
||||
settings->custom_flags = argv + i;
|
||||
settings->custom_flags_count = argc - i;
|
||||
i = argc;
|
||||
mode = CLMode_App;
|
||||
}break;
|
||||
}
|
||||
|
@ -969,8 +969,8 @@ App_Read_Command_Line_Sig(app_read_command_line){
|
|||
*settings = null_app_settings;
|
||||
plat_settings->font_size = 16;
|
||||
|
||||
if (clparams.argc > 1){
|
||||
init_command_line_settings(&vars->models.settings, plat_settings, clparams);
|
||||
if (argc > 1){
|
||||
init_command_line_settings(&vars->models.settings, plat_settings, argc, argv);
|
||||
}
|
||||
|
||||
*files = vars->models.settings.init_files;
|
||||
|
@ -1623,11 +1623,11 @@ App_Step_Sig(app_step){
|
|||
}
|
||||
|
||||
if (there_is_unsaved){
|
||||
Coroutine *command_coroutine = models->command_coroutine;
|
||||
Coroutine_Head *command_coroutine = models->command_coroutine;
|
||||
Command_Data *command = cmd;
|
||||
USE_VIEW(view);
|
||||
|
||||
for (i32 i = 0; i < 128 && command_coroutine; ++i){
|
||||
for (i32 i = 0; i < 128 && command_coroutine != 0; ++i){
|
||||
User_Input user_in = {0};
|
||||
user_in.abort = true;
|
||||
|
||||
|
@ -1686,7 +1686,7 @@ App_Step_Sig(app_step){
|
|||
|
||||
// NOTE(allen): Keyboard and Mouse input to command coroutine.
|
||||
if (models->command_coroutine != 0){
|
||||
Coroutine *command_coroutine = models->command_coroutine;
|
||||
Coroutine_Head *command_coroutine = models->command_coroutine;
|
||||
u32 get_flags = models->command_coroutine_flags[0];
|
||||
u32 abort_flags = models->command_coroutine_flags[1];
|
||||
|
||||
|
@ -1969,7 +1969,7 @@ App_Step_Sig(app_step){
|
|||
}
|
||||
|
||||
Assert(models->command_coroutine == 0);
|
||||
Coroutine *command_coroutine = system->create_coroutine(command_caller);
|
||||
Coroutine_Head *command_coroutine = system->create_coroutine(command_caller);
|
||||
models->command_coroutine = command_coroutine;
|
||||
|
||||
Command_In cmd_in;
|
||||
|
|
10
4ed.h
10
4ed.h
|
@ -46,11 +46,6 @@ struct Input_Summary{
|
|||
f32 dt;
|
||||
};
|
||||
|
||||
struct Command_Line_Parameters{
|
||||
char **argv;
|
||||
int32_t argc;
|
||||
};
|
||||
|
||||
typedef u8 Log_To_Type;
|
||||
enum{
|
||||
LogTo_Nothing,
|
||||
|
@ -77,7 +72,7 @@ struct Plat_Settings{
|
|||
};
|
||||
|
||||
#define App_Read_Command_Line_Sig(name) \
|
||||
i32 name(System_Functions *system, Application_Memory *memory, String current_directory, Plat_Settings *plat_settings, char ***files, i32 **file_count, Command_Line_Parameters clparams)
|
||||
i32 name(System_Functions *system, Application_Memory *memory, String current_directory, Plat_Settings *plat_settings, char ***files, i32 **file_count, i32 argc, char **argv)
|
||||
|
||||
typedef App_Read_Command_Line_Sig(App_Read_Command_Line);
|
||||
|
||||
|
@ -123,8 +118,7 @@ name(System_Functions *system, \
|
|||
Render_Target *target, \
|
||||
Application_Memory *memory, \
|
||||
Application_Step_Input *input, \
|
||||
Application_Step_Result *app_result_, \
|
||||
Command_Line_Parameters params)
|
||||
Application_Step_Result *app_result_)
|
||||
|
||||
typedef App_Step_Sig(App_Step);
|
||||
|
||||
|
|
|
@ -2069,11 +2069,11 @@ DOC_SEE(User_Input)
|
|||
*/{
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
System_Functions *system = cmd->system;
|
||||
Coroutine *coroutine = (Coroutine*)app->current_coroutine;
|
||||
Coroutine_Head *coroutine = (Coroutine_Head*)app->current_coroutine;
|
||||
User_Input result = {0};
|
||||
|
||||
if (app->type_coroutine == Co_Command){
|
||||
Assert(coroutine);
|
||||
Assert(coroutine != 0);
|
||||
*((u32*)coroutine->out+0) = get_type;
|
||||
*((u32*)coroutine->out+1) = abort_type;
|
||||
system->yield_coroutine(coroutine);
|
||||
|
|
|
@ -57,7 +57,7 @@ struct Models{
|
|||
|
||||
Command_Binding prev_command;
|
||||
|
||||
Coroutine *command_coroutine;
|
||||
Coroutine_Head *command_coroutine;
|
||||
u32 command_coroutine_flags[2];
|
||||
|
||||
Hook_Function *hooks[hook_type_count];
|
||||
|
|
18
4ed_system.h
18
4ed_system.h
|
@ -90,27 +90,25 @@ typedef Sys_CLI_Update_Step_Sig(System_CLI_Update_Step);
|
|||
typedef Sys_CLI_End_Update_Sig(System_CLI_End_Update);
|
||||
|
||||
// coroutine
|
||||
#define Coroutine_Function_Sig(name) void name(struct Coroutine *coroutine)
|
||||
typedef Coroutine_Function_Sig(Coroutine_Function);
|
||||
|
||||
struct Coroutine{
|
||||
Plat_Handle plat_handle;
|
||||
Coroutine_Function *func;
|
||||
void *yield_handle;
|
||||
struct Coroutine_Head{
|
||||
void *in;
|
||||
void *out;
|
||||
};
|
||||
|
||||
#define Sys_Create_Coroutine_Sig(name) Coroutine *name(Coroutine_Function *func)
|
||||
#define COROUTINE_SIG(n) void n(Coroutine_Head *coroutine)
|
||||
typedef COROUTINE_SIG(Coroutine_Function);
|
||||
|
||||
#define Sys_Create_Coroutine_Sig(name) Coroutine_Head *name(Coroutine_Function *func)
|
||||
typedef Sys_Create_Coroutine_Sig(System_Create_Coroutine);
|
||||
|
||||
#define Sys_Launch_Coroutine_Sig(name) Coroutine *name(Coroutine *coroutine, void *in, void *out)
|
||||
#define Sys_Launch_Coroutine_Sig(name) Coroutine_Head *name(Coroutine_Head *head, void *in, void *out)
|
||||
typedef Sys_Launch_Coroutine_Sig(System_Launch_Coroutine);
|
||||
|
||||
#define Sys_Resume_Coroutine_Sig(name) Coroutine *name(Coroutine *coroutine, void *in, void *out)
|
||||
#define Sys_Resume_Coroutine_Sig(name) Coroutine_Head *name(Coroutine_Head *head, void *in, void *out)
|
||||
typedef Sys_Resume_Coroutine_Sig(System_Resume_Coroutine);
|
||||
|
||||
#define Sys_Yield_Coroutine_Sig(name) void name(Coroutine *coroutine)
|
||||
#define Sys_Yield_Coroutine_Sig(name) void name(Coroutine_Head *head)
|
||||
typedef Sys_Yield_Coroutine_Sig(System_Yield_Coroutine);
|
||||
|
||||
// thread
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
struct View_Persistent{
|
||||
i32 id;
|
||||
Coroutine *coroutine;
|
||||
Coroutine_Head *coroutine;
|
||||
Event_Message message_passing_slot;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
/*
|
||||
4tech_file_moving.h - Code for moving files around on the file system.
|
||||
By Allen Webster
|
||||
21.01.2017 (dd.mm.yyyy)
|
||||
*/
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 21.01.2017
|
||||
*
|
||||
* Moving files around on the file system.
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
|
@ -302,9 +305,9 @@ extern "C"{
|
|||
#define FILE_ATTRIBUTE_NORMAL 0x00000080
|
||||
#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
|
||||
|
||||
static u64 perf_frequency;
|
||||
global u64 perf_frequency;
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_init_system(){
|
||||
LARGE_INTEGER lint;
|
||||
if (QueryPerformanceFrequency(&lint)){
|
||||
|
@ -313,7 +316,7 @@ fm_init_system(){
|
|||
fm__init_memory();
|
||||
}
|
||||
|
||||
static Temp_Dir
|
||||
internal Temp_Dir
|
||||
fm_pushdir(char *dir){
|
||||
Temp_Dir temp = {0};
|
||||
GetCurrentDirectoryA(sizeof(temp.dir), temp.dir);
|
||||
|
@ -321,12 +324,12 @@ fm_pushdir(char *dir){
|
|||
return(temp);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_popdir(Temp_Dir temp){
|
||||
SetCurrentDirectoryA(temp.dir);
|
||||
}
|
||||
|
||||
static u64
|
||||
internal u64
|
||||
fm_get_time(){
|
||||
u64 time = 0;
|
||||
LARGE_INTEGER lint;
|
||||
|
@ -337,13 +340,13 @@ fm_get_time(){
|
|||
return(time);
|
||||
}
|
||||
|
||||
static i32
|
||||
internal i32
|
||||
fm_get_current_directory(char *buffer, i32 max){
|
||||
i32 result = GetCurrentDirectoryA(max, buffer);
|
||||
return(result);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_execute_in_dir(char *dir, char *str, char *args){
|
||||
if (dir){
|
||||
Temp_Dir temp = fm_pushdir(dir);
|
||||
|
@ -365,7 +368,7 @@ fm_execute_in_dir(char *dir, char *str, char *args){
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_slash_fix(char *path){
|
||||
if (path != 0){
|
||||
for (i32 i = 0; path[i]; ++i){
|
||||
|
@ -374,7 +377,7 @@ fm_slash_fix(char *path){
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_make_folder_if_missing(char *dir){
|
||||
char *path = fm_str(dir);
|
||||
char *p = path;
|
||||
|
@ -388,23 +391,23 @@ fm_make_folder_if_missing(char *dir){
|
|||
CreateDirectoryA(path, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_clear_folder(char *folder){
|
||||
fprintf(stdout, "clearing folder %s\n", folder);
|
||||
systemf("del /S /Q /F %s\\* > nul & rmdir /S /Q %s > nul & mkdir %s > nul", folder, folder, folder);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_delete_file(char *file){
|
||||
systemf("del %s", file);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_copy_file(char *file, char *newname){
|
||||
CopyFileA(file, newname, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_copy_all(char *source, char *tag, char *folder){
|
||||
if (source){
|
||||
fprintf(stdout, "copy %s\\%s to %s\n", source, tag, folder);
|
||||
|
@ -433,7 +436,7 @@ fm_write_file(char *file_name, char *data, u32 size){
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_zip(char *parent, char *folder, char *dest){
|
||||
char cdir[512];
|
||||
fm_get_current_directory(cdir, sizeof(cdir));
|
||||
|
@ -454,7 +457,7 @@ fm_zip(char *parent, char *folder, char *dest){
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static Temp_Dir
|
||||
internal Temp_Dir
|
||||
fm_pushdir(char *dir){
|
||||
Temp_Dir temp;
|
||||
char *result = getcwd(temp.dir, sizeof(temp.dir));
|
||||
|
@ -467,17 +470,17 @@ fm_pushdir(char *dir){
|
|||
return(temp);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_popdir(Temp_Dir temp){
|
||||
chdir(temp.dir);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_init_system(){
|
||||
fm__init_memory();
|
||||
}
|
||||
|
||||
static u64
|
||||
internal u64
|
||||
fm_get_time(){
|
||||
struct timespec spec;
|
||||
u64 result;
|
||||
|
@ -486,7 +489,7 @@ fm_get_time(){
|
|||
return(result);
|
||||
}
|
||||
|
||||
static i32
|
||||
internal i32
|
||||
fm_get_current_directory(char *buffer, i32 max){
|
||||
i32 result = 0;
|
||||
char *d = getcwd(buffer, max);
|
||||
|
@ -496,7 +499,7 @@ fm_get_current_directory(char *buffer, i32 max){
|
|||
return(result);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_execute_in_dir(char *dir, char *str, char *args){
|
||||
if (dir){
|
||||
if (args){
|
||||
|
@ -520,31 +523,31 @@ fm_execute_in_dir(char *dir, char *str, char *args){
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_slash_fix(char *path){}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_make_folder_if_missing(char *dir){
|
||||
systemf("mkdir -p %s", dir);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_clear_folder(char *folder){
|
||||
fprintf(stdout, "clearing folder %s\n", folder);
|
||||
systemf("rm -rf %s* > /dev/null", folder);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_delete_file(char *file){
|
||||
systemf("rm %s", file);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_copy_file(char *file, char *newname){
|
||||
systemf("cp %s %s", file, newname);
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_copy_all(char *source, char *tag, char *folder){
|
||||
if (source){
|
||||
fprintf(stdout, "copy %s/%s to %s\n", source, tag, folder);
|
||||
|
@ -566,7 +569,7 @@ fm_write_file(char *file_name, char *data, u32 size){
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
internal void
|
||||
fm_zip(char *parent, char *folder, char *file){
|
||||
Temp_Dir temp = fm_pushdir(parent);
|
||||
printf("PARENT DIR: %s\n", parent);
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 19.07.2017
|
||||
*
|
||||
* Coroutine implementation from thread+mutex+cv
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
typedef u32 Coroutine_State;
|
||||
enum{
|
||||
CoroutineState_Dead,
|
||||
CoroutineState_Active,
|
||||
CoroutineState_Inactive,
|
||||
CoroutineState_Waiting,
|
||||
};
|
||||
|
||||
typedef u32 Coroutine_Type;
|
||||
enum{
|
||||
CoroutineType_Uninitialized,
|
||||
CoroutineType_Root,
|
||||
CoroutineType_Sub,
|
||||
};
|
||||
|
||||
struct Coroutine{
|
||||
Coroutine_Head head;
|
||||
|
||||
Thread thread;
|
||||
Condition_Variable cv;
|
||||
struct Coroutine_System *sys;
|
||||
Coroutine_Function *function;
|
||||
Coroutine *yield_ctx;
|
||||
Coroutine_State state;
|
||||
Coroutine_Type type;
|
||||
};
|
||||
|
||||
struct Coroutine_System{
|
||||
Mutex lock;
|
||||
Condition_Variable init_cv;
|
||||
b32 did_init;
|
||||
Coroutine *active;
|
||||
};
|
||||
|
||||
#define COROUTINE_INT_SKIP_SLEEP false
|
||||
|
||||
internal void
|
||||
coroutine_internal_pass_control(Coroutine *me, Coroutine *other, Coroutine_State my_new_state, b32 do_sleep_loop = true){
|
||||
Assert(me->state == CoroutineState_Active);
|
||||
Assert(me->sys == other->sys);
|
||||
|
||||
me->state = my_new_state;
|
||||
other->state = CoroutineState_Active;
|
||||
me->sys->active = other;
|
||||
system_signal_cv(&other->cv, &me->sys->lock);
|
||||
if (do_sleep_loop){
|
||||
for (;me->state != CoroutineState_Active;){
|
||||
system_wait_cv(&me->cv, &me->sys->lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal
|
||||
PLAT_THREAD_SIG(coroutine_main){
|
||||
Coroutine *me = (Coroutine*)ptr;
|
||||
|
||||
// NOTE(allen): Init handshake
|
||||
Assert(me->state == CoroutineState_Dead);
|
||||
system_acquire_lock(&me->sys->lock);
|
||||
me->sys->did_init = true;
|
||||
system_signal_cv(&me->sys->init_cv, &me->sys->lock);
|
||||
|
||||
for (;;){
|
||||
// NOTE(allen): Wait until someone wakes us up, then go into our procedure.
|
||||
for (;me->state != CoroutineState_Active;){
|
||||
system_wait_cv(&me->cv, &me->sys->lock);
|
||||
}
|
||||
Assert(me->type != CoroutineType_Root);
|
||||
Assert(me->yield_ctx != 0);
|
||||
Assert(me->function != 0);
|
||||
|
||||
me->function(&me->head);
|
||||
|
||||
// NOTE(allen): Wake up the caller and set this coroutine back to being dead.
|
||||
Coroutine *other = me->yield_ctx;
|
||||
Assert(other != 0);
|
||||
Assert(other->state == CoroutineState_Waiting);
|
||||
|
||||
coroutine_internal_pass_control(me, other, CoroutineState_Dead, COROUTINE_INT_SKIP_SLEEP);
|
||||
me->function = 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
init_coroutine_system(Coroutine *root, Coroutine_System *sys){
|
||||
system_init_lock(&sys->lock);
|
||||
system_init_cv(&sys->init_cv);
|
||||
sys->active = root;
|
||||
|
||||
memset(root, 0, sizeof(*root));
|
||||
|
||||
root->sys = sys;
|
||||
root->state = CoroutineState_Active;
|
||||
root->type = CoroutineType_Root;
|
||||
|
||||
system_init_cv(&root->cv);
|
||||
}
|
||||
|
||||
internal void
|
||||
init_coroutine_sub(Coroutine *co, Coroutine_System *sys){
|
||||
memset(co, 0, sizeof(*co));
|
||||
|
||||
co->sys = sys;
|
||||
co->state = CoroutineState_Dead;
|
||||
co->type = CoroutineType_Sub;
|
||||
|
||||
system_init_cv(&co->cv);
|
||||
|
||||
sys->did_init = false;
|
||||
system_init_and_launch_thread(&co->thread, coroutine_main, co);
|
||||
for (;!sys->did_init;){
|
||||
system_wait_cv(&sys->init_cv, &sys->lock);
|
||||
}
|
||||
}
|
||||
|
||||
// HACK(allen): I want to bundle this with launch!
|
||||
internal void
|
||||
coroutine_set_function(Coroutine *me, Coroutine_Function *function){
|
||||
Assert(me->state == CoroutineState_Dead);
|
||||
me->function = function;
|
||||
}
|
||||
|
||||
internal void
|
||||
coroutine_launch(Coroutine *me, Coroutine *other){
|
||||
Assert(me->sys == other->sys);
|
||||
Assert(other->state == CoroutineState_Dead);
|
||||
Assert(other->function != 0);
|
||||
|
||||
other->yield_ctx = me;
|
||||
coroutine_internal_pass_control(me, other, CoroutineState_Waiting);
|
||||
}
|
||||
|
||||
internal void
|
||||
coroutine_yield(Coroutine *me){
|
||||
Coroutine *other = me->yield_ctx;
|
||||
Assert(other != 0);
|
||||
Assert(me->sys == other->sys);
|
||||
Assert(other->state == CoroutineState_Waiting);
|
||||
|
||||
coroutine_internal_pass_control(me, other, CoroutineState_Inactive);
|
||||
}
|
||||
|
||||
internal void
|
||||
coroutine_resume(Coroutine *me, Coroutine *other){
|
||||
Assert(me->sys == other->sys);
|
||||
Assert(other->state == CoroutineState_Inactive);
|
||||
|
||||
other->yield_ctx = me;
|
||||
coroutine_internal_pass_control(me, other, CoroutineState_Waiting);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
struct Coroutine_Alloc_Block{
|
||||
Coroutine coroutine;
|
||||
Coroutine_Alloc_Block *next;
|
||||
};
|
||||
|
||||
#define COROUTINE_SLOT_SIZE sizeof(Coroutine_Alloc_Block)
|
||||
|
||||
struct Coroutine_System_Auto_Alloc{
|
||||
Coroutine_System sys;
|
||||
|
||||
Coroutine root;
|
||||
Coroutine_Alloc_Block *head_free_uninit;
|
||||
Coroutine_Alloc_Block *head_free_inited;
|
||||
};
|
||||
|
||||
internal void
|
||||
init_coroutine_system(Coroutine_System_Auto_Alloc *sys){
|
||||
init_coroutine_system(&sys->root, &sys->sys);
|
||||
sys->head_free_uninit = 0;
|
||||
sys->head_free_inited = 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
coroutine_system_provide_memory(Coroutine_System_Auto_Alloc *sys, void *memory, umem size){
|
||||
memset(memory, 0, size);
|
||||
|
||||
Coroutine_Alloc_Block *blocks = (Coroutine_Alloc_Block*)memory;
|
||||
umem count = (size / sizeof(*blocks));
|
||||
|
||||
Coroutine_Alloc_Block *old_head = sys->head_free_uninit;
|
||||
sys->head_free_uninit = &blocks[0];
|
||||
Coroutine_Alloc_Block *block = blocks;
|
||||
for (u32 i = 1; i < count; ++i, ++block){
|
||||
block->next = block + 1;
|
||||
}
|
||||
block->next = old_head;
|
||||
}
|
||||
|
||||
internal Coroutine_Alloc_Block*
|
||||
coroutine_system_pop(Coroutine_Alloc_Block **head){
|
||||
Coroutine_Alloc_Block *result = *head;
|
||||
if (result != 0){
|
||||
*head = result->next;
|
||||
}
|
||||
result->next = 0;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
coroutine_system_push(Coroutine_Alloc_Block **head, Coroutine_Alloc_Block *block){
|
||||
block->next = *head;
|
||||
*head = block;
|
||||
}
|
||||
|
||||
internal void
|
||||
coroutine_system_force_init(Coroutine_System_Auto_Alloc *sys, u32 count){
|
||||
for (u32 i = 0; i < count; ++i){
|
||||
Coroutine_Alloc_Block *block = coroutine_system_pop(&sys->head_free_uninit);
|
||||
if (block == 0){
|
||||
break;
|
||||
}
|
||||
init_coroutine_sub(&block->coroutine, &sys->sys);
|
||||
coroutine_system_push(&sys->head_free_inited, block);
|
||||
}
|
||||
}
|
||||
|
||||
internal Coroutine*
|
||||
coroutine_system_alloc(Coroutine_System_Auto_Alloc *sys){
|
||||
Coroutine_Alloc_Block *block = coroutine_system_pop(&sys->head_free_inited);
|
||||
if (block == 0){
|
||||
coroutine_system_force_init(sys, 1);
|
||||
block = coroutine_system_pop(&sys->head_free_inited);
|
||||
}
|
||||
|
||||
Coroutine *result = 0;
|
||||
if (block != 0){
|
||||
result = &block->coroutine;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
coroutine_system_free(Coroutine_System_Auto_Alloc *sys, Coroutine *co){
|
||||
Coroutine_Alloc_Block *block = (Coroutine_Alloc_Block*)co;
|
||||
coroutine_system_push(&sys->head_free_inited, block);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
// TOP
|
||||
|
||||
internal void
|
||||
system_memory_init(){
|
||||
memory_init(){
|
||||
#if defined(FRED_INTERNAL)
|
||||
# if defined(FTECH_64_BIT)
|
||||
void *bases[] = { (void*)TB(1), (void*)TB(2), };
|
||||
|
@ -120,5 +120,25 @@ load_custom_code(){
|
|||
LOGF("Loaded custom file: %s\n", success_file);
|
||||
}
|
||||
|
||||
internal void
|
||||
read_command_line(i32 argc, char **argv){
|
||||
LOG("Reading command line\n");
|
||||
char cwd[4096];
|
||||
u32 size = sysfunc.get_current_path(cwd, sizeof(cwd));
|
||||
if (size == 0 || size >= sizeof(cwd)){
|
||||
system_error_box("Could not get current directory at launch.");
|
||||
}
|
||||
|
||||
String curdir = make_string_cap(cwd, size, sizeof(cwd));
|
||||
terminate_with_null(&curdir);
|
||||
replace_char(&curdir, '\\', '/');
|
||||
|
||||
char **files = 0;
|
||||
i32 *file_count = 0;
|
||||
app.read_command_line(&sysfunc, &memory_vars, curdir, &plat_settings, &files, &file_count, argc, argv);
|
||||
sysshared_filter_real_files(files, file_count);
|
||||
LOG("Read command line.\n");
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -85,7 +85,8 @@ system_load_library(Library *library, char *name, Load_Library_Location location
|
|||
|
||||
internal b32
|
||||
system_load_library(Library *library, char *name, Load_Library_Location location){
|
||||
system_load_library(library, name, location, 0, 0);
|
||||
b32 result = system_load_library(library, name, location, 0, 0);
|
||||
return(result);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -369,7 +369,7 @@ INTERNAL_Sys_Get_Thread_States_Sig(system_internal_get_thread_states){
|
|||
}
|
||||
|
||||
internal void
|
||||
system_init_threaded_work_system(){
|
||||
work_system_init(){
|
||||
AssertThreadSizes();
|
||||
|
||||
u32 core_count = CORE_COUNT;
|
||||
|
|
|
@ -105,14 +105,6 @@ enum {
|
|||
LINUX_4ED_EVENT_CLI = (UINT64_C(5) << 32),
|
||||
};
|
||||
|
||||
struct Linux_Coroutine {
|
||||
Coroutine coroutine;
|
||||
Linux_Coroutine *next;
|
||||
ucontext_t ctx, yield_ctx;
|
||||
stack_t stack;
|
||||
b32 done;
|
||||
};
|
||||
|
||||
//
|
||||
// Linux forward declarations
|
||||
//
|
||||
|
@ -129,6 +121,8 @@ global System_Functions sysfunc;
|
|||
#include "linux_library_wrapper.h"
|
||||
#include "4ed_standard_libraries.cpp"
|
||||
|
||||
#include "4ed_coroutine.cpp"
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
struct Linux_Vars{
|
||||
|
@ -183,9 +177,6 @@ struct Linux_Vars{
|
|||
i32 dpi_x, dpi_y;
|
||||
|
||||
b32 vsync;
|
||||
|
||||
Linux_Coroutine coroutine_data[18];
|
||||
Linux_Coroutine *coroutine_free;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
|
@ -199,6 +190,8 @@ global Libraries libraries;
|
|||
global App_Functions app;
|
||||
global Custom_API custom_api;
|
||||
|
||||
global Coroutine_System_Auto_Alloc coroutines;
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
#include "linux_icon.h"
|
||||
|
@ -326,91 +319,57 @@ Sys_Post_Clipboard_Sig(system_post_clipboard){
|
|||
// Coroutine
|
||||
//
|
||||
|
||||
internal Linux_Coroutine*
|
||||
LinuxAllocCoroutine(){
|
||||
Linux_Coroutine *result = linuxvars.coroutine_free;
|
||||
Assert(result != 0);
|
||||
if (getcontext(&result->ctx) == -1){
|
||||
perror("getcontext");
|
||||
}
|
||||
result->ctx.uc_stack = result->stack;
|
||||
linuxvars.coroutine_free = result->next;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
LinuxFreeCoroutine(Linux_Coroutine *data){
|
||||
data->next = linuxvars.coroutine_free;
|
||||
linuxvars.coroutine_free = data;
|
||||
}
|
||||
|
||||
internal void
|
||||
LinuxCoroutineMain(void *arg_){
|
||||
Linux_Coroutine *c = (Linux_Coroutine*)arg_;
|
||||
c->coroutine.func(&c->coroutine);
|
||||
c->done = 1;
|
||||
LinuxFreeCoroutine(c);
|
||||
setcontext((ucontext_t*)c->coroutine.yield_handle);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Create_Coroutine_Sig(system_create_coroutine){
|
||||
Linux_Coroutine *c = LinuxAllocCoroutine();
|
||||
c->done = 0;
|
||||
|
||||
makecontext(&c->ctx, (void (*)())LinuxCoroutineMain, 1, &c->coroutine);
|
||||
|
||||
*(ucontext_t**)&c->coroutine.plat_handle = &c->ctx;
|
||||
c->coroutine.func = func;
|
||||
|
||||
return(&c->coroutine);
|
||||
Coroutine *coroutine = coroutine_system_alloc(&coroutines);
|
||||
Coroutine_Head *result = 0;
|
||||
if (coroutine != 0){
|
||||
coroutine_set_function(coroutine, func);
|
||||
result = &coroutine->head;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Launch_Coroutine_Sig(system_launch_coroutine){
|
||||
Linux_Coroutine *c = (Linux_Coroutine*)coroutine;
|
||||
ucontext_t* ctx = *(ucontext**)&coroutine->plat_handle;
|
||||
Coroutine *coroutine = (Coroutine*)head;
|
||||
coroutine->head.in = in;
|
||||
coroutine->head.out = out;
|
||||
|
||||
coroutine->yield_handle = &c->yield_ctx;
|
||||
coroutine->in = in;
|
||||
coroutine->out = out;
|
||||
Coroutine *active = coroutine->sys->active;
|
||||
Assert(active != 0);
|
||||
coroutine_launch(active, coroutine);
|
||||
Assert(active == coroutine->sys->active);
|
||||
|
||||
swapcontext(&c->yield_ctx, ctx);
|
||||
|
||||
if (c->done){
|
||||
LinuxFreeCoroutine(c);
|
||||
coroutine = 0;
|
||||
Coroutine_Head *result = &coroutine->head;
|
||||
if (coroutine->state == CoroutineState_Dead){
|
||||
coroutine_system_free(&coroutines, coroutine);
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return(coroutine);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Resume_Coroutine_Sig(system_resume_coroutine){
|
||||
Linux_Coroutine *c = (Linux_Coroutine*)coroutine;
|
||||
void *fiber;
|
||||
Coroutine *coroutine = (Coroutine*)head;
|
||||
coroutine->head.in = in;
|
||||
coroutine->head.out = out;
|
||||
|
||||
Assert(!c->done);
|
||||
Coroutine *active = coroutine->sys->active;
|
||||
Assert(active != 0);
|
||||
coroutine_resume(active, coroutine);
|
||||
Assert(active == coroutine->sys->active);
|
||||
|
||||
coroutine->yield_handle = &c->yield_ctx;
|
||||
coroutine->in = in;
|
||||
coroutine->out = out;
|
||||
|
||||
ucontext *ctx = *(ucontext**)&coroutine->plat_handle;
|
||||
|
||||
swapcontext(&c->yield_ctx, ctx);
|
||||
|
||||
if (c->done){
|
||||
LinuxFreeCoroutine(c);
|
||||
coroutine = 0;
|
||||
Coroutine_Head *result = &coroutine->head;
|
||||
if (coroutine->state == CoroutineState_Dead){
|
||||
coroutine_system_free(&coroutines, coroutine);
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return(coroutine);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Yield_Coroutine_Sig(system_yield_coroutine){
|
||||
swapcontext(*(ucontext_t**)&coroutine->plat_handle, (ucontext*)coroutine->yield_handle);
|
||||
Coroutine *coroutine = (Coroutine*)head;
|
||||
coroutine_yield(coroutine);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1652,39 +1611,19 @@ main(int argc, char **argv){
|
|||
// Memory init
|
||||
//
|
||||
|
||||
system_memory_init();
|
||||
memory_init();
|
||||
|
||||
//
|
||||
// Read command line
|
||||
//
|
||||
|
||||
char* cwd = get_current_dir_name();
|
||||
if (!cwd){
|
||||
char buf[1024];
|
||||
snprintf(buf, sizeof(buf), "Call to get_current_dir_name failed: %s", strerror(errno));
|
||||
system_error_box(buf);
|
||||
}
|
||||
read_command_line(argc, argv);
|
||||
|
||||
String current_directory = make_string_slowly(cwd);
|
||||
//
|
||||
// Threads
|
||||
//
|
||||
|
||||
Command_Line_Parameters clparams;
|
||||
clparams.argv = argv;
|
||||
clparams.argc = argc;
|
||||
|
||||
char **files;
|
||||
i32 *file_count;
|
||||
i32 output_size;
|
||||
|
||||
output_size = app.read_command_line(&sysfunc, &memory_vars, current_directory, &plat_settings, &files, &file_count, clparams);
|
||||
|
||||
if (output_size > 0){
|
||||
LOGF("%.*s", output_size, (char*)memory_vars.target_memory);
|
||||
}
|
||||
if (output_size != 0){
|
||||
system_error_box("Error reading command-line arguments.");
|
||||
}
|
||||
|
||||
sysshared_filter_real_files(files, file_count);
|
||||
work_system_init();
|
||||
|
||||
//
|
||||
// Coroutines
|
||||
|
@ -1692,7 +1631,7 @@ main(int argc, char **argv){
|
|||
|
||||
linuxvars.coroutine_free = linuxvars.coroutine_data;
|
||||
for (i32 i = 0; i+1 < ArrayCount(linuxvars.coroutine_data); ++i){
|
||||
linuxvars.coroutine_data[i].next = linuxvars.coroutine_data + i + 1;
|
||||
linuxvars.coroutine_data[i].next = &linuxvars.coroutine_data[i + 1];
|
||||
}
|
||||
|
||||
const size_t stack_size = MB(2);
|
||||
|
@ -1701,12 +1640,6 @@ main(int argc, char **argv){
|
|||
linuxvars.coroutine_data[i].stack.ss_sp = system_memory_allocate(stack_size);
|
||||
}
|
||||
|
||||
//
|
||||
// Threads
|
||||
//
|
||||
|
||||
system_init_threaded_work_system();
|
||||
|
||||
//
|
||||
// X11 init
|
||||
//
|
||||
|
@ -1715,7 +1648,7 @@ main(int argc, char **argv){
|
|||
if (!linuxvars.XDisplay){
|
||||
// NOTE(inso): probably not worth trying the popup in this case...
|
||||
LOG("Can't open display!\n");
|
||||
return(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define LOAD_ATOM(x) linuxvars.atom_##x = XInternAtom(linuxvars.XDisplay, #x, False);
|
||||
|
@ -1930,7 +1863,7 @@ main(int argc, char **argv){
|
|||
|
||||
b32 keep_running = linuxvars.keep_running;
|
||||
|
||||
app.step(&sysfunc, &target, &memory_vars, &linuxvars.input, &result, clparams);
|
||||
app.step(&sysfunc, &target, &memory_vars, &linuxvars.input, &result);
|
||||
|
||||
if (result.perform_kill){
|
||||
break;
|
||||
|
|
|
@ -105,12 +105,6 @@ struct Win32_Input_Chunk{
|
|||
Win32_Input_Chunk_Persistent pers;
|
||||
};
|
||||
|
||||
struct Win32_Coroutine{
|
||||
Coroutine coroutine;
|
||||
Win32_Coroutine *next;
|
||||
i32 done;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
#define SLASH '\\'
|
||||
|
@ -121,14 +115,11 @@ global System_Functions sysfunc;
|
|||
#include "win32_library_wrapper.h"
|
||||
#include "4ed_standard_libraries.cpp"
|
||||
|
||||
#include "4ed_coroutine.cpp"
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
struct Win32_Vars{
|
||||
Custom_API custom_api;
|
||||
|
||||
Win32_Coroutine coroutine_data[18];
|
||||
Win32_Coroutine *coroutine_free;
|
||||
|
||||
Win32_Input_Chunk input_chunk;
|
||||
b32 lctrl_lalt_is_altgr;
|
||||
b32 got_useful_event;
|
||||
|
@ -168,6 +159,9 @@ global Plat_Settings plat_settings;
|
|||
|
||||
global Libraries libraries;
|
||||
global App_Functions app;
|
||||
global Custom_API custom_api;
|
||||
|
||||
global Coroutine_System_Auto_Alloc coroutines;
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
|
@ -272,94 +266,57 @@ Sys_Send_Exit_Signal_Sig(system_send_exit_signal){
|
|||
// Coroutines
|
||||
//
|
||||
|
||||
internal Win32_Coroutine*
|
||||
Win32AllocCoroutine(){
|
||||
Win32_Coroutine *result = win32vars.coroutine_free;
|
||||
Assert(result != 0);
|
||||
win32vars.coroutine_free = result->next;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
Win32FreeCoroutine(Win32_Coroutine *data){
|
||||
data->next = win32vars.coroutine_free;
|
||||
win32vars.coroutine_free = data;
|
||||
}
|
||||
|
||||
internal void CALL_CONVENTION
|
||||
Win32CoroutineMain(void *arg_){
|
||||
Win32_Coroutine *c = (Win32_Coroutine*)arg_;
|
||||
c->coroutine.func(&c->coroutine);
|
||||
c->done = 1;
|
||||
Win32FreeCoroutine(c);
|
||||
SwitchToFiber(c->coroutine.yield_handle);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Create_Coroutine_Sig(system_create_coroutine){
|
||||
Win32_Coroutine *c;
|
||||
Coroutine *coroutine;
|
||||
void *fiber;
|
||||
|
||||
c = Win32AllocCoroutine();
|
||||
c->done = 0;
|
||||
|
||||
coroutine = &c->coroutine;
|
||||
|
||||
fiber = CreateFiber(0, Win32CoroutineMain, coroutine);
|
||||
|
||||
coroutine->plat_handle = handle_type(fiber);
|
||||
coroutine->func = func;
|
||||
|
||||
return(coroutine);
|
||||
Coroutine *coroutine = coroutine_system_alloc(&coroutines);
|
||||
Coroutine_Head *result = 0;
|
||||
if (coroutine != 0){
|
||||
coroutine_set_function(coroutine, func);
|
||||
result = &coroutine->head;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Launch_Coroutine_Sig(system_launch_coroutine){
|
||||
Win32_Coroutine *c = (Win32_Coroutine*)coroutine;
|
||||
void *fiber;
|
||||
Coroutine *coroutine = (Coroutine*)head;
|
||||
coroutine->head.in = in;
|
||||
coroutine->head.out = out;
|
||||
|
||||
fiber = handle_type(coroutine->plat_handle);
|
||||
coroutine->yield_handle = GetCurrentFiber();
|
||||
coroutine->in = in;
|
||||
coroutine->out = out;
|
||||
Coroutine *active = coroutine->sys->active;
|
||||
Assert(active != 0);
|
||||
coroutine_launch(active, coroutine);
|
||||
Assert(active == coroutine->sys->active);
|
||||
|
||||
SwitchToFiber(fiber);
|
||||
|
||||
if (c->done){
|
||||
DeleteFiber(fiber);
|
||||
Win32FreeCoroutine(c);
|
||||
coroutine = 0;
|
||||
Coroutine_Head *result = &coroutine->head;
|
||||
if (coroutine->state == CoroutineState_Dead){
|
||||
coroutine_system_free(&coroutines, coroutine);
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return(coroutine);
|
||||
return(result);
|
||||
}
|
||||
|
||||
Sys_Resume_Coroutine_Sig(system_resume_coroutine){
|
||||
Win32_Coroutine *c = (Win32_Coroutine*)coroutine;
|
||||
void *fiber;
|
||||
Coroutine *coroutine = (Coroutine*)head;
|
||||
coroutine->head.in = in;
|
||||
coroutine->head.out = out;
|
||||
|
||||
Assert(c->done == 0);
|
||||
Coroutine *active = coroutine->sys->active;
|
||||
Assert(active != 0);
|
||||
coroutine_resume(active, coroutine);
|
||||
Assert(active == coroutine->sys->active);
|
||||
|
||||
coroutine->yield_handle = GetCurrentFiber();
|
||||
coroutine->in = in;
|
||||
coroutine->out = out;
|
||||
|
||||
fiber = handle_type(coroutine->plat_handle);
|
||||
|
||||
SwitchToFiber(fiber);
|
||||
|
||||
if (c->done){
|
||||
DeleteFiber(fiber);
|
||||
Win32FreeCoroutine(c);
|
||||
coroutine = 0;
|
||||
Coroutine_Head *result = &coroutine->head;
|
||||
if (coroutine->state == CoroutineState_Dead){
|
||||
coroutine_system_free(&coroutines, coroutine);
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return(coroutine);
|
||||
return(result);
|
||||
}
|
||||
|
||||
Sys_Yield_Coroutine_Sig(system_yield_coroutine){
|
||||
SwitchToFiber(coroutine->yield_handle);
|
||||
Coroutine *coroutine = (Coroutine*)head;
|
||||
coroutine_yield(coroutine);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1062,7 +1019,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
i32 argc = __argc;
|
||||
char **argv = __argv;
|
||||
|
||||
memset(&linuxvars, 0, sizeof(linuxvars));
|
||||
memset(&win32vars, 0, sizeof(win32vars));
|
||||
memset(&target, 0, sizeof(target));
|
||||
memset(&memory_vars, 0, sizeof(memory_vars));
|
||||
memset(&plat_settings, 0, sizeof(plat_settings));
|
||||
|
@ -1087,51 +1044,35 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
#endif
|
||||
|
||||
//
|
||||
// Memory Initialization
|
||||
// Memory init
|
||||
//
|
||||
|
||||
system_memory_init();
|
||||
|
||||
//
|
||||
// Threads
|
||||
//
|
||||
|
||||
system_init_threaded_work_system();
|
||||
|
||||
//
|
||||
// Coroutines
|
||||
//
|
||||
|
||||
ConvertThreadToFiber(0);
|
||||
win32vars.coroutine_free = win32vars.coroutine_data;
|
||||
for (i32 i = 0; i+1 < ArrayCount(win32vars.coroutine_data); ++i){
|
||||
win32vars.coroutine_data[i].next = &win32vars.coroutine_data[i + 1];
|
||||
}
|
||||
memory_init();
|
||||
|
||||
//
|
||||
// Read Command Line
|
||||
//
|
||||
|
||||
LOG("Reading command line\n");
|
||||
DWORD required = (GetCurrentDirectory(0, 0)*4) + 1;
|
||||
u8 *current_directory_mem = (u8*)system_memory_allocate(required);
|
||||
DWORD written = GetCurrentDirectory_utf8(required, current_directory_mem);
|
||||
read_command_line(argc, argv);
|
||||
|
||||
String current_directory = make_string_cap(current_directory_mem, written, required);
|
||||
terminate_with_null(¤t_directory);
|
||||
replace_char(¤t_directory, '\\', '/');
|
||||
//
|
||||
// Threads
|
||||
//
|
||||
|
||||
Command_Line_Parameters clparams;
|
||||
clparams.argv = argv;
|
||||
clparams.argc = argc;
|
||||
work_system_init();
|
||||
|
||||
char **files = 0;
|
||||
i32 *file_count = 0;
|
||||
//
|
||||
// Coroutines
|
||||
//
|
||||
|
||||
app.read_command_line(&sysfunc, &memory_vars, current_directory, &plat_settings, &files, &file_count, clparams);
|
||||
|
||||
sysshared_filter_real_files(files, file_count);
|
||||
LOG("Loaded system code, read command line.\n");
|
||||
{
|
||||
init_coroutine_system(&coroutines);
|
||||
|
||||
umem size = COROUTINE_SLOT_SIZE*18;
|
||||
void *mem = system_memory_allocate(size);
|
||||
coroutine_system_provide_memory(&coroutines, mem, size);
|
||||
coroutine_system_force_init(&coroutines, 4);
|
||||
}
|
||||
|
||||
//
|
||||
// Window and GL Initialization
|
||||
|
@ -1254,10 +1195,17 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
// Main Loop
|
||||
//
|
||||
|
||||
LOG("Initializing application variables\n");
|
||||
app.init(&sysfunc, &target, &memory_vars, win32vars.clipboard_contents, current_directory, win32vars.custom_api);
|
||||
char cwd[4096];
|
||||
u32 size = sysfunc.get_current_path(cwd, sizeof(cwd));
|
||||
if (size == 0 || size >= sizeof(cwd)){
|
||||
system_error_box("Could not get current directory at launch.");
|
||||
}
|
||||
String curdir = make_string(cwd, size);
|
||||
terminate_with_null(&curdir);
|
||||
replace_char(&curdir, '\\', '/');
|
||||
|
||||
system_memory_free(current_directory.str, 0);
|
||||
LOG("Initializing application variables\n");
|
||||
app.init(&sysfunc, &target, &memory_vars, win32vars.clipboard_contents, curdir, custom_api);
|
||||
|
||||
b32 keep_running = true;
|
||||
win32vars.first = true;
|
||||
|
@ -1450,7 +1398,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
win32vars.send_exit_signal = false;
|
||||
}
|
||||
|
||||
app.step(&sysfunc, &target, &memory_vars, &input, &result, clparams);
|
||||
app.step(&sysfunc, &target, &memory_vars, &input, &result);
|
||||
|
||||
if (result.perform_kill){
|
||||
keep_running = false;
|
||||
|
|
|
@ -13,6 +13,12 @@
|
|||
// 4ed path
|
||||
//
|
||||
|
||||
internal
|
||||
Sys_Get_Current_Path_Sig(system_get_current_path){
|
||||
i32 result = GetCurrentDirectory_utf8(capacity, (u8*)out);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal
|
||||
Sys_Get_4ed_Path_Sig(system_get_4ed_path){
|
||||
i32 size = GetModuleFileName_utf8(0, (u8*)out, capacity);
|
||||
|
|
Loading…
Reference in New Issue