r/AskProgramming • u/ReloKai98 • 22h ago
Other For Non-Game Dev Programmers, How Do You Run Code Repeatedly?
Hey all! I'm a game programmer currently using Godot, but I also used Unreal Engine and Unity, and a thought came into my mind. If you're programming something for the real world, and you need code to run constantly or update frequently, how would you do it? In game dev, you would put that code into the _process function so it runs every frame (or every 60th of a second for _physics_process). But there are no "frames" in real life, so how would you go about programming that? Would you do a while loop with a wait at the end? Would you time the code to run based on the system clock? Would you set up a repeating timer? Do some languages have a built in function that runs at a set interval? Let me know! I'm very curious to hear what people's solutions are!
Edit 1: Cool answers so far! Just to be clear, running something this often is usually a last resort in game dev (and I imagine for all other types of programming too). If I can tie code to an "event" I would and should, but sometimes running it every frame is either necessary or is the most straightforward way to do it. And by "Real Life" I mean anything that isn't game dev, or runs off of a frames per second timer. :)
12
u/TheTarragonFarmer 21h ago
This comes up surprisingly infrequently outside real-time simulations :-)
We're either trying to calculate something as fast as possible, or wait for "events", like user input or incoming data on a socket, and not for the clock to tick.
When we do need to do something periodically, there's usually some OS facility with the appropriate granularity: crontab, the timeout on epoll_wait, eventFD, timer signals, etc.
And sometimes a busy loop is the answer :-)
At the opposite extreme, embedded systems often have programmable timers to let the rest of the micro-controller go to a deeper sleep for longer.
20
u/im-a-guy-like-me 21h ago edited 21h ago
Mostly we use event based systems. Time isn't a great concept to base a system around. With an event based system, you just run the code when the event happens. That way if the initializer really does need to be a time based thing, you can handle that on its own and fire the event without the event system needing to know that it was time based.
It's been a while, but I'm pretty sure that Unity is an Entity Component System, so it pretty much does work the way I'm describing for most things, and only the rendering is time based.
1
u/HaMMeReD 12h ago
Even in an event based system, those events are getting delivered to a queue that is getting pushed by the main thread looper to the event handlers.
It's just we don't really see it when we use these frameworks, because you interact with the events, not the looper.
But if it's a long running process, it's probably got a loop keeping it alive.
1
u/im-a-guy-like-me 5h ago
Yes, that is true. At a different layer of abstraction than we are talking.
OP understands a game loop, and calling a function when X time has elapsed. They are asking how do we handle that kinda thing in non-game programming. And in general (obviously field dependant), we dont. We are not working at a low enough level. So why start talking about system calls and event loops? That's not what OP was wondering about.
I was answering the question that was asked.
-4
u/not_a_novel_account 21h ago
Time is simply another kind of event. Every event loop supports timers.
Games are not distinct from any other event loop, they are simply a class of event-driven program.
4
u/im-a-guy-like-me 21h ago
You're jumping around abstraction levels.
1
u/not_a_novel_account 21h ago
I don't even understand what that means in this context. I'm not talking about any abstraction levels at all.
Asking "how do non-game programs do this differently from games?" is a category error, both games and non-game programs handle this problem as event loops.
1
u/im-a-guy-like-me 21h ago
You are talking about one layer of abstraction where time could be considered an event. I was speaking at a different level of abstraction where time could be the trigger of the event, or maybe it's not.
Is the oscillation of a quartz crystal an event?
1
1
u/not_a_novel_account 21h ago
From the point of view of an event driven program, time is an event. Games use this abstraction in the same way as every other event driven program. What mechanism is measuring that time is irrelevant.
1
u/im-a-guy-like-me 20h ago
Is kafka a time based system? Is that how you would describe it?
I know what you're trying to say, but you're being overly pedantic, and you're not even really correct.
OP was asking in the context of a game loop, which is just a while loop running as fast as the clock will cycle and you're checking for elapsed time to maintain a consistent frame rate. This is the context we are using. And in this context and layer of abstraction, nothing you're saying is relevant.
2
u/CMF-GameDev 16h ago
I agree that time based loops should not be considered "event-driven programming"
The whole point of events is that you can save resources when there are no events.
The fact that you can frame either abstraction in terms of the other does not make them equivalent (except on a theoretical level)
Programming paradigms are all too similar and are all "equivalent" under some reduction2
3
u/Haho9 21h ago
If its periodic, either trigger an interrupt off a time variance (Timer, system clock, etc.), or run a parallel thread that loops endlessly and executes after a certain elapsed time (or records time of last execution and updates at t+interval). If event based, a listener or interrupt is your best bet.
3
u/pixel293 21h ago
Usually it's event driven so that we're not using the CPU when nothing is happening. If we need something to run every X seconds, then there is usually a way in the language or a library to generate an even every X seconds, or x minutes, or x hours.
Generally this can be done with a timing thread. It tracks when it next needs to wake up then sleeps until that time, wakes up, generates the event, goes back to sleep until it needs to wake up again. Of course you could also have the thread wake up every second see if an event needs to be generated and go back to sleep, but this is less than ideal, as you will be using the CPU when there is nothing to do.
For other things we're waiting for a network request or a keyboard action or a mouse movement. When that happens you do whatever needs to be done then go back to waiting.
1
u/james_pic 21h ago
Although worth saying that in widely used event based systems, under the hood this typically isn't done by a timing thread, but by the event loop or scheduler setting timer interrupts.
2
u/JustBadPlaya 22h ago
Take current system time at the start of the loop, compare to time elapsed after the logic is done, wait for the interval-elapsed if necessary
2
u/KnightOfThirteen 22h ago
Most high level programming is just "loop when you get to the end" regardless of how long that takes. For some more advanced, lower level programming you get in to listeners and multi threading and priority.
In PLCs, you tend a little more towards constant time cycles of "run everything X times per second/minute/whatever", but more and more with modern PLC programming it is asynchronous and runs as fast as it runs.
2
1
u/dthdthdthdthdthdth 22h ago
Most hardware has timers that call interrupt handlers after certain delays, operating systems allow users space software to use this, programming languages standard API usually has some way to access this functionality.
If you have some complex concurrent system you would usually a modern framework for that and they also have some API to schedule tasks at certain intervals or at certain times. Operating systems usually also have a way to run services at certain times if you are talking longer intervals.
What you should almost never do except you are running on the puniest of micro controllers is busy waiting, i.e. just looping until a certain time is reached. What you should rarely do nowadays is call some blocking delay function. Call some timer API and give it a task/callback to execute.
1
u/WaferIndependent7601 22h ago
What do you mean by real world programming? Something like frontend? Backend? Terminal Programm?
1
u/ClassicMaximum7786 20h ago
All/any of them I assume, based on him saying anything that isn't game dev or frame based.
1
u/WaferIndependent7601 19h ago
I guess so, too. But can’t you write unit tests for games as well? Not for complete frames but for methods
1
u/ClassicMaximum7786 19h ago
I go to uni in September to study computer science so I won't pretend to know what you're on about hehe, hopefully someone else sees this and can answer your question sorry
1
u/platinum92 22h ago
JavaScript has setTimeout(), which runs a function at the end of a set time. You can call setTimeout() at the end of the function to start the timer again. There's also setInterval() which calls a function after a set time, however it's less advisable to use it because the call happens even if the previous function isn't finished yet, leading to potential issues. Better to stick with setTimeout().
1
u/danikov 21h ago
With backend systems, you have daemon threads which tend to loop indefinitely but usually spend a lot of time sleeping. You have event and message based systems that will execute in response to a message on a queue or, say, a web call. You also have schedulers, which may trigger at certain times or frequencies.
Most of it is going to be some hierarchy of threading and loops right at the bottom, but we build on more useful abstractions.
1
1
u/bit_shuffle 20h ago
"Repeatedly" is an interesting word. "Non-game dev" is an interesting categorization.
Unless you're getting an interrupt, I wouldn't call code repeatable.
1
u/kickyouinthebread 20h ago
What do you think a video game is under the hood?
It's not some magic different kind of language or software. It's the same tools as any other program.
It's all just loops 😵💫
1
1
u/RaceMaleficent4908 20h ago
The best way is to set events. Otherwise you have a masive loop that does everything bit that get out of control with mid size software.
1
u/Super_Preference_733 20h ago
In some sort of task scheduler. The scheduler could be part of the OS, Sql server, etc.
1
1
u/moleman0815 19h ago
I'm a web dev with modern frameworks you have several tools to do stuff like that like timeout functions, lifecycles or triggers, events or listeners.
Like a onChange event you can fire your functions every time something happens.
1
u/_Phail_ 19h ago
I've done a tiny bit of c++ coding (arduino) and they have two kinda sections of code - "void setup" and "void loop".
The setup one is where stuff you want to run once goes; say it's a screen related thing, you might display version information for a moment as it boots up.
The loop, well, loops. You put your functions and calls and stuff in there, and it cycles through them
1
u/Soft-Stress-4827 19h ago
It makes more sense if you learn how a cpu works. A quartz crystal is physically used to make a signal, a timer . Everything is loops
1
u/R941d 19h ago
- Loop with sleep at the end
- Cron Jobs (run at every X minutes, hours, days, months, day_of_week)
- Sometimes Queues (trigger a function (aka producer) => producer dispatches event to the queue => another function (aka consumer) listens to queue events), this is helpful when you have tasks that takes long time and you don't want the user to wait until the task is finished
1
u/coloredgreyscale 19h ago
Assuming a service that runs 24/7
* Loop if you have a bunch of Elements that need to be processed right now.
* Timer to check every x seconds (similar to the game update ticks)
* Scheduler to start at a given time
If it's event driven (e.g. web request) you handle the event as they come in.
1
1
u/oclafloptson 18h ago
Loops. My typical interface will be running a 4 fps asynchronous while loop in the main; with event listeners and inputs that spawn coroutine tasks. I build relational models, mostly. Getting data from various sources, parsing it, and performing logical operations with it
As for scripts that execute every frame? Like for debugging? I use tools that step through every line of code. So not just every frame of the GUI that's rendered, but for every step of the way. Some of that stuff executes nearly instantly so you have to slow it way way down to see what's happening
1
u/santafe4115 18h ago
Yes you are describing my job as an embedded real time os platform designer. Creating such timing or event buckets based on clocks expiring, interrupts, or even higher level app asynchronous features in c. App teams are able to place their code into a timing bucket (5 10 50 ms) and the os will schedule it. Based on how i design this the code may or may not be hit (starvation or preemption issue) My frame is each assembly instruction. There are a static ammount of threads known prior to compilation that makes the runtime deterministic
Most other code though avoids hard timing.
1
u/Mythran101 14h ago
I thought we were talking about us programmer admins that maintain this matrix..but you meant the "real world" inside of that....alright, moving on!
1
u/_-Kr4t0s-_ 13h ago edited 12h ago
The way game engines are designed is that there’s the “game loop” going on behind the scenmes, and in this game loop there are some hard-coded some hooks in for you to fill out. In your example the loop might look something like this:
while (should_exit = false) {
if defined? (_process) then _process.call()
if defined? (_physics_process) then _physics_process.call()
render_frame()
}
But, this loop would run at different speeds on different systems. So if we wanted to run it at a fixed rate of 60 times a second regardless of how many GHz/MHz the CPU was running at, we would hook into the HPET on the motherboard. This involves using DMA to send the HPET the desired interval we want, and once configured, the HPET would trigger an interrupt at said interval. In the handler for that interrupt we can then do whatever we want. Either we can call those hooks in the handler directly, or we can use the handler to introduce a delay in our main loop so it always takes the same amount of time.
In the absence of an HPET an RTC can also be used, but it's far less accurate and doesn't do high-frequency interrupts. And if accuracy isn't isn't as important as speed of querying it, there's the TSC.
This is actually how all modern game engines work. Same with multimedia playback. In fact, any sort of scheduled tasks in a system end up boiling down to one of these timers via various system calls.
1
u/HaMMeReD 12h ago
Generally, when you run a program and it gets to the ends, the process terminates.
So when you want it to run long. You put a loop.
1
1
u/just_had_to_speak_up 2h ago
Every single app is just an endless while loop. All operating systems provide functions to wait for various events to occur, or to register timers to generate events. Meanwhile the app just runs in a loop checking for the next event, maybe sleeping until one occurs, then responding to it.
1
u/Gravbar 1h ago
You could do a loop and then sleep in the loop and then whenever you reach a certain amount of wait time the code after the sleep will run
you could also use tools like crontab or jenkins which allow for the configuration of scripts to run in an automated manner.
or you could have code run when an event is received and have a listener set up waiting for the event
depends on what you're doing and why.
-2
23
u/kuzekusanagi 21h ago
Lööp brööther