2026-10-05 17:54:12 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| DomDef.mqh |
|
| | | //| Copyright 2026, Niquel Mendoza. |
|
| | | //| https://www.mql5.com/ |
|
| | | //+------------------------------------------------------------------+
|
| | | #property copyright "Copyright 2026, Niquel Mendoza."
|
| | | #property link "https://www.mql5.com/"
|
| | | #property strict
|
| | |
|
| | | #ifndef BASESPARSERSLAN_SRC_DOM_DOM_DEF_MQH
|
| | | #define BASESPARSERSLAN_SRC_DOM_DOM_DEF_MQH
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | #include "DomBaseHeader.mqh"
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Code |
|
| | | //+------------------------------------------------------------------+
|
| | | namespace TSN
|
| | | {
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | class CDomNodeManager
|
| | | {
|
| | | public:
|
| | | CDomNodeManager();
|
| | | ~CDomNodeManager() {}
|
| | |
|
| | | //--- String
|
| | | //- Stack
|
| | | int m_string_stack_size;
|
| | | int m_string_stack_r;
|
| | | string m_string_stack[];
|
| | | //- Free
|
| | | int m_string_free[];
|
| | | int m_string_free_r;
|
| | | int m_string_free_s;
|
| | | //- Methods
|
| | | void FreeString(const int ix);
|
| | | int ReserveString();
|
| | |
|
| | | //--- Array
|
| | | struct NodeValues
|
| | | {
|
| | | CDomNodeBase* values[];
|
| | | int values_size;
|
| | | int values_r;
|
| | | };
|
| | | //- node
|
| | | NodeValues m_node[];
|
| | | int m_node_size;
|
| | | int m_node_r;
|
| | | //- free
|
| | | int m_node_free[];
|
| | | int m_node_free_r;
|
| | | int m_node_free_s;
|
| | |
|
| | | //- Methods
|
| | | template <typename T>
|
| | | int ToArray(const int ix, T& array[]) const;
|
| | | void ClearArray(const int ix);
|
| | | bool DeleteElementArr(const int ix, const int el);
|
| | | bool AddElementArr(const int ix, CDomNodeBase* ptr);
|
| | | void FreeArr(const int ix);
|
| | | int ReserveArr(const int initial_reserve);
|
| | | int SlicingArr(const int ix, CDomNodeBase* &out[], int dst_start = 0
|
| | | , int cur = -1, int end = -1, int step = 1) const;
|
| | | int ArrCopyTo(const int ix, CDomNodeBase *&out[], int dst_start) const;
|
| | |
|
| | | //--- Obj
|
| | | CHashMapFast(string, CDomNodeBase*)* m_objs[];
|
| | | int m_objs_size;
|
| | | int m_objs_r;
|
| | | //- free
|
| | | int m_objs_free[];
|
| | | int m_objs_free_r;
|
| | | int m_objs_free_s;
|
| | |
|
| | | //- Methods
|
| | | void FreeObj(const int ix);
|
| | | int ReserveObj(const int initial_reserve);
|
| | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | CDomNodeManager::CDomNodeManager()
|
| | | : m_string_free_s(0), m_string_stack_size(0), m_node_free_s(0), m_node_size(0), m_objs_size(0), m_objs_free_s(0),
|
| | | m_string_free_r(8), m_string_stack_r(8), m_node_free_r(8), m_node_r(8), m_objs_free_r(8), m_objs_r(8)
|
| | | {
|
| | | ArrayResize(m_string_free, m_string_free_r, m_string_free_r);
|
| | | ArrayResize(m_string_stack, m_string_stack_r, m_string_stack_r);
|
| | |
|
| | | ArrayResize(m_node_free, m_node_free_r, m_node_free_r);
|
| | | ArrayResize(m_node, m_node_r, m_node_r);
|
| | |
|
| | | ArrayResize(m_objs_free, m_objs_free_r, m_objs_free_r);
|
| | | ArrayResize(m_objs, m_objs_r, m_objs_r);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Obj |
|
| | | //+------------------------------------------------------------------+
|
| | | int CDomNodeManager::ReserveObj(const int initial_reserve)
|
| | | {
|
| | | //---
|
| | | if(m_objs_free_s > 0)
|
| | | {
|
| | | const int idx = m_objs_free[--m_objs_free_s];
|
| | | return idx;
|
| | | }
|
| | |
|
| | | //---
|
| | | if(m_objs_size + 1 >= m_objs_r)
|
| | | {
|
| | | m_objs_r <<= 1;
|
| | | ArrayResize(m_objs, m_objs_r, m_objs_r);
|
| | | }
|
| | |
|
| | | //---
|
| | | m_objs[m_objs_size++] = new CHashMapFast(string, CDomNodeBase*)(initial_reserve);
|
| | | return m_objs_size - 1;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | void CDomNodeManager::FreeObj(const int ix)
|
| | | {
|
| | | //---
|
| | | //Print("INicio elimiacion: " , ix);
|
| | | CHashMapFast(string, CDomNodeBase*)* ptr = m_objs[ix];
|
| | | CHashMapFastIterator(string, CDomNodeBase*) it = ptr.BeginIteration();
|
| | |
|
| | | //--- Iteramos por todas los value y eliminamos todos los valores
|
| | | while(it.IsValid())
|
| | | {
|
| | | CDomNodeBase* f = it.Val();
|
| | | // Print(it.Key());
|
| | | // En caso el contexto del objeto... a eliminar es el mismo (proviene de la misma pila)
|
| | | // ENtonces eliminamos..
|
| | |
|
| | | //---
|
| | | // puntero colgado
|
| | | // hacemos esto dado qeu si se elimina un ref antes del "base"
|
| | | // se qeuda colgado por lo que ya su valor es invaido y no podemos tocar dicho objeto
|
| | | if(CheckPointer(f) == POINTER_DYNAMIC && f.m_ctx == &this)
|
| | | {
|
| | | //Print("Eliminado: " , it.Key(), " Es nuestro");
|
| | |
|
| | | delete f;
|
| | | }
|
| | | // else
|
| | | // Print("No eliminado: " , it.Key(), " No es nuestro");
|
| | |
|
| | | //---
|
| | | it.Next();
|
| | | }
|
| | |
|
| | | //--- Eliminamos el hashmap
|
| | | if(CheckPointer(ptr) == POINTER_DYNAMIC)
|
| | | delete ptr;
|
| | |
|
| | | //--- Delete
|
| | | if(m_objs_free_s + 1 >= m_objs_free_r)
|
| | | {
|
| | | m_objs_free_r <<= 1;
|
| | | ArrayResize(m_objs_free, m_objs_free_r, m_objs_free_r);
|
| | | }
|
| | | m_objs_free[m_objs_free_s++] = ix;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Stirng |
|
| | | //+------------------------------------------------------------------+
|
| | | int CDomNodeManager::ReserveString(void)
|
| | | {
|
| | | //---
|
| | | if(m_string_free_s > 0)
|
| | | {
|
| | | const int idx = m_string_free[--m_string_free_s];
|
| | | return idx;
|
| | | }
|
| | |
|
| | | //---
|
| | | if(m_string_stack_size + 1 >= m_string_stack_r)
|
| | | {
|
| | | m_string_stack_r <<= 1;
|
| | | ArrayResize(m_string_stack, m_string_stack_r, m_string_stack_r);
|
| | | }
|
| | | m_string_stack_size++;
|
| | | return m_string_stack_size - 1;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | void CDomNodeManager::FreeString(const int ix)
|
| | | {
|
| | | if(m_string_free_s + 1 >= m_string_free_r)
|
| | | {
|
| | | m_string_free_r <<= 1;
|
| | | ArrayResize(m_string_free, m_string_free_r, m_string_free_r);
|
| | | }
|
| | | m_string_free[m_string_free_s++] = ix;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Array |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CDomNodeManager::AddElementArr(const int ix, CDomNodeBase *ptr)
|
| | | {
|
| | | //---
|
| | | if(m_node[ix].values_size + 1 >= m_node[ix].values_r)
|
| | | {
|
| | | m_node[ix].values_r <<= 1;
|
| | | ArrayResize(m_node[ix].values, m_node[ix].values_r, m_node[ix].values_r);
|
| | | }
|
| | |
|
| | | //---
|
| | | m_node[ix].values[m_node[ix].values_size++] = ptr;
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CDomNodeManager::DeleteElementArr(const int ix, const int el)
|
| | | {
|
| | | //---
|
| | | if(el < 0 || el >= m_node[ix].values_size)
|
| | | return false;
|
| | |
|
| | | //---
|
| | | const int t = --m_node[ix].values_size;
|
| | |
|
| | | //---
|
| | | CDomNodeBase* ptr = m_node[ix].values[el];
|
2026-10-08 13:38:10 -05:00 | | | if(CheckPointer(ptr) == POINTER_DYNAMIC && ptr.m_ctx == &this)
|
2026-10-05 17:54:12 -05:00 | | | delete ptr;
|
| | |
|
| | | //---
|
| | | for(int i = el; i < t; i++)
|
| | | m_node[ix].values[i] = m_node[ix].values[i + 1];
|
| | |
|
| | | //---
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | int CDomNodeManager::ReserveArr(const int initial_reserve)
|
| | | {
|
| | | //---
|
| | | if(m_node_free_s > 0)
|
| | | {
|
| | | const int idx = m_node_free[--m_node_free_s];
|
| | | return idx;
|
| | | }
|
| | |
|
| | | //---
|
| | | if(m_node_size + 1 >= m_node_r)
|
| | | {
|
| | | m_node_r <<= 1;
|
| | | ArrayResize(m_node, m_node_r, m_node_r);
|
| | | }
|
| | |
|
| | | //---
|
| | | m_node[m_node_size].values_r = ArrayResize(m_node[m_node_size].values, initial_reserve, initial_reserve);
|
| | | m_node[m_node_size++].values_size = 0; // 0 elementos
|
| | | return m_node_size - 1;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | void CDomNodeManager::FreeArr(const int ix)
|
| | | {
|
| | | //---
|
| | | //Print("--------------------");
|
| | | ClearArray(ix);
|
| | |
|
| | | //---
|
| | | if(m_node_free_s + 1 >= m_node_free_r)
|
| | | {
|
| | | m_node_free_r <<= 1;
|
| | | ArrayResize(m_node_free, m_node_free_r, m_node_free_r);
|
| | | }
|
| | | m_node_free[m_node_free_s++] = ix;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | void CDomNodeManager::ClearArray(const int ix)
|
| | | {
|
| | | //--- iteramos por todos los elementos y vamos eliminando los que son del own
|
| | | //Print("DEL START: ", m_node[ix].values_size);
|
| | | for(int i = 0; i < m_node[ix].values_size; i++)
|
| | | {
|
| | | //Print("Iteration: ", i);
|
| | | CDomNodeBase* ptr = m_node[ix].values[i];
|
| | | if(CheckPointer(ptr) == POINTER_DYNAMIC && ptr.m_ctx == &this)
|
| | | {
|
| | | // Print("Del: ", i);
|
| | | delete ptr;
|
| | | }
|
| | | }
|
| | | //Print("DEL END");
|
| | |
|
| | | //--- resize
|
| | | m_node[ix].values_size = 0; // 0 elementos
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | int CDomNodeManager::ArrCopyTo(const int ix, CDomNodeBase *&out[], int dst_start) const
|
| | | {
|
| | | //---
|
| | | const int t = m_node[ix].values_size;
|
| | | if(t < 1)
|
| | | return 0;
|
| | |
|
| | | //---
|
| | | const int n = dst_start + t;
|
| | | if(n > ArraySize(out)) // es mayor..
|
| | | {
|
| | | ArrayResize(out, n);
|
| | | }
|
| | |
|
| | | //---
|
| | | for(int i = 0; i < t; i++)
|
| | | {
|
| | | out[dst_start++] = m_node[ix].values[i];
|
| | | }
|
| | | return t;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | int CDomNodeManager::SlicingArr(const int ix, CDomNodeBase* &out[], int dst_start = 0
|
| | | , int cur = -1, int end = -1, int step = 1) const
|
| | | {
|
| | | //---
|
| | | int l = m_node[ix].values_size;
|
| | | if(l < 1)
|
| | | return 0;
|
| | |
|
| | | //---
|
| | | const int lock = dst_start;
|
| | |
|
| | | //---
|
| | | if(step > 0)
|
| | | {
|
| | | //---
|
| | | if(cur == -1)
|
| | | cur = 0;
|
| | | else
|
| | | if(cur < 0)
|
| | | {
|
| | | cur = l + cur;
|
| | | if(cur < 0)
|
| | | cur = 0;
|
| | | }
|
| | |
|
| | | //---
|
| | | if(end == -1)
|
| | | end = l;
|
| | | else
|
| | | if(end < 0)
|
| | | {
|
| | | end = l + end;
|
| | | if(end < 0)
|
| | | end = 0;
|
| | | }
|
| | |
|
| | | //---
|
| | | cur = cur < l ? cur : l;
|
| | | end = end < l ? end : l;
|
| | |
|
| | | //---
|
| | | const int n = dst_start + (end - cur);
|
| | | if(n > ArraySize(out))
|
| | | ArrayResize(out, n);
|
| | |
|
| | | //---
|
| | | while(cur < end)
|
| | | {
|
| | | out[dst_start++] = m_node[ix].values[cur];
|
| | | cur += step;
|
| | | }
|
| | | }
|
| | | else
|
| | | {
|
| | | //---
|
| | | // 2 + -3
|
| | | if(cur == -1)
|
| | | cur = l - 1;
|
| | | else
|
| | | if(cur < 0)
|
| | | {
|
| | | cur = l + cur;
|
| | | if(cur < 0)
|
| | | cur = -1;
|
| | | }
|
| | |
|
| | | //---
|
| | | if(end == -1)
|
| | | end = -1;
|
| | | else
|
| | | if(end < 0)
|
| | | {
|
| | | end = l + end;
|
| | | if(end < 0)
|
| | | end = -1;
|
| | | }
|
| | |
|
| | | //---
|
| | | l--;
|
| | | cur = cur < l ? cur : l;
|
| | | end = end < l ? end : l;
|
| | |
|
| | |
|
| | | //---
|
| | | const int n = dst_start + (cur - end);
|
| | |
|
| | | if(n > ArraySize(out))
|
| | | ArrayResize(out, n);
|
| | |
|
| | | //---
|
| | | while(cur > end)
|
| | | {
|
| | | out[dst_start++] = m_node[ix].values[cur];
|
| | | cur += step;
|
| | | }
|
| | | }
|
| | | return dst_start - lock;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename T>
|
| | | int CDomNodeManager::ToArray(const int ix, T &array[]) const
|
| | | {
|
| | | const int t = m_node[ix].values_size;
|
| | | ArrayResize(array, t);
|
| | | for(int i = 0; i < t; i++)
|
| | | {
|
| | | switch(m_node[ix].values[i].m_type)
|
| | | {
|
2026-10-08 13:38:10 -05:00 | | | case TSN_SBL_BASE_TYPE_UINT:
|
| | | {
|
| | | array[i] = (T)m_node[ix].values[i].m_v.uv;
|
| | | break;
|
| | | }
|
2026-10-05 17:54:12 -05:00 | | | case TSN_SBL_BASE_TYPE_INT:
|
| | | {
|
| | | array[i] = (T)m_node[ix].values[i].m_v.iv;
|
| | | break;
|
| | | }
|
| | | case TSN_SBL_BASE_TYPE_FLT:
|
| | | {
|
| | | array[i] = (T)m_node[ix].values[i].m_v.dv;
|
| | | break;
|
| | | }
|
| | | case TSN_SBL_BASE_TYPE_BOL:
|
| | | {
|
| | | array[i] = (T)m_node[ix].values[i].m_v.bv;
|
| | | break;
|
| | | }
|
| | | case TSN_SBL_BASE_TYPE_STR:
|
| | | {
|
| | | const int ri = m_node[ix].values[i].m_v.ix;
|
| | | array[i] = (T)m_string_stack[ri];
|
| | | break;
|
| | | }
|
| | | default:
|
| | | array[i] = (T)NULL;
|
| | | break;
|
| | | }
|
| | | }
|
| | | return t;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | #endif // BASESPARSERSLAN_SRC_DOM_DOM_DEF_MQH
|