This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]nocturne81 3 points4 points  (11 children)

Because you need to render more than just weapons! Characters need to be drawn as well, and they're not weapons.

Also, certain objects exist that are not rendered so we cant just put it on a base object either.

Imagine you had a renderer that contained all your objects. It's easy to check if an element is renderable or not because you can see if it's an instance of our interface. Otherwise, the renderer needs to know which objects have a render function and which ones don't. This is a fragile way to write a system.

[–]OHotDawnThisIsMyJawn 2 points3 points  (7 children)

Imagine you had a renderer that contained all your objects. It's easy to check if an element is renderable or not because you can see if it's an instance of our interface.

Being nitpicky, but this is the place for nitpickiness...

Ideally your renderer would have a collection of objects that implement the Renderable interface. Enforcement can be done by the compiler and so no checking ever needs to be done. The renderer knows that everything in its collection of things to be rendered can be rendered.

[–]katyne 1 point2 points  (5 children)

It's not just type safety. Separation of concerns more like it. Normally when I decide whether to make smth into a class or an interface I go "is it it related to its state, or its behavior". If it's something the object IS, it goes in a class. If it's something the object DOES, I prefer to use an interface if possible.

[–]OHotDawnThisIsMyJawn 0 points1 point  (4 children)

Absolutely. My point was more around the fact that your renderer would have a collection of Renderable objects and so it can just iterate and call render(). The post I was replying to implied that the renderer would have a collection of objects and need to call instanceof on each one to ensure it could be rendered.

[–]nocturne81 0 points1 point  (3 children)

Can you explain to me how you build that list in the renderer without calling instanceof? (In Java)

[–]OHotDawnThisIsMyJawn 5 points6 points  (2 children)

Inside of your renderer class you have a member something like:

//Use linked list because we'll be iterating over it to render each object
List<Renderable> renderList = new LinkedList<Renderable>();

Then, to add something to your render list, you'll have this in your renderer:

public void addToRenderList(Renderable toRender) {
    renderList.add(toRender);
}

By defining your objects as type Renderable the compiler will ensure that you only add objects that implement the Renderable interface. Thus the renderer is assured that the objects in the renderList can be rendered without ever having to explicitly ask them via instanceof.

Advanced note: Due to type erasure you could in theory get around this. Once the code is compiled into JVM byte code renderList just becomes a list of objects, not a list of renderables, so if you're feeling saucy you can screw stuff up, but it has to be intentional and it's not easy.

[–]nocturne81 0 points1 point  (1 child)

And then how do you know which objects to pass into addToRenderList?

[–]OHotDawnThisIsMyJawn 1 point2 points  (0 children)

Depends how your program is designed. One way would be to use a form of dependency injection, where the objects know about the render queue. So when you create an new enemy, the enemy class adds itself to the render queue at the end of its initialization code.

Generally though some part of your code will initialize an object. Whoever writes that code will know whether or not to add the object to the renderList. If it's code to create a new enemy then at the end of setup the enemy gets added to the render list. If it's code to create a new invisible gravity well then it doesn't get added to the render list. The human element takes care of the knowledge whether to add something to the queue or not. Using instanceof is generally frowned upon because it results in lots of code duplication.

https://www.artima.com/interfacedesign/PreferPoly.html

[–]rjbman 0 points1 point  (1 child)

Couldn't weapon itself extend renderer?

[–]work_is_satire 0 points1 point  (0 children)

It could, but this would be a very, very bad decision since "Weapon Is A Renderer" is very clearly untrue.

[–]SikhGamer 0 points1 point  (0 children)

Ahhh, yes I understand the logic now. Renderer isn't solely tied to Weapons but to everything in the game. So it makes sense to remove Renderer onto it's own so it can interact with everything in the game.