publish sim state
This commit is contained in:
parent
13b942efb2
commit
cd40046afc
308
src/app/app.c
308
src/app/app.c
@ -1,308 +0,0 @@
|
|||||||
SharedAppState shared_app_state = ZI;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Write directory
|
|
||||||
|
|
||||||
String InitializeAppWriteDirectory(Arena *arena, String write_dir)
|
|
||||||
{
|
|
||||||
TempArena scratch = BeginScratch(arena);
|
|
||||||
|
|
||||||
/* Create write path */
|
|
||||||
String base_write_dir = P_GetWritePath(scratch.arena);
|
|
||||||
String write_path_fmt = base_write_dir.len > 0 ? Lit("%F/%F/") : Lit("%F%F/");
|
|
||||||
String write_path = FormatString(
|
|
||||||
arena,
|
|
||||||
write_path_fmt,
|
|
||||||
FmtString(base_write_dir),
|
|
||||||
FmtString(write_dir)
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Create write dir if not present */
|
|
||||||
if (!P_IsDir(write_path))
|
|
||||||
{
|
|
||||||
P_MkDir(write_path);
|
|
||||||
/* TODO: handle failure */
|
|
||||||
}
|
|
||||||
|
|
||||||
EndScratch(scratch);
|
|
||||||
|
|
||||||
return write_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
String CatAppWritePath(Arena *arena, String filename)
|
|
||||||
{
|
|
||||||
SharedAppState *g = &shared_app_state;
|
|
||||||
return CatString(arena, g->write_path, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Default settings
|
|
||||||
|
|
||||||
P_WindowSettings GetDefaultAppWindowSettings(P_Window *window)
|
|
||||||
{
|
|
||||||
__prof;
|
|
||||||
|
|
||||||
Vec2I32 monitor_size = P_GetWindowMonitorSize(window);
|
|
||||||
|
|
||||||
i32 width = 1280;
|
|
||||||
i32 height = RoundF32ToI32(width / (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT));
|
|
||||||
i32 x = RoundF32ToI32(monitor_size.x / 2.f - width / 2);
|
|
||||||
i32 y = RoundF32ToI32(monitor_size.y / 2.f - height / 2);
|
|
||||||
|
|
||||||
return (P_WindowSettings)
|
|
||||||
{
|
|
||||||
.title = WINDOW_TITLE,
|
|
||||||
.floating_x = x,
|
|
||||||
.floating_y = y,
|
|
||||||
.floating_width = width,
|
|
||||||
.floating_height = height
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Args
|
|
||||||
|
|
||||||
/* TODO: Remove this and do real argument parsing */
|
|
||||||
AppArgList ParseAppArgs(Arena *arena, String args_str)
|
|
||||||
{
|
|
||||||
AppArgList result = ZI;
|
|
||||||
i64 mode = 0;
|
|
||||||
i64 i = 0;
|
|
||||||
i64 key_start = -1;
|
|
||||||
i64 key_end = -1;
|
|
||||||
i64 value_start = -1;
|
|
||||||
i64 value_end = -1;
|
|
||||||
while (i < (i64)args_str.len)
|
|
||||||
{
|
|
||||||
u8 c = args_str.text[i];
|
|
||||||
switch (mode)
|
|
||||||
{
|
|
||||||
default: break;
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
if (c == '-')
|
|
||||||
{
|
|
||||||
mode = 1;
|
|
||||||
key_start = i + 1;
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
if (c == '=')
|
|
||||||
{
|
|
||||||
key_end = i;
|
|
||||||
value_start = i + 1;
|
|
||||||
mode = 2;
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
if (c == '-' || i == (i64)args_str.len - 1)
|
|
||||||
{
|
|
||||||
if (c == '-')
|
|
||||||
{
|
|
||||||
value_end = i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value_end = i + 1;
|
|
||||||
}
|
|
||||||
if (key_start >= 0 && key_end > key_start && key_end <= (i64)args_str.len && value_start >= 0 && value_end > value_start && value_end <= (i64)args_str.len)
|
|
||||||
{
|
|
||||||
String key = PushString(arena, STRING(key_end - key_start, args_str.text + key_start));
|
|
||||||
String value = PushString(arena, STRING(value_end - value_start, args_str.text + value_start));
|
|
||||||
AppArg *arg = PushStruct(arena, AppArg);
|
|
||||||
arg->key = key;
|
|
||||||
arg->value = value;
|
|
||||||
if (result.last)
|
|
||||||
{
|
|
||||||
result.last->next = arg;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.first = arg;
|
|
||||||
}
|
|
||||||
result.last = arg;
|
|
||||||
++result.count;
|
|
||||||
}
|
|
||||||
key_start = i + 1;
|
|
||||||
mode = 1;
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ @hookdef Entry point
|
|
||||||
|
|
||||||
void Startup(void)
|
|
||||||
{
|
|
||||||
__prof;
|
|
||||||
TempArena scratch = BeginScratchNoConflict();
|
|
||||||
SharedAppState *g = &shared_app_state;
|
|
||||||
|
|
||||||
String args_str = Lit("");
|
|
||||||
AppArgList args = ParseAppArgs(scratch.arena, args_str);
|
|
||||||
String logfile_name = Lit("log.log");
|
|
||||||
String settings_file_name = Lit("settings.txt");
|
|
||||||
String connect_address = ZI;
|
|
||||||
for (AppArg *arg = args.first; arg; arg = arg->next)
|
|
||||||
{
|
|
||||||
String key = arg->key;
|
|
||||||
String value = arg->value;
|
|
||||||
if (MatchString(key, Lit("log")))
|
|
||||||
{
|
|
||||||
logfile_name = value;
|
|
||||||
}
|
|
||||||
else if (MatchString(key, Lit("settings")))
|
|
||||||
{
|
|
||||||
settings_file_name = value;
|
|
||||||
}
|
|
||||||
else if (MatchString(key, Lit("connect")))
|
|
||||||
{
|
|
||||||
connect_address = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LAX args;
|
|
||||||
LAX logfile_name;
|
|
||||||
LAX settings_file_name;
|
|
||||||
LAX connect_address;
|
|
||||||
LAX GetDefaultAppWindowSettings;
|
|
||||||
|
|
||||||
#if !RtcIsEnabled
|
|
||||||
/* Verify test modes aren't left on by accident in release mode */
|
|
||||||
StaticAssert(BITBUFF_DEBUG == 0);
|
|
||||||
StaticAssert(BITBUFF_TEST == 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BITBUFF_TEST
|
|
||||||
BB_Test();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g->arena = AcquireArena(Gibi(64));
|
|
||||||
|
|
||||||
g->write_path = InitializeAppWriteDirectory(g->arena, Lit(WRITE_DIR));
|
|
||||||
|
|
||||||
/* Startup logging */
|
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
TempArena temp = BeginTempArena(scratch.arena);
|
|
||||||
|
|
||||||
String logfile_dir = CatString(temp.arena, g->write_path, Lit("logs/"));
|
|
||||||
String logfile_path = CatString(temp.arena, logfile_dir, logfile_name);
|
|
||||||
P_MkDir(logfile_dir);
|
|
||||||
|
|
||||||
LogStartup(logfile_path);
|
|
||||||
LogInfoF("Start of logs");
|
|
||||||
EndTempArena(temp);
|
|
||||||
}
|
|
||||||
LogInfoF("App started with args \"%F\" (%F parsed)", FmtString(args_str), FmtUint(args.count));
|
|
||||||
for (AppArg *arg = args.first; arg; arg = arg->next)
|
|
||||||
{
|
|
||||||
LogInfoF("Parsed arg: key = \"%F\", value = \"%F\"", FmtString(arg->key), FmtString(arg->value));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Read window settings from file */
|
|
||||||
{
|
|
||||||
TempArena temp = BeginTempArena(scratch.arena);
|
|
||||||
|
|
||||||
P_WindowSettings window_settings = ZI;
|
|
||||||
String settings_path = CatAppWritePath(temp.arena, settings_file_name);
|
|
||||||
LogInfoF("Looking for settings file \"%F\"", FmtString(settings_path));
|
|
||||||
if (P_IsFile(settings_path))
|
|
||||||
{
|
|
||||||
LogInfoF("Settings file found");
|
|
||||||
P_File settings_file = P_OpenFileRead(settings_path);
|
|
||||||
String file_data = P_ReadFile(temp.arena, settings_file);
|
|
||||||
P_CloseFile(settings_file);
|
|
||||||
LogInfoF("Deserializing settings file data: %F", FmtString(file_data));
|
|
||||||
String error = ZI;
|
|
||||||
P_WindowSettings *deser = SETTINGS_WindowSettingsFromString(temp.arena, file_data, &error);
|
|
||||||
if (error.len > 0)
|
|
||||||
{
|
|
||||||
LogInfoF("Failed to load settings file with error - %F", FmtString(error));
|
|
||||||
String msg = StringF(temp.arena,
|
|
||||||
"Failed to loading settings file \"%F\":\n"
|
|
||||||
"------------\n"
|
|
||||||
"%F\n"
|
|
||||||
"------------\n"
|
|
||||||
"To stop this error from appearing, either fix the issue above or delete the file from the system.",
|
|
||||||
FmtString(settings_path),
|
|
||||||
FmtString(error));
|
|
||||||
Panic(msg);
|
|
||||||
}
|
|
||||||
LogInfoF("Settings file loaded successfully");
|
|
||||||
window_settings = *deser;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogInfoF("Settings file not found, loading default");
|
|
||||||
window_settings = GetDefaultAppWindowSettings(window);
|
|
||||||
}
|
|
||||||
PushStringToBuff(StringFromArray(window_settings.title), Lit(WINDOW_TITLE));
|
|
||||||
P_UpdateWindowSettings(window, &window_settings);
|
|
||||||
|
|
||||||
EndTempArena(temp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Global systems */
|
|
||||||
RES_Startup();
|
|
||||||
W_Startup();
|
|
||||||
GPU_Startup();
|
|
||||||
|
|
||||||
/* Subsystems */
|
|
||||||
AC_StartupReceipt asset_cache_sr = AC_Startup();
|
|
||||||
TTF_Startup();
|
|
||||||
S_StartupReceipt sprite_sr = S_Startup();
|
|
||||||
MIX_StartupReceipt mixer_sr = MIX_Startup();
|
|
||||||
D_StartupReceipt draw_sr = D_Startup();
|
|
||||||
|
|
||||||
/* Interface systems */
|
|
||||||
SimStartupReceipt sim_sr = StartupSim();
|
|
||||||
PB_StartupReceipt playback_sr = PB_Startup(&mixer_sr);
|
|
||||||
UserStartupReceipt user_sr = StartupUser(&sprite_sr, &draw_sr, &asset_cache_sr, &mixer_sr, &sim_sr, connect_address);
|
|
||||||
#endif
|
|
||||||
PpMain();
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Write window settings to file */
|
|
||||||
{
|
|
||||||
__profn("Write settings file");
|
|
||||||
TempArena temp = BeginTempArena(scratch.arena);
|
|
||||||
|
|
||||||
String window_settings_path = CatAppWritePath(temp.arena, settings_file_name);
|
|
||||||
|
|
||||||
P_WindowSettings settings = P_GetWindowSettings(window);
|
|
||||||
String str = SETTINGS_StringFromWindowSettings(temp.arena, &settings);
|
|
||||||
LogInfoF("Serialized window settings: %F", FmtString(str));
|
|
||||||
|
|
||||||
LogInfoF("Writing settings file to path \"%F\"", FmtString(window_settings_path));
|
|
||||||
P_File settings_file = P_OpenFileWrite(window_settings_path);
|
|
||||||
P_WriteFile(settings_file, str);
|
|
||||||
P_CloseFile(settings_file);
|
|
||||||
LogInfoF("Finished writing settings file");
|
|
||||||
|
|
||||||
EndTempArena(temp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
P_ReleaseWindow(window);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//LogInfoF("Program exited normally");
|
|
||||||
EndScratch(scratch);
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ App arg types
|
|
||||||
|
|
||||||
Struct(AppArg)
|
|
||||||
{
|
|
||||||
String key;
|
|
||||||
String value;
|
|
||||||
AppArg *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(AppArgList)
|
|
||||||
{
|
|
||||||
AppArg *first;
|
|
||||||
AppArg *last;
|
|
||||||
u64 count;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ State types
|
|
||||||
|
|
||||||
Struct(SharedAppState)
|
|
||||||
{
|
|
||||||
Arena *arena;
|
|
||||||
String write_path;
|
|
||||||
} extern shared_app_state;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ App functions
|
|
||||||
|
|
||||||
//- Write path
|
|
||||||
String InitializeAppWriteDirectory(Arena *arena, String write_dir);
|
|
||||||
String CatAppWritePath(Arena *arena, String filename);
|
|
||||||
|
|
||||||
//- Default window settings
|
|
||||||
P_WindowSettings GetDefaultAppWindowSettings(P_Window *window);
|
|
||||||
|
|
||||||
//- App args
|
|
||||||
|
|
||||||
AppArgList ParseAppArgs(Arena *arena, String args_str);
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
@Layer app
|
|
||||||
|
|
||||||
//- Dependencies
|
|
||||||
@Dep base
|
|
||||||
@Dep platform
|
|
||||||
@Dep ttf
|
|
||||||
@Dep gpu
|
|
||||||
@Dep sprite
|
|
||||||
@Dep watch
|
|
||||||
@Dep sound
|
|
||||||
@Dep font
|
|
||||||
@Dep asset_cache
|
|
||||||
@Dep mixer
|
|
||||||
@Dep settings
|
|
||||||
@Dep net
|
|
||||||
@Dep resource
|
|
||||||
@Dep playback
|
|
||||||
@Dep pp
|
|
||||||
|
|
||||||
//- Api
|
|
||||||
@IncludeC app.h
|
|
||||||
|
|
||||||
//- Impl
|
|
||||||
@IncludeC app.c
|
|
||||||
@ -7,7 +7,6 @@
|
|||||||
@Dep collider
|
@Dep collider
|
||||||
@Dep net
|
@Dep net
|
||||||
@Dep mixer
|
@Dep mixer
|
||||||
@Dep rendertest
|
|
||||||
@Dep playback
|
@Dep playback
|
||||||
@Dep platform
|
@Dep platform
|
||||||
@Dep window
|
@Dep window
|
||||||
|
|||||||
@ -1,16 +1,22 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Key types
|
//~ Key types
|
||||||
|
|
||||||
#define PP_NilKey ((PP_Key) { 0 })
|
#define PP_NilEntKey ((PP_EntKey) { 0 })
|
||||||
|
#define PP_RootEntKey ((PP_EntKey) { .v.hi = 0x75ebb7a47d1ca753, .v.lo = 0x2d505fc8961e5576 })
|
||||||
|
|
||||||
Struct(PP_EntKey)
|
Struct(PP_EntKey)
|
||||||
{
|
{
|
||||||
U128 v;
|
U128 v;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(PP_EntNum)
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Shape types
|
||||||
|
|
||||||
|
Struct(PP_Shape)
|
||||||
{
|
{
|
||||||
u64 v;
|
f32 radius;
|
||||||
|
u32 points_count;
|
||||||
|
Vec2 points[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -36,6 +42,8 @@ Struct(PP_Ent)
|
|||||||
PP_EntKey prev;
|
PP_EntKey prev;
|
||||||
|
|
||||||
PP_EntKey key;
|
PP_EntKey key;
|
||||||
|
|
||||||
|
PP_Shape shape;
|
||||||
} extern Readonly PP_nil_ent;
|
} extern Readonly PP_nil_ent;
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
@ -55,12 +63,11 @@ Struct(PP_EntList)
|
|||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Ent lookup types
|
//~ Lookup types
|
||||||
|
|
||||||
Struct(PP_EntLookupBin)
|
Struct(PP_EntLookupBin)
|
||||||
{
|
{
|
||||||
PP_EntNum first;
|
i32 _;
|
||||||
PP_EntNum last;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -69,12 +76,14 @@ Struct(PP_EntLookupBin)
|
|||||||
Struct(PP_World)
|
Struct(PP_World)
|
||||||
{
|
{
|
||||||
i64 tick;
|
i64 tick;
|
||||||
|
|
||||||
PP_Ent *ents;
|
PP_Ent *ents;
|
||||||
i64 ents_count;
|
i64 ents_count;
|
||||||
|
};
|
||||||
|
|
||||||
PP_EntLookupBin *bins;
|
Struct(PP_WorldNode)
|
||||||
i64 bins_count;
|
{
|
||||||
|
PP_WorldNode *next;
|
||||||
|
PP_World world;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -8,10 +8,15 @@ void PP_Startup(void)
|
|||||||
PP_SharedState *shared = &PP_shared_state;
|
PP_SharedState *shared = &PP_shared_state;
|
||||||
|
|
||||||
/* Initialize shared state */
|
/* Initialize shared state */
|
||||||
for (u64 i = 0; i < countof(shared->v2s); ++i)
|
for (u64 i = 0; i < countof(shared->sim_input_states); ++i)
|
||||||
{
|
{
|
||||||
PP_VisToSimState *v2s = &shared->v2s[i];
|
PP_SimInputState *input = &shared->sim_input_states[i];
|
||||||
v2s->arena = AcquireArena(Gibi(64));
|
input->arena = AcquireArena(Gibi(64));
|
||||||
|
}
|
||||||
|
for (u64 i = 0; i < countof(shared->sim_output_states); ++i)
|
||||||
|
{
|
||||||
|
PP_SimOutputState *output = &shared->sim_output_states[i];
|
||||||
|
output->arena = AcquireArena(Gibi(64));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create job pools */
|
/* Create job pools */
|
||||||
@ -40,6 +45,27 @@ JobDef(PP_SimWorker, sig, job_id)
|
|||||||
Arena *frame_arena = AcquireArena(Gibi(64));
|
Arena *frame_arena = AcquireArena(Gibi(64));
|
||||||
Arena *perm = PermArena();
|
Arena *perm = PermArena();
|
||||||
|
|
||||||
|
//- World data
|
||||||
|
Arena *ents_arena = AcquireArena(Gibi(64));
|
||||||
|
PP_Ent *ents = ArenaFirst(ents_arena, PP_Ent);
|
||||||
|
i64 tick = 0;
|
||||||
|
|
||||||
|
/* Create root ent */
|
||||||
|
{
|
||||||
|
PP_Ent *root_ent = PushStruct(ents_arena, PP_Ent);
|
||||||
|
*root_ent = PP_nil_ent;
|
||||||
|
root_ent->key = PP_RootEntKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create test ent */
|
||||||
|
{
|
||||||
|
PP_Ent *test_ent = PushStruct(ents_arena, PP_Ent);
|
||||||
|
*test_ent = PP_nil_ent;
|
||||||
|
test_ent->parent = PP_RootEntKey;
|
||||||
|
test_ent->shape.points_count = 1;
|
||||||
|
test_ent->shape.radius = 0.25;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Begin sim loop
|
//- Begin sim loop
|
||||||
|
|
||||||
@ -56,22 +82,22 @@ JobDef(PP_SimWorker, sig, job_id)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Pop sim commands
|
//- Pop sim commands
|
||||||
|
|
||||||
PP_VisToSimState *v2s = 0;
|
PP_SimInputState *input = 0;
|
||||||
LockTicketMutex(&shared->v2s_back_tm);
|
LockTicketMutex(&shared->sim_input_back_tm);
|
||||||
{
|
{
|
||||||
v2s = &shared->v2s[shared->v2s_back_idx];
|
input = &shared->sim_input_states[shared->sim_input_back_idx];
|
||||||
++shared->v2s_back_idx;
|
++shared->sim_input_back_idx;
|
||||||
if (shared->v2s_back_idx >= countof(shared->v2s))
|
if (shared->sim_input_back_idx >= countof(shared->sim_input_states))
|
||||||
{
|
{
|
||||||
shared->v2s_back_idx = 0;
|
shared->sim_input_back_idx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnlockTicketMutex(&shared->v2s_back_tm);
|
UnlockTicketMutex(&shared->sim_input_back_tm);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Process sim commands
|
//- Process sim commands
|
||||||
|
|
||||||
for (PP_SimCmdNode *cmd_node = v2s->first_cmd_node; cmd_node; cmd_node = cmd_node->next)
|
for (PP_SimCmdNode *cmd_node = input->first_cmd_node; cmd_node; cmd_node = cmd_node->next)
|
||||||
{
|
{
|
||||||
PP_SimCmd cmd = cmd_node->cmd;
|
PP_SimCmd cmd = cmd_node->cmd;
|
||||||
switch (cmd.kind)
|
switch (cmd.kind)
|
||||||
@ -83,28 +109,51 @@ JobDef(PP_SimWorker, sig, job_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Publish sim state
|
||||||
|
|
||||||
|
LockTicketMutex(&shared->sim_output_back_tm);
|
||||||
|
{
|
||||||
|
PP_SimOutputState *output = &shared->sim_output_states[shared->sim_output_back_idx];
|
||||||
|
PP_WorldNode *world_node = PushStruct(output->arena, PP_WorldNode);
|
||||||
|
PP_World *world = &world_node->world;
|
||||||
|
SllQueuePush(output->first_world_node, output->last_world_node, world_node);
|
||||||
|
++output->worlds_count;
|
||||||
|
world->ents_count = ArenaCount(ents_arena, PP_Ent);
|
||||||
|
world->tick = tick;
|
||||||
|
world->ents = PushStructsNoZero(output->arena, PP_Ent, world->ents_count);
|
||||||
|
for (i64 ent_idx = 0; ent_idx < world->ents_count; ++ent_idx)
|
||||||
|
{
|
||||||
|
PP_Ent *ent = &ents[ent_idx];
|
||||||
|
world->ents[ent_idx] = *ent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnlockTicketMutex(&shared->sim_output_back_tm);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- End sim frame
|
//- End sim frame
|
||||||
|
|
||||||
/* Reset front v2s */
|
/* Reset front input state */
|
||||||
{
|
{
|
||||||
Arena *arena = v2s->arena;
|
Arena *arena = input->arena;
|
||||||
ResetArena(arena);
|
ResetArena(arena);
|
||||||
ZeroStruct(v2s);
|
ZeroStruct(input);
|
||||||
v2s->arena = arena;
|
input->arena = arena;
|
||||||
}
|
}
|
||||||
|
|
||||||
shutdown = Atomic32Fetch(&shared->shutdown);
|
|
||||||
|
|
||||||
i64 frame_end_ns = TimeNs();
|
i64 frame_end_ns = TimeNs();
|
||||||
|
++tick;
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Sleep
|
//- Sleep
|
||||||
|
|
||||||
|
if (!Atomic32Fetch(&shared->shutdown))
|
||||||
{
|
{
|
||||||
i64 step_dt_ns = NsFromSeconds(1) / SIM_TICKS_PER_SECOND;
|
i64 step_dt_ns = NsFromSeconds(1) / SIM_TICKS_PER_SECOND;
|
||||||
P_SleepFrame(frame_begin_ns, step_dt_ns);
|
P_SleepFrame(frame_begin_ns, step_dt_ns);
|
||||||
}
|
}
|
||||||
|
shutdown = Atomic32Fetch(&shared->shutdown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,6 +234,17 @@ JobDef(PP_VisWorker, sig, job_id)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Begin vis loop
|
//- Begin vis loop
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Arena *ents_arena = AcquireArena(Gibi(64));
|
||||||
|
PP_Ent *ents = ArenaFirst(ents_arena, PP_Ent);
|
||||||
|
i64 tick = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
b32 shutdown = 0;
|
b32 shutdown = 0;
|
||||||
while (!shutdown)
|
while (!shutdown)
|
||||||
{
|
{
|
||||||
@ -218,6 +278,33 @@ JobDef(PP_VisWorker, sig, job_id)
|
|||||||
UI_Push(Height, UI_GROW(1, 0));
|
UI_Push(Height, UI_GROW(1, 0));
|
||||||
UI_Push(Parent, UI_BuildColumnEx(UI_KeyF("AAH")));
|
UI_Push(Parent, UI_BuildColumnEx(UI_KeyF("AAH")));
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Pop sim output
|
||||||
|
|
||||||
|
PP_SimOutputState *sim_output = 0;
|
||||||
|
LockTicketMutex(&shared->sim_output_back_tm);
|
||||||
|
{
|
||||||
|
sim_output = &shared->sim_output_states[shared->sim_output_back_idx];
|
||||||
|
++shared->sim_output_back_idx;
|
||||||
|
if (shared->sim_output_back_idx >= countof(shared->sim_output_states))
|
||||||
|
{
|
||||||
|
shared->sim_output_back_idx = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnlockTicketMutex(&shared->sim_output_back_tm);
|
||||||
|
|
||||||
|
{
|
||||||
|
PP_WorldNode *last = sim_output->last_world_node;
|
||||||
|
if (last && last->world.tick > tick)
|
||||||
|
{
|
||||||
|
ResetArena(ents_arena);
|
||||||
|
ents = PushStructsNoZero(ents_arena, PP_Ent, last->world.ents_count);
|
||||||
|
CopyStructs(ents, last->world.ents, last->world.ents_count);
|
||||||
|
tick = last->world.tick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Process controller events vis cmds
|
//- Process controller events vis cmds
|
||||||
|
|
||||||
@ -370,9 +457,9 @@ JobDef(PP_VisWorker, sig, job_id)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Submit sim commands
|
//- Submit sim commands
|
||||||
|
|
||||||
LockTicketMutex(&shared->v2s_back_tm);
|
LockTicketMutex(&shared->sim_input_back_tm);
|
||||||
{
|
{
|
||||||
PP_VisToSimState *v2s = &shared->v2s[shared->v2s_back_idx];
|
PP_SimInputState *v2s = &shared->sim_input_states[shared->sim_input_back_idx];
|
||||||
for (PP_EntListNode *ent_node = spawn_ents.first; ent_node; ent_node = ent_node->next)
|
for (PP_EntListNode *ent_node = spawn_ents.first; ent_node; ent_node = ent_node->next)
|
||||||
{
|
{
|
||||||
PP_SimCmdNode *cmd_node = PushStruct(v2s->arena, PP_SimCmdNode);
|
PP_SimCmdNode *cmd_node = PushStruct(v2s->arena, PP_SimCmdNode);
|
||||||
@ -382,7 +469,7 @@ JobDef(PP_VisWorker, sig, job_id)
|
|||||||
++v2s->cmds_count;
|
++v2s->cmds_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnlockTicketMutex(&shared->v2s_back_tm);
|
UnlockTicketMutex(&shared->sim_input_back_tm);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- End vis frame
|
//- End vis frame
|
||||||
|
|||||||
@ -94,9 +94,10 @@ Global Readonly PP_VisCmdDesc PP_vis_cmd_descs[PP_VisCmdKind_Count] = {
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ State types
|
//~ State types
|
||||||
|
|
||||||
#define PP_VisToSimStatesCount 2
|
#define PP_SimInputStatesCount 2
|
||||||
|
#define PP_SimOutputStatesCount 2
|
||||||
|
|
||||||
Struct(PP_VisToSimState)
|
Struct(PP_SimInputState)
|
||||||
{
|
{
|
||||||
Arena *arena;
|
Arena *arena;
|
||||||
PP_SimCmdNode *first_cmd_node;
|
PP_SimCmdNode *first_cmd_node;
|
||||||
@ -104,6 +105,14 @@ Struct(PP_VisToSimState)
|
|||||||
u64 cmds_count;
|
u64 cmds_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Struct(PP_SimOutputState)
|
||||||
|
{
|
||||||
|
Arena *arena;
|
||||||
|
PP_WorldNode *first_world_node;
|
||||||
|
PP_WorldNode *last_world_node;
|
||||||
|
u64 worlds_count;
|
||||||
|
};
|
||||||
|
|
||||||
Struct(PP_SharedState)
|
Struct(PP_SharedState)
|
||||||
{
|
{
|
||||||
Atomic32 shutdown;
|
Atomic32 shutdown;
|
||||||
@ -111,9 +120,14 @@ Struct(PP_SharedState)
|
|||||||
i64 workers_count;
|
i64 workers_count;
|
||||||
|
|
||||||
//- Vis -> Sim
|
//- Vis -> Sim
|
||||||
TicketMutex v2s_back_tm;
|
TicketMutex sim_input_back_tm;
|
||||||
i32 v2s_back_idx;
|
i32 sim_input_back_idx;
|
||||||
PP_VisToSimState v2s[PP_VisToSimStatesCount];
|
PP_SimInputState sim_input_states[PP_SimInputStatesCount];
|
||||||
|
|
||||||
|
//- Sim -> Vis
|
||||||
|
TicketMutex sim_output_back_tm;
|
||||||
|
i32 sim_output_back_idx;
|
||||||
|
PP_SimOutputState sim_output_states[PP_SimOutputStatesCount];
|
||||||
|
|
||||||
} extern PP_shared_state;
|
} extern PP_shared_state;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Startup
|
|
||||||
|
|
||||||
void RT_Startup(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Startup
|
|
||||||
|
|
||||||
void RT_Startup(void);
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
@Layer rendertest
|
|
||||||
|
|
||||||
//- Dependencies
|
|
||||||
@Dep gpu
|
|
||||||
@Dep sprite
|
|
||||||
@Dep font
|
|
||||||
@Dep collider
|
|
||||||
|
|
||||||
//- Api
|
|
||||||
@IncludeC rendertest.h
|
|
||||||
|
|
||||||
//- Impl
|
|
||||||
@IncludeC rendertest.c
|
|
||||||
|
|
||||||
//- Startup
|
|
||||||
@Startup RT_Startup
|
|
||||||
Loading…
Reference in New Issue
Block a user