I have a couple of classes that I've nested together (not in the sense you may think so bare with me), to create what I call a prefab object (similar to Unity's prefab system).
In this particular case, I have a prefab called BarkingHorse
that contains its own instances of objects CullingBird
and DivingWeasel
. All of these classes derive from a base class called RenderObject
. There is a master object called Almighty
that manages the rendering of individual objects. Now, when handling prefabs, the Almighty
class should remain ignorant of objects contained within. For example:
// Almighty Class
public void Render(RenderObject obj) {
obj.Render();
}
// BarkingHorse Class
public override void Render() {
if (ShowCullingBird)
cullingBird.Render();
if (ShowDivingWeasel)
divingWeasel.Render();
}
Now, normally this would be straight forward but in this case it isn't. BarkingHorse
has a texture associated with it and is thus required to inform the DeviceContext
prior to rendering. However, CullingBird
and DivingWeasel
do not have textures, and are rendered in a drab Color.Gray
unless the DeviceContext
has been notified that they do not have images. So for example with more basic code:
// Almighty Class
public void Render(...) {
bool hasTexture = !string.IsNullOrWhiteSpace(obj.ImageFile);
if (hasTexture)
TellDeviceContextAboutTexture();
obj.Render();
if (hasTexture)
TellDeviceContextTextureIsGone();
}
The code depicted above works well when the three class are separated and rendered as such; however, with the above-above code it does not as the DeviceContext
still believes there is a texture. I know this is the issue because I've tested it.
My base class RenderObject
contains the following properties that could prove to be useful here:
public RenderObject Parent { get; protected set; }
public List<RenderObject> Children { get; protected set; }
public void AddChild(RenderObject obj) {
obj.Parent = this;
Children.Add(obj);
}
However, I am unsure about taking the approach I am about to discuss as I believe from a public API standpoint this may not be a good idea. This leads us to the reason I'm here.
The Idea
I believe I could add a bool
to the Render
method on Almighty
called renderChildren
that could allow the method to render the object's children; but this is where my head begins spinning about the potential drawbacks. Either way, a basic representation would be:
// 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();
}
The Questions
- What are the drawbacks of this new idea?
- Is there a smarter way to tackle this without passing around arguments?
- Will what I have work fine from a public API standpoint or should I go back to the drawing board?
Notes
I forgot to mention that one of my concerns is that the ShowCullingBird
type properties aren't able to be accessed from that level; in that case I would need to create an Enabled
or Visible
property on the RenderObject
class.
Also, if you can think of a better title, please feel free to rename this post.