168 lines
4.6 KiB
MQL5
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;
|