Open joshuaauerbachwatson opened 1 week ago
The problem with the third solution is that the UnigameModel
is retrieved by class name from the environment by many views that are part of the unigame
layer. Only views that are part of the specific app will want the subtype. But, if observed objects are placed in the environment keyed by their type, then both types need to be in the environment.
In fact, this probably means the idea of making UnigameModel
generic also won't work. The unigame
views won't be able to retrieve the object not knowing its precise type.
Some things to note.
unigame
layer, it is sufficient that the UnigameModel
is in the environment and that that model object has access to a game-specific implementation of GameHandle
(stored as any GameHandle
).UnigameModel
and to the app's own model. Both objects must be put into the environment when the app initializes. So, navigation from one to the other doesn't really buy the app layer anything.GameHandle
as long as some type specific to the app does implement it. I will keep this open as a unigame
issue but I think all of the real work to address it must be done in the higher layer.
As it stands now, the unigame model points to the app-specific game handle but not vice versa. So, it is the unigame model that is generally passed through the environment and the app accesses its game handle from there.
As it stand now, the unigame model stores
any GameHandle
so a cast is always needed to get to the app-specific definition. This cast is not only a pain to manage but it interferes with SwiftUI binding logic.I've tried making the
UnigameModel
generic so that it can have aGameHandle
of known type. This might be possible to work out but as I started working it out I found it leads to lots of complications. At theunigame
level, it needs to be instantiated withDummyGameHandle
but at app level, of course, the specific handle must be used. I could come back to this design if there is nothing better.If it were the app-specific
GameHandle
that was in the environment and the navigation worked the other way, some things would be better, but the unigame model still needs a reference to itsGameHandle
, so I would either have to use a weak reference or I would end up with a strong cycle. We don't really want the model or handle to be short-lived and repeatedly allocated, so perhaps a strong cycle is ok and, anyway, a weak reference is no big deal. However, it seems a bit weird that we have to go to this extent to get the relationship right.Another possible design is for the app-specific model to simply subclass
UnigameModel
. The methods thatUnigameModel
now calls in the game handle would be there in pseudo-abstract ("fatal error") form, and would have to be overridden. The class would beopen
rather thanpublic final
.I kind of like the third solution. It might be that we could just ditch the
DummyGameHandle
and leave the fatal error methods in place since, in a preview situation, they would not be called and there is no meaningful way to rununigame
all by itself.