2013-05-26 2 views
1

Я пытаюсь создать класс для обработки ключевых обратных вызовов.unordered_map векторов сброса векторов

Для этого я карта определяется как так:

class Keyboard { 
public: 
    void registerCallback(int key, callback_fn func, bool repeat = false); 
    void onKeyEvent(int key, int state); 

private: 
    typedef std::function<void (int)> callback_fn; 

    struct Callback { 
     Callback(callback_fn f, bool r) 
      : func(f), repeat(r), last_state(-1) {} 

     callback_fn func; 
     bool repeat; 
     int last_state; 
    }; 

    std::unordered_map<int, std::vector<Callback>> callbacks; 
}; 

Я тогда зарегистрировать обратные вызовы, как так:

void Keyboard::registerCallback(int key, callback_fn func, bool repeat) { 
    // My understanding is that if there is nothing mapped to the key 
    // it will create a new vector. Otherwise it will return the mapped 
    // object. I did try checking if anything already exists at the key 
    // and if not creating a new vector but it yielded the same results. 
    callbacks[key].push_back({ func, repeat }); 
} 

Однако я имею вопрос, где отображается вектор появляется потерять все его элементов.

Когда я регистрирую обратный вызов, вектор с заданным ключом увеличивается в размере, но когда я пытаюсь перебрать вектор по другому методу, он не имеет элементов.

Ниже приведено как мой метод для итерации по вектору.

void Keyboard::onKeyEvent(int key, int state) { 
    for(auto& callback : callbacks[key]) { 
     if(callback.repeat || callback.last_state != state) { 
      callback.func(state); 
     } 
    } 
} 

Примечание Если добавить std::cout << callbacks[key].size() << std::endl; к верхней части функции она печатает 0.

Если это имеет значение, это пример того, как я регистрирую обратный вызов.

keyboard.registerCallback('w', [](int state) { 
    std::cout << "w " << (state == GLFW_PRESS ? "pressed" : "released") << std::endl; 
}, true); 

Я подозреваю, что моя проблема связана с различиями между картами Явы, которые, я больше привык, и карты C++ 's

+0

Что делает следующая печать сразу после вызова registerCallback: 'std :: cout << keyboard.callbacks ['w']. Size();'? – Inspired

+0

Когда вы возвращаете вектор обратных вызовов, вы уверены, что используете один и тот же экземпляр 'callbacks', как при добавлении их? –

+0

Являются ли эти единственные функции, которые изменяют «обратные вызовы»? И вы уверены, что вы не создаете и не работаете с копией «обратных вызовов» где-то? – jamesdlin

ответ

3

Позвольте мне угадать: проблема в том, что вы получите код ключа в виде буквы ('W' , алфавитные коды клавиш чаще всего имеют верхний регистр), но регистрируют обратный вызов для маленькой буквы ('w').

0

Проблема, скорее всего, зависит от чувствительности к регистру, так как нет ничего особенного в вашем коде и 10 секунд в отладчике подтверждает, что ничего магического не происходит. Пока вы используете один и тот же экземпляр «Keyboard», но единственная причина, по которой он не найдет «ключ», который вы ищете, - это потому, что он отличается от того, что вы зарегистрировали.

Прошли ли вы в отладчике и определили, какой ключ вы искали? Вы пытались его вывести?

Если вам нужно иметь дело с переменным футляром, вы всегда можете перегрузить 'unordered_map', чтобы использовать пользовательскую хеширующую функцию, которая может сделать бесполезное сравнение для вас.