mql5/Include/Escape/RAII.mqh
2025-08-05 01:57:33 -04:00

168 lines
4.6 KiB
MQL5

//+------------------------------------------------------------------+
//| RAII.mqh |
//| Copyright 2025, EscapeEA |
//| https://www.escapeea.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, EscapeEA"
#property link "https://www.escapeea.com"
#property version "1.00"
#property strict
#include <Object.mqh>
//+------------------------------------------------------------------+
//| RAII wrapper for file handles |
//+------------------------------------------------------------------+
class CFileRAII {
private:
int m_handle; // File handle (MQL5 FileOpen returns int)
// Prevent copying
CFileRAII(const CFileRAII&);
void operator=(const CFileRAII&);
public:
CFileRAII(const string filename, const int flags, const int delimiter = '\t', const int codepage = CP_ACP) {
// FileOpen returns int according to MQL5 documentation
m_handle = (int)FileOpen(filename, flags, delimiter, codepage);
}
~CFileRAII() {
if(m_handle != INVALID_HANDLE) {
FileClose(m_handle);
}
}
// Check if file was opened successfully
bool IsValid() const {
return m_handle != INVALID_HANDLE;
}
// Get the file handle
int GetHandle() const {
return m_handle;
}
// Get the file handle as long if needed
long GetHandleAsLong() const {
return (long)m_handle;
}
// Check if handle is valid
bool IsHandleValid() const {
return m_handle != INVALID_HANDLE;
}
};
//+------------------------------------------------------------------+
//| RAII wrapper for indicators |
//+------------------------------------------------------------------+
class CIndicatorRAII {
private:
int m_handle;
// Prevent copying
CIndicatorRAII(const CIndicatorRAII&);
void operator=(const CIndicatorRAII&);
public:
// Constructor for indicators with up to 8 parameters (MQL5 limit for iCustom)
CIndicatorRAII(const string symbol, const ENUM_TIMEFRAMES timeframe, const string name,
const int param1=0, const int param2=0, const int param3=0, const int param4=0,
const int param5=0, const int param6=0, const int param7=0, const int param8=0) {
m_handle = iCustom(symbol, timeframe, name, param1, param2, param3, param4, param5, param6, param7, param8);
}
~CIndicatorRAII() {
if(m_handle != INVALID_HANDLE) {
IndicatorRelease(m_handle);
}
}
// Check if indicator was created successfully
bool IsValid() const {
return m_handle != INVALID_HANDLE;
}
// Get the indicator handle
int GetHandle() const {
return m_handle;
}
};
//+------------------------------------------------------------------+
//| RAII wrapper for arrays |
//+------------------------------------------------------------------+
template<typename T>
class CArrayRAII {
private:
T m_array[];
// Prevent copying
CArrayRAII(const CArrayRAII&);
void operator=(const CArrayRAII&);
public:
CArrayRAII(int size = 0, int reserve = 0) {
if (reserve > 0) {
ArrayResize(m_array, 0, reserve);
}
if (size > 0) {
ArrayResize(m_array, size);
}
}
~CArrayRAII() {
ArrayFree(m_array);
}
// Resize the array
int Resize(int size, int reserve = 0) {
return ArrayResize(m_array, size, reserve);
}
// Get array size
int Size() const {
return ArraySize(m_array);
}
// Access array elements
T operator[](int index) const {
return m_array[index];
}
// Access array elements by reference
T& operator[](int index) {
return m_array[index];
}
};
//+------------------------------------------------------------------+
//| RAII wrapper for critical sections |
//+------------------------------------------------------------------+
class CCriticalSectionRAII {
private:
static int m_lock;
// Prevent copying
CCriticalSectionRAII(const CCriticalSectionRAII&);
void operator=(const CCriticalSectionRAII&);
public:
CCriticalSectionRAII() {
while (true) {
if (m_lock == 0) {
m_lock = 1;
break;
}
Sleep(1);
}
}
~CCriticalSectionRAII() {
m_lock = 0;
}
};
// Initialize static member
static int CCriticalSectionRAII::m_lock = 0;