5

I have a structure like that

  abstract Class Entity {
    //some variables... 
    //some methods ...
    public abstract void render(Graphics g);
    }

Thats the parent ..Now I have 3 children..

Class A extends Entity{}
Class B extends Entity{}
Class C extends Entity{} 

Every class has some different stuff do render .One is for example drawing yellow circle , second green text and the third is displaying image.

But ... there is a thing.

Class A have List<B>... 
Class B have List<C>... 

One Entity has for example 10 Bs ... and each B has 20 Cs ... So now .. I have a render method that renders 60x per second.. And I have to call every render method from every object.

So I have something like this

for(A a : listOfAs){
   for(B b : listOfBs){
      for(C c : listOfCs){
         c.render(g);
      }b.render(g);
   }a.render(g);
}

Now if you imagine I have much more objects like that and I call this method 60x per second ... I find this really ...really bad practice.. I don't know how to solve this better or so... I don't think that this for each loop is actually the best solution or not. Anyone any ideas ?

I was thinking about implementing the child like that :

Entity x = new A(); ... 
Entity y = new B(); ... 

and so but some of the classes have other methods that have to be looped like that and I cannot call them from parent.

For the render method ... Just stick to the fact that you have to loop something many times in a short period of time for a long time.

I cannot progress through this ... I got stuck here for a long time and I am not sure how to solve this.

  • 1
    I feel like Lambdas would be faster here for looping through since the nested foreach loops will occur `listOfAs.count` * `listOfBs.count` * `listOfCs.count` times whereas a lambda done properly with some form of hashjoin or inner join can do it in `listOfAs.count` + `listOfBs.count` + `listOfCs.count` times. I'd write the proof of it but that won't answer your question. – Adam Aug 03 '15 at 19:45
  • 2
    This sounds like a case for first rendering your Entities to a temporary Image, then painting that in paint/paintComponent... Also, you really don't need to render 60x a second; the eye's only good for about 24x – ControlAltDel Aug 03 '15 at 19:48
  • @Adam I'm not sure what you're referring to, but I'm not convinced without a good explanation I'm afraid! There are a number of objects to iterate through; no amount of joining can reduce that number, surely? My instinct would be instead to think about utilising concurrency. Another optimisation might be to figure out which pixels are going to be redrawn and just draw the last value, though the cost of that might end up outweighing the benefit. – Oly Aug 03 '15 at 19:55
  • 1
    Do you need to re-render all of them all the time? A classic solution is to track what has really changed and re-render only that. – GeertPt Aug 03 '15 at 20:55
  • Are you sure A, B, and C relate? OR they are dependent? – LHA Aug 04 '15 at 13:58
  • You should use encapsulation in `render()` method. If object of class **A** has / encapsulates many objects of class **B**, then `A.render()` should be invoking `B.render()` for each object it encloses. If you are rendering too many objects, you have to establish visibility somehow for each object (e.g. you render only limited window in 2D or in 3D you will only render what camera sees, which usually is not 360') and quickly return from `Entity.render()` of entity which is not visible. You still have to traverse the whole tree of objects, but perhaps you can cull a lot of them. – diginoise Aug 04 '15 at 15:35

3 Answers3

1

Since your primary concern seems to be rendering or not rendering certain entities, regardless of whether they are child entities, you should do some research into general graphics programming optimizations and tricks and what rendering engines do to improve performance. A big gain in performance in rendering engines is not doing work that is not necessary.

One was already mentioned, which is to determine which actually changed state and only render them. Another is to check the bounds of your view against the bounds of each entity on the graphics canvas and only render things that are within the bounds. Whether you have 2D or 3D, you might have things overlapping, so you could determine what entities are occluded and avoid rendering them. If your child entities are within the bounds of the parent, then you can avoid rendering an entire tree of your object graph and avoid iteration of many elements.

Also, these things can be done in partials by checking for a part of an entity that must be re-rendered, a part that is not occluded, etc. This may require some changes to your API to pass in bounds where entities are expected to render instead of the entire graphics context to each item.

If you don't know anything else about any of your renderable entities such as dirty state or bounds, then you are stuck with iterating them all and invoking render one each of them.

Paul Bilnoski
  • 556
  • 4
  • 13
0

I'm not sure I quite follow... But Are you making an entity that consists of several other entities? No matter how much you think this through, you'll always have to visit each entity once. It doesn't really matter what kind of loop you choose.

However, if you have an Entity that consists of a bunch of sprites, I would recommend creating a new texture and render these sprites onto that texture once. Then you just need to render that texture each frame. Makes sense?

Jake
  • 843
  • 1
  • 7
  • 18
0

I located a friend at work who took a look at it and helped me stabilize it. Thank you all for your tips and help. I don't think that lambdas can help a lot here.

It's hard to explain what I am doing in this project . It's not a game at all .. It's something different. I got double rendering so it's really 2* 30 times per sec. I was just playing with the load of objects that I can actually later use in my engine . But this problem got me stuck for a pretty big while.

Again. Thank you all .