97 lines
2.7 KiB
Text
97 lines
2.7 KiB
Text
/*
|
|
Building this program will result in two outputs:
|
|
|
|
1) an executable that controls memory,
|
|
hot-reloading, and the main loop.
|
|
|
|
2) a dynamic library the executable will call into.
|
|
|
|
This program is the library. The "host" executable is
|
|
automatically generated at build-time.
|
|
|
|
If you'd like to see code that isn't heavily annotated,
|
|
see: 'quickstart.jai'
|
|
*/
|
|
|
|
// The global state for this program.
|
|
// It's a pointer because the memory is allocated by the
|
|
// reload module and given to this program when init is called.
|
|
G: *struct {
|
|
allocator: Allocator;
|
|
iterations: int;
|
|
};
|
|
|
|
// The maximum amount of memory your program is allowed to use.
|
|
// Its true size is max_memory - state_size bytes.
|
|
#program_export max_memory: u64 = 4 * Gigabyte;
|
|
|
|
// The current size of the global state structure.
|
|
#program_export state_size: u64 = size_of(type_of(G.*));
|
|
|
|
// Called at program startup or on reload.
|
|
//
|
|
// 'allocator' should be stored in the global state to ensure
|
|
// memory allocated by this program persists between reloads
|
|
// and does not leak.
|
|
//
|
|
// 'full_reset' will be 'true' when the program is expected
|
|
// to (re)initialize its global state, as if the program restarted.
|
|
#program_export init :: (state: *void, allocator: Allocator, full_reset: bool) {
|
|
print("in: init\n");
|
|
|
|
G = state.(type_of(G));
|
|
G.allocator = allocator;
|
|
if !full_reset return;
|
|
|
|
// initialize global state
|
|
G.iterations = 0;
|
|
}
|
|
|
|
// Called once at program startup (after init).
|
|
// Your window/rendering context should be created here.
|
|
#program_export setup :: () {
|
|
print("in: setup\n");
|
|
}
|
|
|
|
// Called in a loop until this program exits.
|
|
// This is your classic update/render procedure.
|
|
//
|
|
// The status this returns tells the reload module
|
|
// what to do after this frame is done.
|
|
//
|
|
// .none: continue running
|
|
// .quit: stop running
|
|
// .soft_reload: reload without reinitializing state
|
|
// .hard_reload: reload then reinitialize state
|
|
//
|
|
// Unless given explicitly, soft_reload or hard_reload
|
|
// will be done automatically depending on how this
|
|
// program has changed between compiles.
|
|
#program_export frame :: () -> reload.Status {
|
|
G.iterations += 1; // change this line and rebuild the program library
|
|
|
|
print("in frame, count: %\n", G.iterations);
|
|
sleep_milliseconds(1000);
|
|
return .none;
|
|
}
|
|
|
|
// Called once at program exit.
|
|
// This will be called before any program memory has been deallocated.
|
|
#program_export teardown :: () {
|
|
print("in: teardown\n");
|
|
}
|
|
|
|
#import "jx";
|
|
|
|
#poke_name reload frame;
|
|
#poke_name reload init;
|
|
#poke_name reload setup;
|
|
#poke_name reload teardown;
|
|
#poke_name reload build_options;
|
|
|
|
// Use the default build options
|
|
build_options :: () => reload.Simple_Build_Options.{};
|
|
|
|
reload :: #import "jx/reload";
|
|
|
|
#import "Basic";
|