Características da linguagem mql5, subtilezas e técnicas - página 187

 

Alguém se deparou com uma solução multitemporal para que eu próprio não tenha de reinventar a roda?
Não vejo a implementação como sendo complicada através da utilização de apontadores para a função. É improvável que não tivesse já sido implementado antes de mim.
Ou seja, a tarefa original é criar um temporizador com qualquer periodicidade e atribuir-lhe uma função para lidar com o evento do temporizador. E pode haver qualquer número de temporizadores.

Assim:

#include <Timer.mqh> 

CTimer timers;
int x1=0;
int x2=0;

int OnInit()
  {
   timers.NewTimer(500, Sum1);  // создаем новый таймер с периодом обновления 500  милисекунд и функцией-обраточником Sum1()
   timers.NewTimer(2000, Sum2); // создаем новый таймер с периодом обновления 2000 милисекунд и функцией-обраточником Sum2()
   return(INIT_SUCCEEDED);
  }

...

void OnTimer()
  {
    timers.OnTimer();   
  }

//+------------------------------------------------------------------+

void Sum1() { // данная функция вызывает с периодичностью 500 милисекунд
x1++;
if (x1==10) timers.KillTimer(Sum1); // удаляем этот таймер 
}

void Sum2() { // данная функция вызывает с периодичностью 2000 милисекунд
x2++;
if (x2==10) timers.KillTimer(Sum2); // удаляем этот таймер
}
 
Nikolai Semko:

Ninguém se deparou com uma solução multitemporal

Tenho a certeza que já o vi no KB há muito tempo atrás.
 
fxsaber:
Tenho a certeza que já o vi na Buy More há muito tempo.

Não o consigo encontrar. Estranho.
OK, eu próprio o implementarei. Não deve haver nenhuma armadilha. Vou publicá-lo na Buy More.

 
Nikolai Semko:

Isto é, a tarefa inicial é criar um temporizador com qualquer periodicidade e mapear para ele a sua função de tratamento de eventos do temporizador. E pode haver qualquer número de temporizadores.

uma variante mais simples não serve?

input int            OnTimerMs               = 100;
int OnInit()
{
   EventSetMillisecondTimer(OnTimerMs);
   return(INIT_SUCCEEDED);
}
void  OnTimer()
{
   static uint tickcount_500ms = 0;
   static uint tickcount_1s = 0;
   static uint tickcount_1M = 0;
   uint gettickcount = GetTickCount();
   bool event_500ms  =  gettickcount - tickcount_500ms >= 500;
   bool event_1s     =  gettickcount - tickcount_1s >= 1000;
   bool event_1M     =  gettickcount - tickcount_1M >= 60000;
   

// счетчики 500мс, 1с и 1М
   if(event_500ms)
   {
      tickcount_500ms = gettickcount;
.....
   }

   if(event_1s)
   {
      tickcount_1s = gettickcount;
.....
   }

   if(event_1M)
   {
      tickcount_1M = gettickcount;
......
   }

}

UPD: E assim, pode usar o código fxsaber como um modelo

eis como fazê-lo para que todos os objectos sejam automaticamente apagados https://www.mql5.com/ru/forum/325418/page4#comment_16116740

 
Nikolai Semko:

Não o consigo encontrar. Estranho.
OK, eu próprio o implementarei. Não deve haver nenhuma armadilha. Vou colocá-lo na Buy More.

feito
https://www.mql5.com/ru/code/31306

Multi Timer
Multi Timer
  • www.mql5.com
1. Включите в свою программу класс CTimer 2. Создайте один объект класса СTimer. Например timers. 3. Создайте функции-обработчики необходимых таймеров формата void AnyNameFunction() {....} например с такими именами: 4. Когда вам необходимо создать и запустить таймер, сделайте так из любого места: 5. Когда вам таймер больше не нужен...
 
Igor Makanu:

uma versão mais simples não funcionaria?

UPD: caso contrário, pode usar o código fxsaber como modelo

eis como fazê-lo para que todos os objectos sejam automaticamente apagados https://www.mql5.com/ru/forum/325418/page4#comment_16116740

Claro que o poderia fazer dessa forma. Mas menos legível e mais difícil de gerir.

 

Era uma vez (aproximadamente) que isto acontecia.

É inconveniente usar com aulas.

class CWithTimer {

public:

    void CallMeByTimer();

};

E o temporizador externo (à classe) com apontadores para a função é impotente.

 
Maxim Kuznetsov:

era uma vez (aproximadamente) que o fazia.

É inconveniente usar com aulas.

class CWithTimer {

public:

    void CallMeByTimer();

};

E o temporizador externo (à classe) com apontadores para a função é impotente.

Se se refere à função como um método de classe, então sim, concordo. Eu próprio apercebi-me disso ontem e estou perplexo quanto à forma de resolver o problema.
Eu gostaria de utilizar esta classe dentro de outra classe, caso contrário a utilização é muito limitada.
Pelo menos um botão deve ainda ser implementado e um temporizador já em funcionamento fora da classe deve ser controlado.
 
Nikolai Semko:
Se se refere à função como um método de classe, então sim, concordo. Eu próprio o descobri ontem e estou intrigado com a forma de sair dela.
Eu gostaria de aplicar esta classe dentro de outra classe, caso contrário a aplicação é muito limitada.
No mínimo, precisamos de implementar um singleton e controlar o temporizador já a funcionar fora da classe.
Deve haver um ponteiro para a classe com o temporizador no objecto.
 
Vladimir Simakov:
O objecto deve ter um ponteiro para uma classe com um temporizador.
A questão é como executar um método não estático da classe a partir do ponteiro, mesmo que o objecto de outra classe (neste caso o CTimer) seja uma propriedade (variável) desta classe. Será possível? Receio que não.
Razão: