/*
   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";
