Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Punching holes in const corectness (of sf::Drawable)  (Read 3751 times)

0 Members and 1 Guest are viewing this topic.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Punching holes in const corectness (of sf::Drawable)
« on: September 19, 2012, 01:19:08 am »
Do you ever do that? It at times does get annoying how draw is const method.
Things like updating position of a sprite, updating animation count, updating frame count, ect. become a bit problematic, especially if the reason for derieving from drawable in the first place was for polymorphism.
It seems the only other way around that would be to create own drawable abc and then derieve all the sfml drawables from it.
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Punching holes in const corectness (of sf::Drawable)
« Reply #1 on: September 19, 2012, 07:47:07 am »
This is exactly why draw is const -- to force people to do things right, even if it pisses them off ;D

Although mixing update and draw is sometimes convenient, a good practice is to always separate logic and drawing.

And, most important, if draw was non-const it would break a lot of users code in which the whole drawing process is const.
Laurent Gomila - SFML developer

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Punching holes in const corectness (of sf::Drawable)
« Reply #2 on: September 19, 2012, 01:55:00 pm »
I don't say it's bad or I want it to change, I say it might be annoying at times. I don't think that fetching positions from box2d and setting them to sprite is 'logic'. Especially if the object has no logic part in it and just displays a sprite at box2d coords. I would have to inherit it from my runable abc and then 'run' it(even though it does nothing except update sprite pos - which doesn't affect the game). And also my fps(whatever/second) and update cycles(60/second) are untied so I'd update sprites too often or too rarely.
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Punching holes in const corectness (of sf::Drawable)
« Reply #3 on: September 19, 2012, 02:17:09 pm »
Quote
I don't think that fetching positions from box2d and setting them to sprite is 'logic'
It's 'update', so it's definitely not 'drawing' ;)

But ok, I understand your concern. But it would certainly be worst to make it non-const; and I think you agree with that when you say:
Quote
I don't say it's bad or I want it to change

So what do you expect from this discussion?
Laurent Gomila - SFML developer

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Punching holes in const corectness (of sf::Drawable)
« Reply #4 on: September 19, 2012, 05:12:32 pm »
Quote
It's 'update', so it's definitely not 'drawing'  ;)
It is update but not logic update. That's the point : anything related to visuals (except debug drawing, which is for debug so it can be crapped up) happens in draw() and anything related to game logic happens in Run() or in collision callbacks from box2d. Moving pre-draw update into run can't happen because it'd mix these two unrelated things(now any mistakes can be traced like: -> turn debug drawings on, is sprite at same position as body ->yes = Run(logic) is messed and bodies are at wrong positions, no-> draw(displaying) is messed and graphical representations are at wrong positions),not everything that can be drawn can be Ran and Run() and draw() cycles are not synchronized(they are on 60 fps but it's not requirement and framerate doesn't affect speed of game simulation).

Quote
So what do you expect from this discussion?
I'm wondering what is most 'clean' and reasonable way to handle that besides breaking const that people use.
Update proc dedicated to pre-drawing updates beats the point of inheriting from drawable instead of making own public Draw(sf::RenderTarget& target,sf::RenderStates states) without const and putting draw and update there since at some point we would need to know the real type to call our pre-drawing anyway.

Quote
and I think you agree with that when you say
Part of the problem(which makes it a rare problem most people might not face?) is I don't iterate through entities to update their positions and don't have chance to update their sprites then.
« Last Edit: September 19, 2012, 05:16:05 pm by FRex »
Back to C++ gamedev with SFML in May 2023

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Punching holes in const corectness (of sf::Drawable)
« Reply #5 on: September 19, 2012, 05:37:43 pm »
It is update but not logic update. That's the point : anything related to visuals (except debug drawing, which is for debug so it can be crapped up) happens in draw()
Do you just want to update the graphics according to the logics, or do draw() calls advance the animation state each time?

Does it make a difference for the object if draw() is called once or twice?
« Last Edit: September 19, 2012, 05:46:31 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Punching holes in const corectness (of sf::Drawable)
« Reply #6 on: September 19, 2012, 05:58:00 pm »
Quote
For example, calling draw() twice instead of once should not make a difference with respect to the object state.
It doesn't 'change' the object after the first call that happens after world step.
while(App.isOpen())
{
/*world step*/
App.draw(something);
}
Would look exactly same as
while(App.isOpen())
{
/*world step*/
int a=5;
while(--a)
App.draw(something);
}

Quote
Why can't you write a method updateGraphics() or alike that is not const?
Because then I could give up the inheritance from drawable and just roll own abc that does both in one call( or even two calls) since App.draw(**it); (with it being iterator of container of drawable pointers) is no longer safe.
Back to C++ gamedev with SFML in May 2023

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10800
    • View Profile
    • development blog
    • Email
Re: Punching holes in const corectness (of sf::Drawable)
« Reply #7 on: September 19, 2012, 06:14:33 pm »
I still don't get why it shouldn't be a logic update...

You don't update the logic position yourself, but Box2D does and thus after letting Box2D update the (logic) positions you copy them onto your sprites. It then doesn't matter which 'loop' runs at which FPS, because the sprites position get updated as soon as their logic parts could've changed.

Maybe I got you all wrong, but I don't see the need for having updates in the draw call. ;)
If you don't feel comfortable with the update/draw or update/updateGraphics/draw solutions then you're maybe better of with your own draw function...
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Punching holes in const corectness (of sf::Drawable)
« Reply #8 on: September 19, 2012, 06:36:00 pm »
It doesn't 'change' the object after the first call that happens after world step.
Okay, so the graphical properties needn't necessarily be members, right? You could create new sprites everytime, but don't do it for performance reasons?

In this case, there is indeed a better approach: Member variables that are not part of the object's logical state can be attributed with mutable to allow cache semantics. If you use this keyword, make sure none of those variables appear in the class's interface.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Punching holes in const corectness (of sf::Drawable)
« Reply #9 on: September 19, 2012, 06:52:07 pm »
Quote
Okay, so the graphical properties needn't necessarily be members, right? You could create new sprites everytime, but don't do it for performance reasons?
Well YEAH.. ??? , but that idea is so performance killing I never considered it outside of debug draw class.

Quote
I still don't get why it shouldn't be a logic update...
Logic updates are things that change the entity and b2world like key pressed, late responses to collision callbacks, setting velocities and applying forces to bodies ect.
Back to C++ gamedev with SFML in May 2023

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Punching holes in const corectness (of sf::Drawable)
« Reply #10 on: September 19, 2012, 07:39:14 pm »
It then doesn't matter which 'loop' runs at which FPS, because the sprites position get updated as soon as their logic parts could've changed.
When there are more iterations of game logics than graphics, this approach updates the graphics unnecessarily often.

Well YEAH.. ??? , but that idea is so performance killing I never considered it outside of debug draw class.
It depends on the amount of work, I have already done that without performance issues. If you reset most sf::Sprite attributes, you are not much faster than the constructor.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10800
    • View Profile
    • development blog
    • Email
Re: Punching holes in const corectness (of sf::Drawable)
« Reply #11 on: September 19, 2012, 08:44:56 pm »
When there are more iterations of game logics than graphics, this approach updates the graphics unnecessarily often.
Hmm... I see. I didn't really think enough far. :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Punching holes in const corectness (of sf::Drawable)
« Reply #12 on: September 19, 2012, 08:53:46 pm »
Quote
Hmm... I see. I didn't really think enough far.
Swords' sprites are drawn very rarely so they don't need to be updated most of the time. They are attached to player as sensors and zero out their collision filters and quit their draw after one bool check unless the sword is in use.
Quote
It depends on the amount of work, I have already done that without performance issues. If you reset most sf::Sprite attributes, you are not much faster than the constructor.
Even if speed was same I'd stay with mutable as is, that way my entity c-tor(which knows the size of physic body but doesn't keep it) can rescale sprite and set origin and texture as needed instead of me doing it every frame in addition to setting position.
« Last Edit: September 19, 2012, 10:34:19 pm by FRex »
Back to C++ gamedev with SFML in May 2023