Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Czy trzymać sf::RectangleShape w pamięci oraz inteligentne wskaźniki

Ostatnio zmodyfikowano dzisiaj: 9h » 24 min
Autor Wiadomość
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ć.
P-183306
tBane
Temat założony przez niniejszego użytkownika
» 2025-10-28 16:02:18
C/C++
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();
   
// etc ...
};

C/C++
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 );
}
P-183307
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ą
C/C++
sf::Text text( font );
//...
target.draw( text );
zmieniasz w
C/C++
if( !m_text )
   
 m_text = new sf::Text( font );

auto & text = * m_text;
//... bez zmian
target.draw( text );

C/C++
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.
P-183308
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ęć.
C/C++
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 );
}
P-183309
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ęć:
C/C++
struct A
{
   
std::unique_ptr < int > a, b;
   
A()
        :
a( new int )
       
, b( new int )
   
{ }
}
;
Ten kod nie:
C/C++
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?
P-183310
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?
C/C++
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
C/C++
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;
   
}
P-183311
pekfos
» 2025-10-28 16:37:07
No tak. Możesz pominąć tworzenie tej referencji jeśli nie zamierzasz ją użyć tylko raz.
P-183312
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.

C/C++
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 );
}
P-183313
1 « 2 » 3 4 5
Poprzednia strona Strona 2 z 5 Następna strona