kipar писал(а):Мышью, за исключением кликов (ну и двойных кликов, ты правильно подметил) так не делают
Очень даже делают. Всегда, что по личному опыту, что по чужому (в свое время был сисадмином, у меня эти пользовательские привычки поперек горла стояли), если быстро и щелкают, то "по памяти". Окно еще не открылось, а мышь уже в угол ползет. Особо упоротые даже второй клик успевали, прежде чем эта чертова 1С таки откроет свою несчастную проводку. И наоборот, если пользователь таки сначала думает, а потом кликает, он всегда дожидается реакции программы и потом продолжает. Посередине этих двух крайностей почему-то никого нет. Поэтому если
kipar писал(а):Программа запоминает все клики и они складываются, например, в последовательность уничтожения предмета
то скорее всего именно это пользователь и хотел; вплоть до обратной ситуации -- то, что вместо окна я вторым кликом попаду по монстру на карте, вообще выбесить может, я черт побери не по карте щелкал.
kipar писал(а):Поэтому я за считывание статуса, возможно даже двойных кликов или скажем нажатых в момент клика модификаторов кнопок (хотя это излишнее усложнение, по-моему), но против очереди из более чем одного события.
Считывание координат, одинарных, двойных кликов, левой, правой, средней кнопок, состояния модификаторов левых, правых -- и вот она, структура на все случаи жизни. Осталось добить ее кодом обычной клавиши, флагами и количеством повторений и получить химеру из SDL_чтототам и lParam/wParam. Нет, к черту.
Ну а теперь вишенка. Вся дискуссия не имеет большого смысла:
* Если тебе нужна очередь, берешь input_t key = terminal_get(); и обрабатываешь каждое событие.
* Если тебе очередь не нужна -- делаешь input_t key; while ( terminal_kbhit() ) key = terminal_get(); и получаешь просто последнее случившееся событие.
В обратную сторону так нельзя, ибо взятие статуса устройства ввода теряет данные. Я не горю желанием требовать всех в обязательном порядке использовать все данные (очередь), но терять их тоже не намерен.
Apromix писал(а):Рассмотри вариант использования для либы движка HGE или SDL )) В движок там много чего встроено и не нужно придумывать самому.
Не стоит. Во-первых, к данному моменту уже бессмысленно, ибо сделано по-своему. Во-вторых, лишние либы не нужны. Создание OpenGL-окна есть задача тривиальная. Ввод в этих либах выполнен ну тоже не то чтобы идеальным способом. А уж с текстом (самая, кстати, большая часть задумки) там полный срам. Ну и лишняя .dll тоже никому не нужна.
Uvadzucumi писал(а):по вводу, я бы делал в либе приблизительно так: возможность повесить каллбэк на функуии <...> и функции чтения возможность чтения состояний <...>
Не, коллбеки это совсем не то. Чуть выше уже ведется спор событийный vs потоковый ввод, сейчас ход
kipar =)
События с обратными вызовами хороши, когда у тебя соответствующая архитектура. Я же люто, бешено хочу, чтоб можно было написать просто
Код: Выделить всё
int main()
{
terminal_open("");
while ( true )
{
DrawLevel();
input_t key = terminal_get();
if ( key.code == VK_CLOSE ) break;
else if ( key.code == VK_LEFT ) { MoveLeft(); }
/* ... */
}
terminal_close();
}
И -- все. И можно не думать, что оно сожрет все ресурсы безрассудно опрашивая клавиатуру. Или начнет подлагивать из-за слишком большого sleep() в цикле и, соответственно, несколько заторможенной реакции. Или вообще пропустит нажатие или два.
При пустой очереди terminal_get вернет нажатие в тот же момент, когда произойдет нажатие. Не в конце какого-то на шару подобранного интервала проверки, а в сие мгновение. А до того мгновения программа будет мирно спать не тратя CPU. Ну а обновление картинки вообще само по себе и выполняется когда нужно и сколько нужно.
Проникнитесь насколько это упрощает логику. Не надо думать когда там обновить экран. Не надо думать как часто надо опросить ввод. Девяти десятым простых набросков для проверки того или сего (для чего, не в последнюю очередь, либа и пилится) за глаза хватит такого простого, как полено, алгоритма.
Для тех же, кому аж не спится без реалтайма и обязательной проверки ввода здесь и сейчас, поясняю темную сторону обработки ввода в BearLibTerminal (которую я самодержавно придумал к текущему моменту):
Увы-увы-увы, я вынужден пойти на ввод структуры "событие ввода" следующего вида:
Код: Выделить всё
struct input_t
{
unsigned char code, flags, x, y;
};
И функции:
Код: Выделить всё
int terminal_kbhit();
input_t terminal_get();
input_t terminal_get_nonblocked(int timeout);
Ну и, наконец, пояснения:
Поле
code в структуре
input_t -- это код, кхм, события. VK_LEFT, VK_LBUTTON, VK_WHEELUP, и т. д.
Поля
x и
y там же -- координаты мыши в соответствующий момент.
terminal_get_nonblocked -- это как terminal_get, но с таймаутом. Фактически, как раз наоборот, terminal_get -- это terminal_get_nonblocked(очень-большое-число). К слову, необязательно блокирующий вызов get был в интерфейсе с самого начала, но до сего момента не афишировался.
* Получили
code == F1? Великолепно, в этой же структуре уже есть
x и
y. F1 просто справка приложения? Ну так никто и не заставляет.
* Получили VK_LBUTTON? Ну так вы уже знаете где искать координаты.
* Нет события, но координаты мыши ну позарез как нужны здесь и сейчас? terminal_get_nonblocked(0) к вашим услугам. Поля
x и
y заполнены всегда, что бы там не произошло с клавиатурой, мышью или мировой политической ареной.
* Куча событий, но хочется только последнее -- ну так, как уже было показано, возьми самое последнее, кто ж мешает?
Вы лучше скажите, какой шрифт взять в качестве дефолтного (который используется если terminal_font не вызывалось или сфейлилось) -- старый добрый Fixedsys или что-нибудь более в ногу со временем типа Ubuntu Mono? Дефолтный шрифт будет в наличии всегда (вложен в .dll), растеризован и иметь неполный относительно юникода, но и не маленький набор глифов. По меньшей мере расширенную латиницу, греческий (ну прикольные у них буквы) и кириллицу.