Функции структуры не будут работать должным образом, если имеется более 2 элементов

#c

#c

Вопрос:

У меня есть структура с именем ImAnimstate, которая содержит 3 значения с плавающей запятой. И у меня есть карта, которая содержит идентификатор виджета и ImAnimstate

 std::map <int, ImAnimstate> menuAnimations;
 

Он отлично работает, если есть только 1 виджет, но если я создаю более одного startAnim , startAnimDown функции and не работают должным образом. Функция вызывается, но значение enable просто сбрасывается до 1, например.

Вот как я вызываю функцию в коде виджета:

 auto animHandle = menuAnimations.at(id);
if (enabled)
    animHandle.startAnim(ANIM_ENABLE);
else
    animHandle.startAnimDown(ANIM_ENABLE);
 
 void Checkbox(std::string name, bool* v) {
        static ImAnimstate state;

        menuAnimations.emplace(ImGui::GetID(name.c_str()), state);
        ImGui::Checkbox(name.c_str(), v);
    }
 
 struct ImAnimstate
{
    float enable, hover, extra;

    ImAnimstate(float m_enable = 0.f, float m_hover = 0.f, float m_extra = 0.f) {
        enable = m_enable;
        hover = m_hover;
        extra = m_extra;
    }

    float menuAnimFrequency = 0.8f / 1.f;

    void startAnim(int type) {
        switch (type) {
        case ANIM_ENABLE:
            enable  = menuAnimFrequency * g_Frametime;
            enable = std::clamp(enable, 0.f, 1.f);
            break;
        case ANIM_HOVER:
            hover  = menuAnimFrequency * g_Frametime;
            hover = std::clamp(hover, 0.f, 1.f);
            break;
        case ANIM_EXTRA:
            extra  = menuAnimFrequency * g_Frametime;
            extra = std::clamp(extra, 0.f, 1.f);
            break;
        }
    }

    void startAnimDown(int type) {
        switch (type) {
        case ANIM_ENABLE:
            enable -= menuAnimFrequency * g_Frametime;
            enable = std::clamp(enable, 0.f, 1.f);
            break;
        case ANIM_HOVER:
            hover -= menuAnimFrequency * g_Frametime;
            hover = std::clamp(hover, 0.f, 1.f);
            break;
        case ANIM_EXTRA:

            extra -= menuAnimFrequency * g_Frametime;
            extra = std::clamp(extra, 0.f, 1.f);
            break;
        }
    }
};
 

Комментарии:

1. OT: static ImAnimstate state; не требуется. Вы можете просто сделать menuAnimations.emplace(ImGui::GetID(name.c_str()), {});

2. О, да, моя ошибка. Спасибо

3. Я понял, что enable переменная в обоих флажках сбрасывается на 0 после этой строки enable = std::clamp(enable, 0.f, 1.f); , все еще не знаю, что вызывает это.

4. g_Frametime никогда не бывает 0 или ниже. Я на 100% уверен в этом

5. Я отредактировал функцию Checkbox так, чтобы сначала получить идентификатор auto id = ImGui::GetID(name.c_str()); , затем поместить, затем получить ImAnimstate auto entry = menuAnimations.at(id); , а затем вызвать функцию визуализации с в entry качестве одного из аргументов. Но это все то же самое.

Ответ №1:

Проблема здесь:

 auto animHandle = menuAnimations.at(id);
 

Это создаст копию ImAnimstate объекта. По сути, это равно:

 ImAnimstate animHandle = menuAnimations.at(id);
 

Вы можете изменять копию столько, сколько захотите, но оригинал внутри карты никогда не будет изменен.

Чтобы решить проблему, вы должны получить ссылку на объект на карте:

 autoamp; animHandle = menuAnimations.at(id);
//  ^
// Notice ampersand here