pekfos |
» 2025-10-28 16:00:49 Wszystko co przekazujesz do draw możesz domyślnie tworzyć tylko na potrzeby przekazania do tej operacji i potem usunąć. Rób inaczej kiedy masz powód. Tak jest dobrze? Brakuje break. O to chodzi?
sf::RectangleShape Size: 352 bytes Alignmanet: 8 bytes
sf::Sprite Size: 280 bytes Alignmanet: 8 bytes Nie. To tylko bezpośrednia oszczędność pamięci z nietrzymania tych obiektów. Bezpośrednia, bo nie obejmuje dynamicznej alokacji pamięci. Ciężkie pamięciowo nie znaczy że tworzenie obiektów jest ciężkie obliczeniowo. A jak za dużo pokombinujesz to przy odrobinie niefarta jeszcze coś popsujesz Dokładnie dlatego należy robić prosto by działało i optymalizować potem. Jeśli nie mierzysz, to nie optymalizujesz. A musisz mieć co mierzyć. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-28 16:02:18 class ColoredButtonWithText { public: sf::Text * _text; sf::Color _selectColor; sf::Color _idleColor; sf::Color _hoverColor; sf::Color _pressColor; sf::Vector2f _position; ButtonState _state; std::function < void() > _hover_func; std::function < void() > _onclick_func; sf::Time _clickTime; ColoredButtonWithText( std::wstring text, sf::Vector2f size, sf::Vector2f position = sf::Vector2f( 0, 0 ) ); ~ColoredButtonWithText(); };
void ColoredButtonWithText::draw() { sf::RectangleShape rect( sf::Vector2f( _rect.size ) ); switch( _state ) { case ButtonState::Pressed: rect.setFillColor( _pressColor ); rect.setOutlineThickness( dialog_border_width ); rect.setOutlineColor( dialog_border_color ); break; case ButtonState::Hover: rect.setFillColor( _hoverColor ); rect.setOutlineThickness( dialog_border_width ); rect.setOutlineColor( dialog_border_color ); break; case ButtonState::Idle: if( _isSelected ) { rect.setFillColor( _selectColor ); rect.setOutlineThickness( dialog_border_width ); rect.setOutlineColor( dialog_border_color ); } else { rect.setFillColor( _idleColor ); rect.setOutlineThickness( dialog_border_width ); rect.setOutlineColor( dialog_border_color ); }; break; }; rect.setPosition( sf::Vector2f( _rect.position ) ); window->draw( rect ); window->draw( * _text ); }
|
|
pekfos |
» 2025-10-28 16:12:42 Nawiasem mówiąc gdy masz już kod który używa obiektów lokalnych do rysowania, optymalizacja jest trywialną zmianą sf::Text text( font ); target.draw( text ); zmieniasz w if( !m_text ) m_text = new sf::Text( font );
auto & text = * m_text; target.draw( text ); class ColoredButtonWithText { public: sf::Text * _text; Rób std::unique_ptr<sf::Text> zamiast gołego sf::Text*. Pamięć zostanie zwolniona automatycznie i poprawnie. Założę się że nie robisz tego poprawnie gdy masz więcej niż jeden taki alokowany obiekt w jednej klasie. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-28 16:20:54 Coś takiego? Ponoć surowe wskaźniki są szybsze, a ja zawsze usuwam dynamicznie przydzielaną pamięć. ColoredButtonWithText::~ColoredButtonWithText() { if( _text ) delete _text; }
void ColoredButtonWithText::draw() { sf::RectangleShape rect( sf::Vector2f( _rect.size ) ); switch( _state ) { case ButtonState::Pressed: rect.setFillColor( _pressColor ); rect.setOutlineThickness( dialog_border_width ); rect.setOutlineColor( dialog_border_color ); break; case ButtonState::Hover: rect.setFillColor( _hoverColor ); rect.setOutlineThickness( dialog_border_width ); rect.setOutlineColor( dialog_border_color ); break; case ButtonState::Idle: if( _isSelected ) { rect.setFillColor( _selectColor ); rect.setOutlineThickness( dialog_border_width ); rect.setOutlineColor( dialog_border_color ); } else { rect.setFillColor( _idleColor ); rect.setOutlineThickness( dialog_border_width ); rect.setOutlineColor( dialog_border_color ); }; break; }; rect.setPosition( sf::Vector2f( _rect.position ) ); window->draw( rect ); if( !_text ) { _text = new sf::Text( basicFont, _textStr, 13 ); _text->setFillColor( dark_and_red_button_text_color ); } auto & text = * _text; window->draw( text ); }
|
|
pekfos |
» 2025-10-28 16:29:55 Coś takiego? Z rzeczy których nie widać, to inicjalizacja wskaźnika na nullptr. Ponoć surowe wskaźniki są szybsze Bzdura a ja zawsze usuwam dynamicznie przydzielaną pamięć. To że zawsze piszesz delete nie znaczy że zawsze usuwasz pamięć. Musisz ją usuwać w każdej ścieżce wykonania by faktycznie usuwać ją "zawsze". Ten kod zawsze usuwa zaalokowaną pamięć: struct A { std::unique_ptr < int > a, b; A() : a( new int ) , b( new int ) { } }; Ten kod nie: struct A { int * a, * b; A() : a( new int ) , b( new int ) { } ~A() { delete a; delete b; } }; Czy widzisz ścieżkę wykonania w której pamięć wycieka? |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-28 16:32:33 Dobra. Wróćmy narazie do tego, bo poprawiłem kod; Za chwilę zajmiemy się wskaźnikami - wszystkiego na raz nie poprawię :P To jest dobre renderowanie tekstu? if( !_text ) { _text = new sf::Text( basicFont, textString, 13 ); _text->setFillColor( dark_and_red_button_text_color ); }
auto & text = * _text; window->draw( text );
przypisanie nullptr do _text jest w konstruktorze ColoredButtonWithText::ColoredButtonWithText( std::wstring text, sf::Vector2f size, sf::Vector2f position ) : Button() { _idleColor = dark_and_red_button_normal_color; _hoverColor = dark_and_red_button_hover_color; _pressColor = dark_and_red_button_press_color; _selectColor = dark_and_red_button_select_color; _rect = sf::IntRect( sf::Vector2i( 0, 0 ), sf::Vector2i( size ) ); _text = nullptr; setPosition( position ); _state = ButtonState::Idle; _hover_func = { }; _onclick_func = { }; _clickTime = currentTime; }
|
|
pekfos |
» 2025-10-28 16:37:07 No tak. Możesz pominąć tworzenie tej referencji jeśli nie zamierzasz ją użyć tylko raz. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-28 16:39:30 Dodałem funkcje do pozycjonowania tekstu. W następnym poście spróbuję przypisać dynamiczne wskaźniki do zmiennych buttona. void ColoredButtonWithText::draw() { sf::RectangleShape rect( sf::Vector2f( _rect.size ) ); switch( _state ) { case ButtonState::Pressed: rect.setFillColor( _pressColor ); rect.setOutlineThickness( dialog_border_width ); rect.setOutlineColor( dialog_border_color ); break; case ButtonState::Hover: rect.setFillColor( _hoverColor ); rect.setOutlineThickness( dialog_border_width ); rect.setOutlineColor( dialog_border_color ); break; case ButtonState::Idle: if( _isSelected ) { rect.setFillColor( _selectColor ); rect.setOutlineThickness( dialog_border_width ); rect.setOutlineColor( dialog_border_color ); } else { rect.setFillColor( _idleColor ); rect.setOutlineThickness( dialog_border_width ); rect.setOutlineColor( dialog_border_color ); }; break; }; rect.setPosition( sf::Vector2f( _rect.position ) ); window->draw( rect ); if( !_text ) { _text = new sf::Text( basicFont, _text_str, 13 ); _text->setFillColor( dark_and_red_button_text_color ); } sf::Vector2f text_pos; text_pos.x = _rect.position.x + _rect.size.x / 2 - _text->getGlobalBounds().size.x / 2; text_pos.y = _rect.position.y + _rect.size.y / 2 - basicFont.getLineSpacing( 13 ) / 2; _text->setPosition( text_pos ); window->draw( * _text ); }
|
|
| 1 « 2 » 3 4 5 |