844 lines
50 KiB
MQL5
844 lines
50 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Managers.mqh |
|
|
//| Copyright 2025, Niquel Mendoza. |
|
|
//| https://www.mql5.com/es/users/nique_372/news |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2025, Niquel Mendoza."
|
|
#property link "https://www.mql5.com/es/users/nique_372/news"
|
|
#property strict
|
|
|
|
#ifndef UTILS_FA_SIMPLE_MANAGER_MQH
|
|
#define UTILS_FA_SIMPLE_MANAGER_MQH
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Includes |
|
|
//+------------------------------------------------------------------+
|
|
//--- CLoggerBase
|
|
#include "SimpleLogger.mqh"
|
|
|
|
//---
|
|
#include "FuncionesBases.mqh"
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Base class for object managers |
|
|
//+------------------------------------------------------------------+
|
|
/*
|
|
ADVERTENCIA: ESTA CLASE SI ELIMINA LOS ITEMS POR DEFECTO, TAMBIEN PROPAGA LOS FLAGS, ES COMO UNA EVOLUCION DE CSPECILZIAEDMANAGER, DADO QUE
|
|
NO SOLO PROPAGA LOS FLAGS SI NO QUE SE PEUDEN HACER MAS COSAS CON LOS ITEMS.
|
|
|
|
WARNING: IF THIS CLASS REMOVES THE DEFAULT ITEMS, IT ALSO PROPAGATES THE FLAGS. IT IS LIKE AN EVOLUTION OF CSPECILZIAEDMANAGER,
|
|
SINCE IT NOT ONLY PROPAGATES THE FLAGS BUT MORE THINGS CAN BE DONE WITH THE ITEMS.
|
|
*/
|
|
|
|
|
|
/*
|
|
Spanish:
|
|
Antes de incluir mqhs se podria poner CMANAGERBASE_DEBUG, este define unicamente quitara verificacion de fuera de rango... para CheckPoitner
|
|
este siempre se debera de hacer, esto lo hago para optimizar, por que si se que un codigo no dara errores entonces, creo que hacer esos check, estan
|
|
por demas.. cuando lo programo, ahi creo qeu si es muy necesario..
|
|
|
|
English:
|
|
Before including mqhs, you could set CMANAGERBASE_DEBUG. This defines that it will only remove the out-of-range check... for CheckPointer,
|
|
this should always be done. I do this for optimization purposes, because if I know a code won't produce errors, then I think doing those checks is unnecessary...
|
|
when I program it, I think it's very necessary.
|
|
*/
|
|
|
|
//---
|
|
//#define CMANAGERBASE_DEBUG
|
|
|
|
//---
|
|
template<typename T>
|
|
class CManagerBase : public CLoggerBase
|
|
{
|
|
protected:
|
|
T* items[]; // Pointers Array
|
|
int total; // Total number of items
|
|
bool clean_in_destructor; // Flag indicating whether items will be deleted in the destructor
|
|
bool funcionar_solo_como_container; // Flag indicating whether the class only functions as a manager (No flags are propagated)
|
|
|
|
//--- Function to propagate logging flags
|
|
void PropagateFlags(const uint8_t flags, bool enable);
|
|
|
|
//--- Internal methods (without calling virtual functions, class-specific use)
|
|
void RemoveInternal(int index);
|
|
inline void AddItemInternal(T* item);
|
|
inline void ReplaceInternal(int index, T* new_item);
|
|
void InsertInternal(T* item, int index);
|
|
|
|
//--- Virtual functions
|
|
virtual void OnAntesClear() {}
|
|
virtual void OnNewElement(int new_pos) {} // Function executed each time a new element is added at index new_pos
|
|
virtual void OnDeleteElement(int delete_pos, T* item) {} // Function executed each time an element is deleted at delete_pos
|
|
|
|
public:
|
|
CManagerBase(bool funcionar_solo_como_container_);
|
|
~CManagerBase();
|
|
|
|
//--- General
|
|
void SetCleanInDestructor(bool new_val) { clean_in_destructor = new_val; }
|
|
inline int Size() const { return total; }
|
|
void CleanItems(bool delete_ptrs); // Clean the class and remove items
|
|
|
|
//--- Basic operations
|
|
// Add
|
|
virtual void AddItem(T* item, bool check_duplicate); // Add item to end of array (pointer)
|
|
void AddItem(T& item, bool check_duplicate); // Add item to end of array (reference - usage: instance)
|
|
inline void AddItemFast(T* item); // Add item to end of array (pointer), without checks
|
|
|
|
// Insert
|
|
bool Insert(T* item, int index); // Insert at position
|
|
bool Insert(T& item, int index); // Insert at position
|
|
|
|
// Remove
|
|
bool Remove(int index); // Remove by index (The function does not delete the pointer)
|
|
bool Remove(T* item); // Remove by object (The function does not delete the pointer)
|
|
bool RemoveFirst(); // Remove first (The function does not delete the pointer)
|
|
bool RemoveLast(); // Remove last (The function does not delete the pointer)
|
|
T* Pop(); // Remove last and return (The function does not delete the pointer)
|
|
|
|
// Replace
|
|
bool Replace(int index, T* new_item); // Replace item
|
|
|
|
// Check index
|
|
inline bool InRange(const int index, const string& function_name) const; // Check index
|
|
|
|
//--- Search
|
|
int Find(T* item); // Find index
|
|
int Exist(T* item); // Check if item exists (unique), returns its index if exists
|
|
T* GetFirst(); // First item
|
|
T* GetLast(); // Last item
|
|
int GetActiveCount(); // Non-invalid items
|
|
|
|
//--- Utilities
|
|
void Compact(); // Remove invalid items
|
|
bool Swap(int index1, int index2); // Swap items
|
|
void Reverse(); // Reverse order
|
|
virtual void PrintInfo(); // Debug info
|
|
|
|
//--- Operators
|
|
#ifdef CMANAGERBASE_DEBUG
|
|
T* operator[](const int index) { return InRange(index, FUNCION_ACTUAL) ? items[index] : NULL; }
|
|
#else
|
|
T* operator[](const int index) { return items[index]; }
|
|
#endif
|
|
|
|
//--- Logs
|
|
void AddLogFlags(const uint8_t flags) override;
|
|
void RemoveLogFlags(const uint8_t flags) override;
|
|
void EnableAllLogs() override;
|
|
void DisableAllLogs() override;
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Constructor |
|
|
//+------------------------------------------------------------------+
|
|
template<typename T> CManagerBase::CManagerBase(bool funcionar_solo_como_container_) : total(0)
|
|
{
|
|
ArrayResize(items, 0);
|
|
this.funcionar_solo_como_container = funcionar_solo_como_container_;
|
|
this.clean_in_destructor = true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T> CManagerBase::~CManagerBase()
|
|
{
|
|
if(clean_in_destructor)
|
|
CleanItems(true);
|
|
else
|
|
{
|
|
ArrayResize(items, 0);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Function to check if an index is in the range [0 - (total-1)] |
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
inline bool CManagerBase::InRange(const int index, const string& function_name) const
|
|
{
|
|
if(index < total && index >= 0)
|
|
return true;
|
|
else
|
|
{
|
|
LogError(StringFormat("(%s) Index %d is invalid, array range [ %d - %d ]", function_name, index, total), function_name);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Functions for (add - insert - replace) elements |
|
|
//| (without calling virtual functions, class-specific use) |
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::RemoveInternal(int index)
|
|
{
|
|
//---
|
|
for(int i = index; i < total - 1; i++)
|
|
items[i] = items[i + 1];
|
|
|
|
//---
|
|
total--;
|
|
ArrayResize(items, total);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
inline void CManagerBase::AddItemInternal(T* item)
|
|
{
|
|
ArrayResize(items, total + 1);
|
|
items[total] = item;
|
|
total++;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
inline void CManagerBase::ReplaceInternal(int index, T* new_item)
|
|
{
|
|
items[index] = new_item;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::InsertInternal(T* item, int index)
|
|
{
|
|
//---
|
|
ArrayResize(items, total + 1);
|
|
|
|
//---
|
|
for(int i = total; i > index; i--)
|
|
items[i] = items[i - 1];
|
|
|
|
//---
|
|
items[index] = item;
|
|
total++;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Functions to (add - insert - replace) items |
|
|
//| (public with calls to virtual functions) |
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::AddItem(T* item, bool check_duplicate)
|
|
{
|
|
//---
|
|
if(!CheckPointer(item))
|
|
{
|
|
LogError("Cannot add NULL item", FUNCION_ACTUAL);
|
|
return;
|
|
}
|
|
|
|
//--- Only check if exists if requested
|
|
if(check_duplicate)
|
|
{
|
|
if(Exist(item) != -1)
|
|
{
|
|
LogWarning("Item not added, it's duplicated", FUNCION_ACTUAL);
|
|
return;
|
|
}
|
|
}
|
|
|
|
//--- Resize
|
|
ArrayResize(items, total + 1);
|
|
items[total] = item;
|
|
|
|
//--- Add log_flags
|
|
if(!funcionar_solo_como_container)
|
|
items[total].AddLogFlags(LogFlags());
|
|
|
|
//---
|
|
OnNewElement(total);
|
|
|
|
//---
|
|
total++;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::AddItem(T& item, bool check_duplicate)
|
|
{
|
|
AddItem(GetPointer(item), check_duplicate);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
inline void CManagerBase::AddItemFast(T* item)
|
|
{
|
|
ArrayResize(items, total + 1);
|
|
items[total] = item;
|
|
OnNewElement(total);
|
|
total++;
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
bool CManagerBase::Insert(T* item, int index)
|
|
{
|
|
//---
|
|
if(CheckPointer(item) == POINTER_INVALID)
|
|
{
|
|
LogError("Cannot insert NULL item", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
if(!InRange(index, FUNCION_ACTUAL))
|
|
return false;
|
|
|
|
//---
|
|
ArrayResize(items, total + 1);
|
|
|
|
//--- Move elements to the right
|
|
for(int i = total; i > index; i--)
|
|
items[i] = items[i - 1];
|
|
|
|
//---
|
|
items[index] = item;
|
|
total++;
|
|
|
|
//---
|
|
OnNewElement(index);
|
|
|
|
//--- Log
|
|
LogInfo(StringFormat("Item inserted at index %d. Total: %d", index, total), FUNCION_ACTUAL);
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
bool CManagerBase::Insert(T& item, int index)
|
|
{
|
|
return Insert(::GetPointer(item), index);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
bool CManagerBase::Remove(int index)
|
|
{
|
|
//---
|
|
#ifdef CMANAGERBASE_DEBUG
|
|
if(!InRange(index, FUNCION_ACTUAL))
|
|
return false;
|
|
#endif
|
|
|
|
//---
|
|
OnDeleteElement(index, items[index]);
|
|
|
|
//---
|
|
for(int i = index; i < total - 1; i++)
|
|
items[i] = items[i + 1];
|
|
|
|
//---
|
|
total--;
|
|
ArrayResize(items, total);
|
|
|
|
//--- Log
|
|
LogInfo(StringFormat("Item removed from index %d. Total: %d", index, total), FUNCION_ACTUAL);
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
bool CManagerBase::Remove(T* item)
|
|
{
|
|
// Find already checks if the item is invalid, and if it returns -1, Remove handles it (if CMANAGERBASE_DEBUG is enabled)
|
|
return Remove(Find(item));
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
bool CManagerBase::Replace(int index, T* new_item)
|
|
{
|
|
#ifdef CMANAGERBASE_DEBUG
|
|
if(!InRange(index, FUNCION_ACTUAL))
|
|
return false;
|
|
#endif
|
|
|
|
//---
|
|
if(CheckPointer(new_item) == POINTER_INVALID)
|
|
{
|
|
LogError("Cannot replace with NULL item", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
//---
|
|
OnDeleteElement(index, items[index]);
|
|
items[index] = new_item;
|
|
OnNewElement(index);
|
|
|
|
//---
|
|
LogInfo(StringFormat("Item replaced at index %d", index), FUNCION_ACTUAL);
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
T* CManagerBase::Pop()
|
|
{
|
|
//---
|
|
if(total == 0)
|
|
{
|
|
LogWarning("No items to Pop", FUNCION_ACTUAL);
|
|
return NULL;
|
|
}
|
|
|
|
//---
|
|
const int last_index = total - 1;
|
|
T* last_item = items[last_index];
|
|
OnDeleteElement(last_index, last_item);
|
|
|
|
//---
|
|
total--;
|
|
ArrayResize(items, total);
|
|
|
|
//---
|
|
LogInfo(StringFormat("Pop executed. Total: %d", total), FUNCION_ACTUAL);
|
|
return last_item;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
bool CManagerBase::RemoveFirst()
|
|
{
|
|
return Remove(0);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
bool CManagerBase::RemoveLast()
|
|
{
|
|
return Remove(total - 1);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
int CManagerBase::Find(T* item)
|
|
{
|
|
//---
|
|
if(CheckPointer(item) == POINTER_INVALID)
|
|
{
|
|
LogError("Cannot find index of item*, its pointer is invalid", FUNCION_ACTUAL);
|
|
return -1;
|
|
}
|
|
|
|
//---
|
|
for(int i = 0; i < total; i++)
|
|
if(items[i] == item)
|
|
return i;
|
|
|
|
//---
|
|
LogWarning("Index not found for item pointer", FUNCION_ACTUAL);
|
|
return -1;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template <typename T>
|
|
int CManagerBase::Exist(T* item)
|
|
{
|
|
//---
|
|
if(CheckPointer(item) == POINTER_INVALID)
|
|
{
|
|
LogError("Pointer is invalid", FUNCION_ACTUAL);
|
|
return -1;
|
|
}
|
|
|
|
//---
|
|
const void* ptr1 = item;
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
const void* ptr2 = items[i];
|
|
if(ptr2 == ptr1)
|
|
return i;
|
|
}
|
|
|
|
//---
|
|
return -1;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
T* CManagerBase::GetFirst()
|
|
{
|
|
if(total > 0)
|
|
return items[0];
|
|
|
|
LogWarning("Total size of items is less than 1, there is no first item, will return NULL", FUNCION_ACTUAL);
|
|
return NULL;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
T* CManagerBase::GetLast()
|
|
{
|
|
if(total > 0)
|
|
return items[total - 1];
|
|
|
|
LogWarning("Total size of items is less than 1, there is no last item, will return NULL", FUNCION_ACTUAL);
|
|
return NULL;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
int CManagerBase::GetActiveCount()
|
|
{
|
|
int count = 0;
|
|
for(int i = 0; i < total; i++)
|
|
if(CheckPointer(items[i]) != POINTER_INVALID)
|
|
count++;
|
|
|
|
//---
|
|
return count;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::Compact()
|
|
{
|
|
//---
|
|
int write_pos = 0;
|
|
|
|
//---
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
if(CheckPointer(items[i]) != POINTER_INVALID)
|
|
{
|
|
if(write_pos != i)
|
|
items[write_pos] = items[i];
|
|
write_pos++;
|
|
}
|
|
}
|
|
|
|
//---
|
|
int old_total = total;
|
|
total = write_pos;
|
|
ArrayResize(items, total);
|
|
|
|
//--- Log
|
|
LogInfo(StringFormat("Compaction completed: %d -> %d items", old_total, total), FUNCION_ACTUAL);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
bool CManagerBase::Swap(int index1, int index2)
|
|
{
|
|
#ifdef CMANAGERBASE_DEBUG
|
|
if(!InRange(index1, FUNCION_ACTUAL) || !InRange(index2, FUNCION_ACTUAL))
|
|
return false;
|
|
#endif
|
|
|
|
//---
|
|
T* temp = items[index1];
|
|
items[index1] = items[index2];
|
|
items[index2] = temp;
|
|
|
|
//--- Log
|
|
LogCaution(StringFormat("Items swapped: indices %d and %d", index1, index2), FUNCION_ACTUAL);
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::Reverse()
|
|
{
|
|
ArrayReverse(items);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::CleanItems(bool delete_ptrs)
|
|
{
|
|
//---
|
|
if(total < 1)
|
|
return;
|
|
|
|
//---
|
|
const int t = total;
|
|
OnAntesClear();
|
|
|
|
//---
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
OnDeleteElement(i, items[i]);
|
|
if(delete_ptrs && CheckPointer(items[i]) == POINTER_DYNAMIC)
|
|
{
|
|
delete items[i];
|
|
items[i] = NULL;
|
|
}
|
|
}
|
|
|
|
//---
|
|
ArrayResize(items, 0);
|
|
total = 0;
|
|
|
|
//--- Log
|
|
LogWarning(StringFormat("Manager cleaned, objects before = %d, now = 0", t), FUNCION_ACTUAL);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Function to print manager information |
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::PrintInfo()
|
|
{
|
|
LogInfo(StringFormat("Manager Info - Total: %d, Active: %d, ArraySize: %d", total, GetActiveCount(), ArraySize(items)), FUNCION_ACTUAL);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Functions for propagating logging flags |
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::PropagateFlags(const uint8_t flags, bool enable)
|
|
{
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
if(enable)
|
|
items[i].AddLogFlags(flags);
|
|
else
|
|
items[i].RemoveLogFlags(flags);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::AddLogFlags(const uint8_t flags)
|
|
{
|
|
CLoggerBase::AddLogFlags(flags);
|
|
|
|
if(funcionar_solo_como_container)
|
|
return;
|
|
|
|
PropagateFlags(flags, true);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::RemoveLogFlags(const uint8_t flags)
|
|
{
|
|
CLoggerBase::RemoveLogFlags(flags);
|
|
|
|
if(funcionar_solo_como_container)
|
|
return;
|
|
|
|
PropagateFlags(flags, false);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::EnableAllLogs()
|
|
{
|
|
CLoggerBase::EnableAllLogs();
|
|
|
|
if(funcionar_solo_como_container)
|
|
return;
|
|
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
items[i].EnableAllLogs();
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
template<typename T>
|
|
void CManagerBase::DisableAllLogs()
|
|
{
|
|
CLoggerBase::DisableAllLogs();
|
|
|
|
if(funcionar_solo_como_container)
|
|
return;
|
|
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
items[i].DisableAllLogs();
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------------------+
|
|
//| Base class for flag propagation |
|
|
//| Utils: When you have a class with several objects separate from CLoggerBase, |
|
|
//| so propagating logs to instances or pointers is necessary |
|
|
//+------------------------------------------------------------------------------+
|
|
/*
|
|
Spanish:
|
|
ADVERTENCIA NO SE ELIMINAN LOS ITEMS, PERO SI HAY UNA FUNCION INTEGRADA PARA HCERLO PERO ESTA SOLO ESTA COMO FUNCIONALDAD, IDEALMENTE SOLO SUAR PARA PROPAGAR FLAGS
|
|
English:
|
|
WARNING ITEMS ARE NOT REMOVED, BUT THERE IS A BUILT-IN FUNCTION TO DO SO, BUT THIS IS ONLY FOR FUNCTIONALITY, IDEALLY ONLY USED TO PROPAGATE FLAGS
|
|
*/
|
|
|
|
//--- Implementation
|
|
class CSpecializedManager : public CLoggerBase
|
|
{
|
|
protected:
|
|
int total;
|
|
CLoggerBase* items[];
|
|
|
|
void PropagateFlags(const uint8_t flags, bool enable);
|
|
|
|
void RemoveLogger(int index);
|
|
bool RemoveLogger(CLoggerBase * _logger);
|
|
void AddLogger(CLoggerBase * _logger);
|
|
void AddLogger(CLoggerBase & _logger);
|
|
virtual void CleanItems(const string &den_name) final;
|
|
|
|
public:
|
|
CSpecializedManager();
|
|
void AddLogFlags(const uint8_t flags) override;
|
|
void RemoveLogFlags(const uint8_t flags) override;
|
|
void EnableAllLogs() override;
|
|
void DisableAllLogs() override;
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Constructor |
|
|
//+------------------------------------------------------------------+
|
|
CSpecializedManager::CSpecializedManager() : total(0)
|
|
{
|
|
ArrayResize(items, 0);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CSpecializedManager::CleanItems(const string &den_name)
|
|
{
|
|
#ifdef CSM_DEBUG_ELIMIACIONES
|
|
const string f = StringFormat("CSpecializedManger[%s]::CleanItems", den_name);
|
|
FastLog(f, "WARNING", "Se esta limpiando los items");
|
|
#endif
|
|
|
|
//---
|
|
for(int i = 0; i < total; i++)
|
|
if(CheckPointer(items[i]) == POINTER_DYNAMIC)
|
|
delete items[i];
|
|
|
|
//---
|
|
total = 0;
|
|
ArrayResize(items, 0);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CSpecializedManager::AddLogger(CLoggerBase* _logger)
|
|
{
|
|
if(CheckPointer(_logger) == POINTER_INVALID)
|
|
{
|
|
LogFatalError("El puntero *_logger es inválido", FUNCION_ACTUAL);
|
|
return;
|
|
}
|
|
|
|
//---
|
|
AddArrayNoVerification1(this.items, _logger, total, 0);
|
|
|
|
//---
|
|
total = ArraySize(items);
|
|
|
|
//---
|
|
_logger.AddLogFlags(LogFlags());
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void CSpecializedManager::AddLogger(CLoggerBase &_logger)
|
|
{
|
|
AddLogger(GetPointer(_logger));
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CSpecializedManager::PropagateFlags(const uint8_t flags, bool enable)
|
|
{
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
if(enable)
|
|
items[i].AddLogFlags(flags);
|
|
else
|
|
items[i].RemoveLogFlags(flags);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void CSpecializedManager::AddLogFlags(const uint8_t flags)
|
|
{
|
|
CLoggerBase::AddLogFlags(flags);
|
|
PropagateFlags(flags, true);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void CSpecializedManager::RemoveLogFlags(const uint8_t flags)
|
|
{
|
|
CLoggerBase::RemoveLogFlags(flags);
|
|
PropagateFlags(flags, false);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void CSpecializedManager::EnableAllLogs()
|
|
{
|
|
CLoggerBase::EnableAllLogs();
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
items[i].EnableAllLogs();
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
void CSpecializedManager::DisableAllLogs()
|
|
{
|
|
CLoggerBase::DisableAllLogs();
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
items[i].DisableAllLogs();
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CSpecializedManager::RemoveLogger(int index)
|
|
{
|
|
if(index < 0 || index >= total)
|
|
{
|
|
LogError(StringFormat("Índice inválido: %d. Rango válido: 0-%d", index, total - 1), FUNCION_ACTUAL);
|
|
return;
|
|
}
|
|
|
|
if(total == 0)
|
|
{
|
|
LogWarning("No hay loggers para remover", FUNCION_ACTUAL);
|
|
return;
|
|
}
|
|
|
|
for(int i = index; i < total - 1; i++)
|
|
{
|
|
items[i] = items[i + 1];
|
|
}
|
|
|
|
total--;
|
|
ArrayResize(items, total);
|
|
|
|
LogInfo(StringFormat("Logger en índice %d removido. Total restante: %d", index, total), FUNCION_ACTUAL);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
bool CSpecializedManager::RemoveLogger(CLoggerBase* _logger)
|
|
{
|
|
if(CheckPointer(_logger) == POINTER_INVALID)
|
|
{
|
|
LogError("No se puede remover logger nulo", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
if(items[i] == _logger)
|
|
{
|
|
RemoveLogger(i);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
LogWarning("Logger no encontrado para remover", FUNCION_ACTUAL);
|
|
return false;
|
|
}
|
|
#endif
|
|
//+------------------------------------------------------------------+
|