hey guys I'm writing a tui game in rust and I've written a lot of architecture and a lot of UI for it but im looking to refactor my code and practice good design patterns and principles and to remove any uses of Rc<RefCell<T>> I have lying around. In this current instance I have a SceneManager that handles structs of trait GameScene that have describe all of the usual functions: update, init, enter, ..., key_event, mouse_event and so on, and the SceneManager also has functions that match these and run that function for the current scene (or in init's case, for every scene). now the main issue was that I pass around an Rc<RefCell<Universe>> all over the place through these functions as if I was writing a C++ game engine and I really didn't want to do this and saw it as a good exercise to practise some more intermediate rust concepts. Universe is the big game logic handler here.
So I started refactoring. I decomposed SceneManager into a SceneLogger, SceneState and the other, always active, UI elements. And then I decided that I could also decouple the GameScenes from direct game logic and also pull the Universe borrow semantics into its own struct called SceneContext that held a few things like a SceneView which gives frame deltas and the "screen" area and made it so the &mut Universe was not public facing and was interfaced via an enum GameCommand. Then to further decouple I brung in the SceneState to SceneContext that allowed Universe to instigate scene transitions by returning an Option<SceneCommand> from it's own Universe::execute_command(&mut Self, GameCommand) function. This all started getting pretty complicated and once again functionality started feeling a bit like a muddled and I wasn't really sure where to take it until I just hit a classic borrowchk error that came from creating the SceneContext in SceneManager, using its own SceneState to instantiate it, then using SceneState (which contains, well the scenes and state), to run the function, i.e., render(..).
then I hit the SceneContext::execute_command(cmd: GameCommand) passes to => Universe::execute_command(cmd: GameCommand)
which bubbles up the return type SceneCommand from Universe to SceneContext to SceneManager
I feel like I'm heading in the wrong direction here, I almost feel like a java developer but this code also feels a lot better than what I have been writing. But I'm kind of lost, sorry for the ramble. I can always provide code if anyone is willing enough to read this but I'd appreciate some pointers towards good design pattern resources that don't just have the same old AbstractCarFactory with functions makeSUV, makeCar, ...; the dreaded "real world" examples with interface IAnimal
I'd appreciate anything though from naming convention critique onwards