Ho un paio di classi che ho annidato insieme (non nel senso che potresti pensare così nudo con me), per creare ciò che chiamo un oggetto prefabbricato (simile al sistema prefabbricato di Unity).
In questo caso particolare, ho un prefabbricato chiamato BarkingHorse
che contiene le proprie istanze di oggetti CullingBird
e DivingWeasel
. Tutte queste classi derivano da una classe base chiamata RenderObject
. Esiste un oggetto master chiamato Almighty
che gestisce il rendering di singoli oggetti. Ora, quando gestiamo le prefabbricate, la classe Almighty
dovrebbe rimanere all'oscuro degli oggetti contenuti all'interno. Ad esempio:
// Almighty Class
public void Render(RenderObject obj) {
obj.Render();
}
// BarkingHorse Class
public override void Render() {
if (ShowCullingBird)
cullingBird.Render();
if (ShowDivingWeasel)
divingWeasel.Render();
}
Ora, normalmente questo sarebbe semplice ma in questo caso non lo è. BarkingHorse
ha una trama associata ad esso ed è quindi richiesto di informare DeviceContext
prima del rendering. Tuttavia, CullingBird
e DivingWeasel
non hanno textures e sono renderizzati in un drab Color.Gray
a meno che DeviceContext
non sia stato informato che non hanno immagini. Quindi, ad esempio con più codice di base:
// Almighty Class
public void Render(...) {
bool hasTexture = !string.IsNullOrWhiteSpace(obj.ImageFile);
if (hasTexture)
TellDeviceContextAboutTexture();
obj.Render();
if (hasTexture)
TellDeviceContextTextureIsGone();
}
Il codice illustrato sopra funziona bene quando le tre classi sono separate e rese come tali; tuttavia, con il codice sopra riportato, non lo fa poiché DeviceContext
crede ancora che ci sia una trama. So che questo è il problema perché l'ho testato.
La mia classe base RenderObject
contiene le seguenti proprietà che potrebbero rivelarsi utili qui:
public RenderObject Parent { get; protected set; }
public List<RenderObject> Children { get; protected set; }
public void AddChild(RenderObject obj) {
obj.Parent = this;
Children.Add(obj);
}
Tuttavia, non sono sicuro di adottare l'approccio che sto per discutere, poiché credo che dal punto di vista dell'API pubblica potrebbe non essere una buona idea. Questo ci porta al motivo per cui sono qui.
L'idea
Credo di poter aggiungere un bool
al metodo Render
su Almighty
chiamato renderChildren
che potrebbe consentire al metodo di eseguire il rendering dei figli dell'oggetto; ma qui è dove inizia la mia testa a girare sui potenziali inconvenienti. In entrambi i casi, una rappresentazione di base sarebbe:
// Almighty Class
public void Render(RenderObject obj, bool renderChildren) {
bool hasTexture = !string.IsNullOrWhiteSpace(obj.ImageFile);
if (hasTexture)
TellDeviceContextAboutTexture();
obj.Render();
if (hasTexture)
TellDeviceContextTextureIsGone();
if (renderChildren) {
foreach (RenderObject child in obj.Children) {
if (!child.Enabled)
continue;
hasTexture = !string.IsNullOrWhiteSpace(child.ImageFile);
if (hasTexture)
TellDeviceContextAboutTexture();
child.Render();
if (hasTexture)
TellDeviceContextTextureIsGone();
}
}
TellDeviceContextTextureIsGone();
}
Le domande
- Quali sono gli svantaggi di questa nuova idea?
- C'è un modo più intelligente per affrontare questo problema senza aggirare gli argomenti?
- Ciò che lavoro funziona bene da un punto di vista dell'API pubblica o dovrei tornare al tavolo da disegno?
Note
Ho dimenticato di menzionare che una delle mie preoccupazioni è che non è possibile accedere alle proprietà del tipo ShowCullingBird
da quel livello; in tal caso, dovrei creare una proprietà Enabled
o Visible
sulla classe RenderObject
.
Inoltre, se riesci a pensare a un titolo migliore, non esitare a rinominare questo post.