Typed coroutine in/out
This commit is contained in:
parent
ca2fcc5f04
commit
1b6091b871
92
4ed.cpp
92
4ed.cpp
|
@ -24,39 +24,40 @@ restore_state(Application_Links *app, App_Coroutine_State state){
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Coroutine*
|
internal Coroutine*
|
||||||
app_coroutine_handle_request(Models *models, Coroutine *co, u32 *vals){
|
app_coroutine_handle_request(Models *models, Coroutine *co, App_Coroutine_Out *out){
|
||||||
Coroutine *result = 0;
|
Coroutine *result = 0;
|
||||||
switch (vals[2]){
|
switch (out->request){
|
||||||
case AppCoroutineRequest_NewFontFace:
|
case AppCoroutineRequest_NewFontFace:
|
||||||
{
|
{
|
||||||
Face_Description *description = ((Face_Description**)vals)[0];
|
Face_Description *description = out->face_description;
|
||||||
Face *face = font_set_new_face(&models->font_set, description);
|
Face *face = font_set_new_face(&models->font_set, description);
|
||||||
result = coroutine_run(&models->coroutines, co, &face->id, vals);
|
App_Coroutine_In in = {};
|
||||||
|
in.face_id = face->id;
|
||||||
|
result = coroutine_run(&models->coroutines, co, &in, out);
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case AppCoroutineRequest_ModifyFace:
|
case AppCoroutineRequest_ModifyFace:
|
||||||
{
|
{
|
||||||
Face_Description *description = ((Face_Description**)vals)[0];
|
Face_Description *description = out->face_description;
|
||||||
Face_ID face_id = ((Face_ID*)vals)[3];
|
Face_ID face_id = out->face_id;
|
||||||
b32 success = font_set_modify_face(&models->font_set, face_id, description);
|
App_Coroutine_In in = {};
|
||||||
result = coroutine_run(&models->coroutines, co, &success, vals);
|
in.success = font_set_modify_face(&models->font_set, face_id, description);
|
||||||
|
result = coroutine_run(&models->coroutines, co, &in, out);
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Coroutine*
|
internal Coroutine*
|
||||||
app_coroutine_run(Models *models, App_Coroutine_Purpose purpose, Coroutine *co, void *in, u32 *out){
|
app_coroutine_run(Models *models, App_Coroutine_Purpose purpose, Coroutine *co, App_Coroutine_In *in, App_Coroutine_Out *out){
|
||||||
Application_Links *app = &models->app_links;
|
Application_Links *app = &models->app_links;
|
||||||
App_Coroutine_State prev_state = get_state(app);
|
App_Coroutine_State prev_state = get_state(app);
|
||||||
app->current_coroutine = co;
|
app->current_coroutine = co;
|
||||||
app->type_coroutine = purpose;
|
app->type_coroutine = purpose;
|
||||||
u32 coroutine_out[4] = {};
|
Coroutine *result = coroutine_run(&models->coroutines, co, in, out);
|
||||||
Coroutine *result = coroutine_run(&models->coroutines, co, in, coroutine_out);
|
for (;result != 0 && out->request != AppCoroutineRequest_None;){
|
||||||
for (;result != 0 && coroutine_out[2] != 0;){
|
result = app_coroutine_handle_request(models, result, out);
|
||||||
result = app_coroutine_handle_request(models, result, coroutine_out);
|
|
||||||
}
|
}
|
||||||
block_copy(out, coroutine_out, sizeof(*out)*2);
|
|
||||||
restore_state(app, prev_state);
|
restore_state(app, prev_state);
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
@ -115,8 +116,8 @@ DELTA_RULE_SIG(fallback_scroll_rule){
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
command_caller(Coroutine *coroutine){
|
command_caller(Coroutine *coroutine){
|
||||||
Command_In *cmd_in = (Command_In*)coroutine->in;
|
App_Coroutine_In *in = (App_Coroutine_In*)coroutine->in;
|
||||||
Models *models = cmd_in->models;
|
Models *models = in->models;
|
||||||
Assert(models->command_caller != 0);
|
Assert(models->command_caller != 0);
|
||||||
models->command_caller(&models->app_links);
|
models->command_caller(&models->app_links);
|
||||||
}
|
}
|
||||||
|
@ -350,10 +351,10 @@ models_init(Thread_Context *tctx){
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
force_abort_coroutine(Models *models, View *view){
|
force_abort_coroutine(Models *models, View *view){
|
||||||
User_Input user_in = {};
|
App_Coroutine_In in = {};
|
||||||
user_in.abort = true;
|
in.user_input.abort = true;
|
||||||
for (u32 j = 0; j < 10 && models->command_coroutine != 0; ++j){
|
for (u32 j = 0; j < 100 && models->command_coroutine != 0; ++j){
|
||||||
models->command_coroutine = app_coroutine_run(models, Co_Command, models->command_coroutine, &user_in, models->command_coroutine_flags);
|
models->command_coroutine = app_coroutine_run(models, Co_Command, models->command_coroutine, &in, &models->coroutine_out);
|
||||||
}
|
}
|
||||||
if (models->command_coroutine != 0){
|
if (models->command_coroutine != 0){
|
||||||
#define M "SERIOUS ERROR: command did not terminate when passed an abort"
|
#define M "SERIOUS ERROR: command did not terminate when passed an abort"
|
||||||
|
@ -370,47 +371,16 @@ launch_command_via_event(Models *models, View *view, Input_Event *event){
|
||||||
Assert(models->command_coroutine == 0);
|
Assert(models->command_coroutine == 0);
|
||||||
Coroutine *command_coroutine = coroutine_create(&models->coroutines, command_caller);
|
Coroutine *command_coroutine = coroutine_create(&models->coroutines, command_caller);
|
||||||
models->command_coroutine = command_coroutine;
|
models->command_coroutine = command_coroutine;
|
||||||
Command_In cmd_in = {models};
|
App_Coroutine_In in = {};
|
||||||
|
in.models = models;
|
||||||
models->event_unhandled = false;
|
models->event_unhandled = false;
|
||||||
models->command_coroutine = app_coroutine_run(models,
|
models->command_coroutine = app_coroutine_run(models,
|
||||||
Co_Command, models->command_coroutine,
|
Co_Command, models->command_coroutine,
|
||||||
&cmd_in, models->command_coroutine_flags);
|
&in, &models->coroutine_out);
|
||||||
if (match_core_code(event, CoreCode_Animate)){
|
if (match_core_code(event, CoreCode_Animate)){
|
||||||
models->animate_next_frame = true;
|
models->animate_next_frame = true;
|
||||||
}
|
}
|
||||||
return(!models->event_unhandled);
|
return(!models->event_unhandled);
|
||||||
|
|
||||||
#if 0
|
|
||||||
b32 result = false;
|
|
||||||
|
|
||||||
Command_Map_ID map = view_get_map(view);
|
|
||||||
Command_Binding cmd_bind = map_get_binding_recursive(&models->mapping, map, event);
|
|
||||||
|
|
||||||
if (cmd_bind.custom != 0){
|
|
||||||
result = true;
|
|
||||||
block_copy_struct(&models->event, event);
|
|
||||||
|
|
||||||
Assert(models->command_coroutine == 0);
|
|
||||||
Coroutine *command_coroutine = coroutine_create(&models->coroutines, command_caller);
|
|
||||||
models->command_coroutine = command_coroutine;
|
|
||||||
|
|
||||||
Command_In cmd_in = {};
|
|
||||||
cmd_in.models = models;
|
|
||||||
cmd_in.bind = cmd_bind;
|
|
||||||
|
|
||||||
models->event_unhandled = false;
|
|
||||||
models->command_coroutine = app_coroutine_run(models, Co_Command, models->command_coroutine, &cmd_in, models->command_coroutine_flags);
|
|
||||||
if (models->event_unhandled){
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match_core_code(event, CoreCode_Animate)){
|
|
||||||
models->animate_next_frame = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -841,17 +811,17 @@ App_Step_Sig(app_step){
|
||||||
block_copy_struct(&models->event, event);
|
block_copy_struct(&models->event, event);
|
||||||
|
|
||||||
Coroutine *command_coroutine = models->command_coroutine;
|
Coroutine *command_coroutine = models->command_coroutine;
|
||||||
Event_Property abort_flags = models->command_coroutine_flags[1];
|
App_Coroutine_Out *co_out = &models->coroutine_out;
|
||||||
Event_Property get_flags = models->command_coroutine_flags[0] | abort_flags;
|
Event_Property abort_flags = co_out->abort_flags;
|
||||||
|
Event_Property get_flags = co_out->get_flags|abort_flags;
|
||||||
|
|
||||||
Event_Property event_flags = get_event_properties(event);
|
Event_Property event_flags = get_event_properties(event);
|
||||||
if ((get_flags&event_flags) != 0){
|
if ((get_flags&event_flags) != 0){
|
||||||
User_Input user_in = {};
|
App_Coroutine_In in = {};
|
||||||
user_in.event = *event;
|
in.user_input.event = *event;
|
||||||
user_in.abort = ((abort_flags & event_flags) != 0);
|
in.user_input.abort = ((abort_flags & event_flags) != 0);
|
||||||
|
|
||||||
models->event_unhandled = false;
|
models->event_unhandled = false;
|
||||||
models->command_coroutine = app_coroutine_run(models, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags);
|
models->command_coroutine = app_coroutine_run(models, Co_Command, command_coroutine, &in, &models->coroutine_out);
|
||||||
if (!HasFlag(event_flags, EventProperty_Animate)){
|
if (!HasFlag(event_flags, EventProperty_Animate)){
|
||||||
models->animate_next_frame = true;
|
models->animate_next_frame = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2088,10 +2088,13 @@ get_user_input(Application_Links *app, Event_Property get_properties, Event_Prop
|
||||||
if (app->type_coroutine == Co_Command){
|
if (app->type_coroutine == Co_Command){
|
||||||
Coroutine *coroutine = (Coroutine*)app->current_coroutine;
|
Coroutine *coroutine = (Coroutine*)app->current_coroutine;
|
||||||
Assert(coroutine != 0);
|
Assert(coroutine != 0);
|
||||||
((u32*)coroutine->out)[0] = get_properties;
|
App_Coroutine_Out *out = (App_Coroutine_Out*)coroutine->out;
|
||||||
((u32*)coroutine->out)[1] = abort_properties;
|
out->request = AppCoroutineRequest_None;
|
||||||
|
out->get_flags = get_properties;
|
||||||
|
out->abort_flags = abort_properties;
|
||||||
coroutine_yield(coroutine);
|
coroutine_yield(coroutine);
|
||||||
result = *(User_Input*)coroutine->in;
|
App_Coroutine_In *in = (App_Coroutine_In*)coroutine->in;
|
||||||
|
result = in->user_input;
|
||||||
}
|
}
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
@ -2549,10 +2552,12 @@ try_create_new_face(Application_Links *app, Face_Description *description)
|
||||||
if (is_running_coroutine(app)){
|
if (is_running_coroutine(app)){
|
||||||
Coroutine *coroutine = (Coroutine*)app->current_coroutine;
|
Coroutine *coroutine = (Coroutine*)app->current_coroutine;
|
||||||
Assert(coroutine != 0);
|
Assert(coroutine != 0);
|
||||||
((Face_Description**)coroutine->out)[0] = description;
|
App_Coroutine_Out *out = (App_Coroutine_Out*)coroutine->out;
|
||||||
((u32*)coroutine->out)[2] = AppCoroutineRequest_NewFontFace;
|
out->request = AppCoroutineRequest_NewFontFace;
|
||||||
|
out->face_description = description;
|
||||||
coroutine_yield(coroutine);
|
coroutine_yield(coroutine);
|
||||||
result = *(Face_ID*)(coroutine->in);
|
App_Coroutine_In *in = (App_Coroutine_In*)coroutine->in;
|
||||||
|
result = in->face_id;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
Face *new_face = font_set_new_face(&models->font_set, description);
|
Face *new_face = font_set_new_face(&models->font_set, description);
|
||||||
|
@ -2569,11 +2574,13 @@ try_modify_face(Application_Links *app, Face_ID id, Face_Description *descriptio
|
||||||
if (is_running_coroutine(app)){
|
if (is_running_coroutine(app)){
|
||||||
Coroutine *coroutine = (Coroutine*)app->current_coroutine;
|
Coroutine *coroutine = (Coroutine*)app->current_coroutine;
|
||||||
Assert(coroutine != 0);
|
Assert(coroutine != 0);
|
||||||
((Face_Description**)coroutine->out)[0] = description;
|
App_Coroutine_Out *out = (App_Coroutine_Out*)coroutine->out;
|
||||||
((u32*)coroutine->out)[2] = AppCoroutineRequest_ModifyFace;
|
out->request = AppCoroutineRequest_NewFontFace;
|
||||||
((u32*)coroutine->out)[3] = id;
|
out->face_description = description;
|
||||||
|
out->face_id = id;
|
||||||
coroutine_yield(coroutine);
|
coroutine_yield(coroutine);
|
||||||
result = *(b32*)(coroutine->in);
|
App_Coroutine_In *in = (App_Coroutine_In*)coroutine->in;
|
||||||
|
result = in->success;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
result = font_set_modify_face(&models->font_set, id, description);
|
result = font_set_modify_face(&models->font_set, id, description);
|
||||||
|
|
|
@ -34,6 +34,36 @@ enum App_State{
|
||||||
APP_STATE_COUNT
|
APP_STATE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct App_Coroutine_In{
|
||||||
|
union{
|
||||||
|
struct Models *models;
|
||||||
|
User_Input user_input;
|
||||||
|
Face_ID face_id;
|
||||||
|
b32 success;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef i32 App_Coroutine_Request;
|
||||||
|
enum{
|
||||||
|
AppCoroutineRequest_None = 0,
|
||||||
|
AppCoroutineRequest_NewFontFace = 1,
|
||||||
|
AppCoroutineRequest_ModifyFace = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct App_Coroutine_Out{
|
||||||
|
App_Coroutine_Request request;
|
||||||
|
union{
|
||||||
|
struct{
|
||||||
|
Event_Property get_flags;
|
||||||
|
Event_Property abort_flags;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
Face_Description *face_description;
|
||||||
|
Face_ID face_id;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
struct Models{
|
struct Models{
|
||||||
Thread_Context *tctx;
|
Thread_Context *tctx;
|
||||||
|
|
||||||
|
@ -47,7 +77,7 @@ struct Models{
|
||||||
|
|
||||||
Coroutine_Group coroutines;
|
Coroutine_Group coroutines;
|
||||||
Coroutine *command_coroutine;
|
Coroutine *command_coroutine;
|
||||||
u32 command_coroutine_flags[2];
|
App_Coroutine_Out coroutine_out;
|
||||||
|
|
||||||
Child_Process_Container child_processes;
|
Child_Process_Container child_processes;
|
||||||
Custom_API config_api;
|
Custom_API config_api;
|
||||||
|
@ -163,10 +193,6 @@ struct App_Coroutine_State{
|
||||||
i32 type;
|
i32 type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Command_In{
|
|
||||||
Models *models;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct File_Init{
|
struct File_Init{
|
||||||
String_Const_u8 name;
|
String_Const_u8 name;
|
||||||
Editing_File **ptr;
|
Editing_File **ptr;
|
||||||
|
@ -194,12 +220,6 @@ enum Command_Line_Mode{
|
||||||
CLMode_Custom
|
CLMode_Custom
|
||||||
};
|
};
|
||||||
|
|
||||||
enum{
|
|
||||||
AppCoroutineRequest_None = 0,
|
|
||||||
AppCoroutineRequest_NewFontFace = 1,
|
|
||||||
AppCoroutineRequest_ModifyFace = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
Loading…
Reference in New Issue