#File I/O in a game loop

10 messages · Page 1 of 1 (latest)

molten gorge
#

Hi everyone! I have a normal old gameloop and I would like to load files to memory without blocking the whole game, essentially loading in the background. How would I go about this? The file is guaranteed to not be needed instantly, but its gotta load at some point! I wrote pseudocode for the desired behaviour below, any help will be much appreciated!

fn main() {
  // Initialisation blah blah

  // Main game loop
  loop {
  // Obvs we wont allways have something loading in the bg
    if let Some(queued_file_op) = file_queued_option { 
      if queued_file_op.is_done() {
          some_struct_somewhere.push(queued_file_op.data());
          file_queued_option = None;
      } else {
        // Draw a loading bar or something idk
      }
    }

    run_the_game_without_being_blocked_by_file_io();
  }

}
tranquil thorn
#

Hello ! As a general design note, in general games are a lot event-driven. So you may want to avoid a large loop with a lot of pollings "ifs" in it. I'd suggest you try to look for a framework that let you launch tasks, raise and catch events instead.

In general though, and as a first step, your approach would work, the only downside could be performance if you begin to stack a lot of checking operations in the mainloop, and, based on execution, could be a little less readable as well.

#

On example crate for async tasks and events is tokio. Tokio is quite popular in networking, but you can ignore the protocol bits if you want. It is essentially allowing to spawn and join asynchronous tasks as needed. Other frameworks could exist doing the same task though

molten gorge
#

thanks for helping! i’ll look into tokio, though wouldn’t that require me annotating lots of my code as async when in reality i have one bit of code that actually needs async?

tranquil thorn
#

You can't call async func from sync func but the other way around is possible. So if you already have a lot of game logic in sync function, you don't necessarily have to convert them.

#

However your main loop will have to be async and so does the main thread of the loading function

#

I admit there is a bit of complexity to that solution. The problem i forsee is also that you will also need to notify your loading is over, and that's not particularly practically done with tokio (you need to create a channel etc.).. Probably there is need to search for something more adapted

molten gorge
#

thank you so much! event listener is very close for my use case, though rolling my own sounds like fun task lol

prime cloak
#

The way I would do this is have a thread dedicated to loading files. Send the file names you need loaded + a oneshot channel through a channel, and have the file content sent back through the oneshot. Or you could put the file content in some kind of cache data structure.

You could even put a tokio runtime on the file-loading thread(s), although that's probably not necessary.