Who's in charge, the GUI or the program

snotnose

Ars Tribunus Militum
2,747
Subscriptor
I've noticed in my programs sometimes the GUI controls things and calls the guts, other times the guts control the program and calls the GUI. Take Sudoku for example. You could write a solver such that the GUI instantiates the solver, or you could have the solver instantiate the GUI. Seems an argument can be made either way for each being a has-a and an is-a.

What say you, does main() go in your GUI, or the guts?

I've found I tend to solve the interesting problem first, first solved is the boss. For Mandelbrot the guts were more interesting, I didn't throw a GUI on it until the guts were pretty much finished. For Sudoku the GUI was interesting and the solver was put in at the end.
 

fitten

Ars Legatus Legionis
52,251
Subscriptor++
Hard to say. When I'm messing around on my own stuff, I'll usually code the "engine" and then provide various methods of interacting with the engine... GUI, cmdline, whatever (sometimes multiple ways). But I think more generally it's how much interaction a user needs. If the user is required to 'do a lot of stuff', then the GUI is the driver and the guts need to respond to user input as the user inputs it. Say a Tic-Tac-Toe game, I'd most likely make a GUI that plays the game (state machine or whatever inside). If it's a "solver" type thing where the user sets up starting conditions or whatever and then submits all the starting data/parameters to the engine to solve and the results returned to the GUI to visualize, then it's more of an engine that is less coupled to the visualizer. I guess an "engine" Tic-Tac-Toe game for me would be where the UI submits the board to the engine and the engine returns a new board with its move on it. I don't know if I'm describing it well, but that's how I usually think about it in my mind.

Where I work now, that's kind of how what we do works. We have a big engine that runs on input files and writes output files. Users can write their own input files and kick it off via cmdline if they want (which is useful for when they want to script a bunch of stuff), but we also have a GUI that does a bunch of stuff, including creating all the input files for the user and kicking off the engine on them. Then it can take the output files and render them graphically, tabularly, or whatever is appropriate for the tasks it was asked to do.
 

Apteris

Ars Tribunus Angusticlavius
8,938
Subscriptor
Who's in charge
The program.

Virtually every non-trivial piece of software you use is doing a hundred things a second in the background, while you (the fleshy, slow human) decide which key or mouse button to press next. "The user pressed a key!" exclaims one subroutine. "Ah, my grandfather told me of this happening once, when he was a boy.", replies another.

You can start ProcMon and look at virtually any Windows executable, even something as simple as CalculatorApp.exe, to see this in action. Or you can attach a debugger to a piece of software to see all of the threads it has in flight at any one time.

For the purposes of architecting your program, it's usually recommended -- and I agree with this -- to regard a GUI as just one of several possible input interfaces to your program, the better to separate concerns. Not so much "A drives B" but rather "this process needs to be able to do these things in between when it is started and stopped, one of these things being accepting user input, another being doing computations, probably in some sort of 'background' as we don't want the program to become unresponsive".
 
  • Like
Reactions: VividVerism

Lt_Storm

Ars Praefectus
16,294
Subscriptor++
So, this is what the MVC and MVVC patterns are all about, so that is what you should read up on. But, the short version is that the model (the sudoku solver), is instantiated and handed to the controller. The controller then interrogates the model and sets up the view with the necessary information to display. The view then sends user input to the controller which preforms the correct operations on the model to preform whatever the user has asked, when finished, updates the view by feeding it new information.

The important part: you don't want the gui components directly doing things like instantiating the solver because that means that if you ever wanted to, say, solve batches of sudoku puzzles, it wouldn't really be possible. Also, it makes testing really really really hard, to the point where it makes sense to minimize the things done by gui components (both the view and the controller) just for the sake of making testing easier.
 
  • Like
Reactions: timezon3
Want to twist your brain even more? Ask yourself "Who's responsible for the data?". Do you need a shadow copy of the data if it's all already in the GUI? How do you ensure the data is in sync? In the web-dev world, this is a massive issue. HTMX's philosophy is that the backend is the source of data and it spits out the GUI code in segments to update the interface. So, in this case, the backend controls the GUI.

In Windows land, early GUI controls contained the data. They were also limited to a few KB of data and got really slow really quick. The basic ListBox was/is far from robust. The newer paradigm is for a control to have a routine that asks for the data of a single item when drawing the interface. So, data is sent on an as-needed basis. I never did enough X Windows to remember how it worked, but I'd assume the server/client relationship isn't going to want the entire data.

For games, it's all backend. The GUI API (DirectX, OpenGL, Vulcan, etc.) is just there to draw stuff. You still needs something to make menu screens, but this isn't the bulk of the work.
 

ShuggyCoUk

Ars Tribunus Angusticlavius
9,975
Subscriptor++
So long as they are separate in some way so you can:

1. Change your mind about something only relevant to one or the other and not have to care about the other one
2. use one without the other if desired...

Don't obsesses about specific approaches/patterns for this too much till you see how you can achieve it yourself. Then start looking for alternative views on the world
 
  • Like
Reactions: Haas Bioroid

hanser

Ars Legatus Legionis
41,687
Subscriptor++
I tend to think of "client" and "server", where the client can ask the server to do things, but the server is the source of truth about state, and has control over the data. The client can't force the server to do things, and the server generally has a composable, preferably-idempotent API that the client knows how to interact with.

The rest is implementation details.