Page 1 of 2

mainloop - как использовать?

Posted: Mon Jun 08, 2009 12:38 pm
by Louigi Verona
Всем привет!

Написал приложение (клеточный автомат), которое использует таймер. Но таймер не так быстр и для значительного ускорения процессов уже не подходит. Мне посоветовали использовать mainloop, но как это сделать? Мне нужно взаимодействие с компонентами формы. Если вызывать что-то из OnInit или OnIdle, компоненты в тот момент ещё не созданы и компилятор ругается, что не знает их. А как тогда делать?

Posted: Tue Jun 09, 2009 11:08 am
by Nikolay
Если скорости таймера не хватает (?!?), то наверное стоит использовать OnIdle.
Взаимосвязи между тем что компоненты еще не созданы (runtime) и ругается компилятор (compile time) в упор не вижу:) Ошибка где-то в другом месте...

Posted: Tue Jun 09, 2009 12:26 pm
by Louigi Verona
Ну, может быть и в другом. А не можете вкратце рассказать, как этот mainloop вызывать? Вот я создал проект в wxDev-C++ и теперь хочу в mainloop или OnIdle запихнуть вызов какой-нить функции. Куда что писать? Я пробовал экспериментировать с OnRun или OnIdle, но ничего не получалось - или компилятор говорил что не знает мою форму, либо просто ничего не происходило.

Posted: Wed Jun 10, 2009 5:55 am
by Nikolay
Ну давай по шагам, ты можешь написать обработчик некоего события например wxIdleEvent или wxCloseEvent?
Поставить внутри брейк поинт или wxLogDebug(_T("something")) и убедится что туда заходит?
И не забудь про RequestMore для OnIdle.

И повторюсь, имхо тебе не надо не OnIdle не main loop. Расскажи чем тебя таймер не устраивает и что ты хочешь сделать?

Posted: Wed Jun 10, 2009 6:39 am
by Louigi Verona
Да, я написал обработчик OnIdle, но вызвать оттуда функцию не могу - даже просто обратиться к форме не могу, потому что компилятор говорит - а это не декларировано.

В англоязычном форуме я уже попросил помощи, уже несколько дней мне подсказывают то одно, то другое, но пока результата нет. Вот тема (чтобы не повторять одно и то же): http://forums.wxwidgets.org/viewtopic.php?t=24406

Программа, которую я делаю, лежит тут: http://www.cathyportal.ru/files/Cycles.zip

Попробуй там поставить несколько элементов рядом (кликая на таблицу) и посмотреть, что будет происходить. Надо подождать, там как бы "заряжается" вакуум.

Проблема в том, что я не могу ускорить процесс. Таймер быстрее просто не работает. У меня интервал стоит на 10 мс и быстрее он уже не может. Соответственно, ускорить программу не получается, а так ждать слишком долго пока всё происходит, иногда хочется ускорить.

Posted: Wed Jun 10, 2009 6:58 am
by Nikolay
Ну, я вижу что в англоязычном форуме тебе говорили, что вместо

Code: Select all

void OnIdle(wxIdleEvent& event){ 

    frame->GetNum(); 

} 
надо писать

Code: Select all

void  TablesFrmApp::OnIdle(wxIdleEvent& event){ 

    frame->GetNum(); 

} 
А после этого ты приводишь свой код в котором TablesFrmApp:: отсутствует, а ошибка то тут..

И еще по поводу таймера что там такое делается что 100 раз в секунду сильно редко?
Может тогда стоит вместо

Code: Select all

... OnTimer(wxTimerEvent & event)
{
  SomeWork();
}
Писать

Code: Select all

... OnTimer(wxTimerEvent & event)
{
  for(int t = 0; t < 100; ++t)
      SomeWork();
}
??

Posted: Wed Jun 10, 2009 8:07 am
by Louigi Verona
Ыыыы... а этого я и не заметил. Просматривал код, а этой детали не заметил. Попробую с ней.

Ну а насчёт таймера - по таймеру создаётся случайная координата x и y и затем вызывается wxGrid1->SelectCell(y,x). Функция события OnCellSelect содержит основные вычисления.

Вот мне бы хотелось чтобы это быстрее было - чтобы чаще вызывалось wxGrid1->SelectCell(y,x).

Posted: Wed Jun 10, 2009 8:56 am
by borr_1
Louigi Verona wrote: Вот мне бы хотелось чтобы это быстрее было - чтобы чаще вызывалось wxGrid1->SelectCell(y,x).
Чаще чем таймер это как это? 1 миллисекунда не устраивает :shock:

Posted: Wed Jun 10, 2009 11:49 am
by Louigi Verona
Ребят, я не знаю. Я не очень сильный программист. Конечно, я с радостью учусь новому и разбираться с wxWidgets мне нравится, но пока я многого не понимаю. Но я точно знаю, что ускорить мою программу можно - там очень простые вычисления и компьютер способен во много раз ускорить процесс.
В таймере я выставил очень маленький интервал, но процесс не ускоряется достаточно.

Posted: Wed Jun 10, 2009 12:02 pm
by Nikolay
Значит надо искать где грабли...

wxLogDebug(..) в таймере до и после вызова твоей функции, и выводи время, а потом уже смотри где все тормозится.

Posted: Wed Jun 10, 2009 12:04 pm
by borr_1
И чё? Я вообще не программист.

Просто ребята подозревают, что собака порылась не в таймере. Видимо у тебя где то в обработке узкое место. Показывай код, если можешь. И откуда у тебя пускается таймер со стартом приложения?

Posted: Wed Jun 10, 2009 12:25 pm
by Louigi Verona
Да конечно, код могу показать. могу файл куда-нить закачать.

Таймер запускается, когда в меню пользователь нажимает Start. Тогда случается WxTimer1->Start(1,false);

В функции OnTimer производится вызов WxGrid1->SelectCell(y,x);

А далее в функции OnSelectCell производятся "вычисления" - то есть, в зависимости от значения окружающих ячеек в данную ячейку ставится то или иное значение.

Я вижу что бегунок бегает по таблице очень шустро - за секунду думаю раз десять пробегает. Я читал, что компонент Таймер не может иметь интервал меньше 10мс и что для увеличения скорости выполнения нужно отходить от таймера и вместо этого использовать mainloop, благодаря чему можно в секунду тысячи раз пробегать по таблице.

То есть у меня нет ощущения что что-то тормозится - таймер просто не настолько быстр.

Posted: Wed Jun 10, 2009 12:35 pm
by Nikolay
А я уже предлагал в таймере больше чем 1 раз пробегать по таблице?:)

Posted: Wed Jun 10, 2009 12:49 pm
by Louigi Verona
Да, Николай, спасибо за совет, я прочитал и обязательно (буквально прямо сейчас) попробую это!

Но хочется тогда понять - действительно - лучше использовать таймер или mainloop? Или всё-таки mainloop лучше не трогать?

Posted: Wed Jun 10, 2009 12:49 pm
by borr_1
Я читал, что компонент Таймер не может иметь интервал меньше 10мс и что для увеличения скорости выполнения нужно отходить от таймера и вместо этого использовать mainloop
Вот что мне говорит справка
wxTimer

The wxTimer class allows you to execute code at specified intervals. Its precision is platform-dependent, but in general will not be better than 1ms nor worse than 1s.
Разбери у wxTimer Start.
Похоже про миллисекунды это твое субъективное мнение. Если тебя интересует реакция интерфейса на что-то то лучше всего привязывать это события к5 событиям (прости за тавтологию - Event'ам)