MQLArticles/Utils/FA/Events.mqh

525 lines
34 KiB
MQL5

2026-01-29 08:19:08 -05:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| Events.mqh |
//| Niquel y Leo, Copyright 2025. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Niquel y Leo, Copyright 2025"
#property link "https://www.mql5.com"
#property strict
#ifndef MQLARTICLES_UTILS_FA_EVENTS_MQH
#define MQLARTICLES_UTILS_FA_EVENTS_MQH
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include "Managers.mqh"
//+------------------------------------------------------------------+
//| Clase base para los eventos basicos |
//+------------------------------------------------------------------+
class CAllClassEventsBasic : public CSpecializedManager
{
protected:
bool m_is_global;
int m_hijos_events_valid_idx[];
int m_hijos_events_valid_idx_size;
//--- Impidimos la instanciacion solo ptr.. pero se debe de asignar..
CAllClassEventsBasic(const bool& is_g) : m_is_global(is_g), m_hijos_events_valid_idx_size(0) {}
//--- Ocultamos
void AddLogger(CLoggerBase* _logger, bool is_all_class);
void AddLogger(CLoggerBase &_logger, bool is_all_class);
bool RemoveLogger(CLoggerBase* _logger);
//---
void CleanItems(const string &den_name) override final;
void CleanItemsNoDelete(const string& den_name) override final;
public:
~CAllClassEventsBasic() {}
//---
void __SetGlobal(bool is_global);
//---
__forceinline bool IsGlobalInstance() { return m_is_global; }
//--- Eventos basicos
// Nota: Estos eventos son los basicos
virtual void OnNewDay(const datetime& curr_time) {}
virtual void OnNewWeek(const datetime& curr_time) {}
virtual void OnNewMonth(const datetime& curr_time) {}
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CAllClassEventsBasic::CleanItems(const string &den_name)
{
m_hijos_events_valid_idx_size = ArrayResize(m_hijos_events_valid_idx, 0);
CSpecializedManager::CleanItems(den_name);
}
//+------------------------------------------------------------------+
void CAllClassEventsBasic::CleanItemsNoDelete(const string &den_name)
{
m_hijos_events_valid_idx_size = ArrayResize(m_hijos_events_valid_idx, 0);
CSpecializedManager::CleanItemsNoDelete(den_name);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CAllClassEventsBasic::AddLogger(CLoggerBase* _logger, bool is_all_class)
{
//---
if(!CheckPointer(_logger))
{
LogFatalError("El puntero *_logger es inv<00>lido", FUNCION_ACTUAL);
return;
}
//---
m_loggers[ArrayResize(m_loggers, (++m_loggers_total)) - 1] = _logger;
//---
if(is_all_class)
m_hijos_events_valid_idx[ArrayResize(m_hijos_events_valid_idx, (++m_hijos_events_valid_idx_size)) - 1] = (m_loggers_total - 1);
//---
_logger.AddLogFlags(LogFlags());
}
//+------------------------------------------------------------------+
__forceinline void CAllClassEventsBasic::AddLogger(CLoggerBase &_logger, bool is_all_class)
{
AddLogger(GetPointer(_logger), is_all_class);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
/*
- [L1, L2, L3, L4, L5, L6, L7, L8]
0 3 5 7
- Eliminar L4
- [L1, L2, L3, L8, L5, L6, L7]
0 3 5
- [0, 3, 7, 5]
- [0, 5, 7]
- [0, 5, 3]
L1, L8,
- El orden no improta...
aqui eliminamos usando find + swap
*/
bool CAllClassEventsBasic::RemoveLogger(CLoggerBase* _logger)
{
//---
if(!CheckPointer(_logger))
{
LogError("Se esta removiendo un logger NULL", FUNCION_ACTUAL);
}
//---
for(int i = 0; i < m_loggers_total; i++)
{
if(m_loggers[i] == _logger)
{
//---
const int last_idx = --m_loggers_total;
m_loggers[i] = m_loggers[last_idx];
ArrayResize(m_loggers, m_loggers_total);
//---
for(int k = 0; k < m_hijos_events_valid_idx_size; k++)
{
if(m_hijos_events_valid_idx[k] == i)
{
m_hijos_events_valid_idx[k] = m_hijos_events_valid_idx[--m_hijos_events_valid_idx_size];
ArrayResize(m_hijos_events_valid_idx, m_hijos_events_valid_idx_size);
k--;
}
else
if(m_hijos_events_valid_idx[k] == last_idx)
{
m_hijos_events_valid_idx[k] = i;
}
}
//---
LogInfo(StringFormat("Logger en <00>ndice %d removido. Total restante: %d", i, m_loggers_total), FUNCION_ACTUAL);
//---
return true;
}
}
//---
LogWarning("Logger no encontrado para remover", FUNCION_ACTUAL);
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CAllClassEventsBasic::__SetGlobal(bool is_global)
{
m_is_global = is_global;
for(int k = 0; k < m_hijos_events_valid_idx_size; k++)
((CAllClassEventsBasic*)m_loggers[m_hijos_events_valid_idx[k]]).__SetGlobal(is_global);
}
//+------------------------------------------------------------------+
//| Clase base para los eventos |
//+------------------------------------------------------------------+
#define BASICEVENT_REG_FLAG_ON_NEW_DAY (1)
#define BASICEVENT_REG_FLAG_ON_NEW_WEEK (2)
#define BASICEVENT_REG_FLAG_ON_NEW_MON (4)
//---
#define BASICEVENT_REG_ALL_FLAG (BASICEVENT_REG_FLAG_ON_NEW_DAY|BASICEVENT_REG_FLAG_ON_NEW_WEEK|BASICEVENT_REG_FLAG_ON_NEW_MON)
//---
class CBasicEvents
{
private:
static CAllClassEventsBasic* m_on_new_day[];
static int m_on_new_day_size;
static CAllClassEventsBasic* m_on_new_week[];
static int m_on_new_week_size;
static CAllClassEventsBasic* m_on_new_mon[];
static int m_on_new_mon_size;
//---
static void RemoveFromArrayFast(CAllClassEventsBasic* &array[], int &size, CAllClassEventsBasic* &ptr);
public:
CBasicEvents(void) {}
~CBasicEvents(void) {}
//--- Registrar
static void Register(CAllClassEventsBasic* ptr, const uint8_t flags);
static void RegisterEvent(CAllClassEventsBasic* ptr, const uint8_t event);
static void Unregister(CAllClassEventsBasic* ptr, const uint8_t flags);
static void UnregisterEvent(CAllClassEventsBasic* ptr, const uint8_t event);
//--- Eventos
static void OnNewDay(const datetime& curr_time);
static void OnNewWeek(const datetime& curr_time);
static void OnNewMonth(const datetime& curr_time);
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static void CBasicEvents::RemoveFromArrayFast(CAllClassEventsBasic* &array[], int &size, CAllClassEventsBasic* &ptr)
{
for(int i = 0; i < size; i++)
{
if(array[i] == ptr)
{
array[i] = array[size - 1];
ArrayResize(array, --size);
return;
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static void CBasicEvents::Unregister(CAllClassEventsBasic* ptr, const uint8_t flags)
{
if(!CheckPointer(ptr))
{
FastLog(FUNCION_ACTUAL, WARNING_TEXT, "Invalid pointer for unregister");
return;
}
//--- OnNewDay
if((flags & BASICEVENT_REG_FLAG_ON_NEW_DAY) != 0)
RemoveFromArrayFast(m_on_new_day, m_on_new_day_size, ptr);
//--- OnNewWeek
if((flags & BASICEVENT_REG_FLAG_ON_NEW_WEEK) != 0)
RemoveFromArrayFast(m_on_new_week, m_on_new_week_size, ptr);
//--- OnNewMonth
if((flags & BASICEVENT_REG_FLAG_ON_NEW_MON) != 0)