//+------------------------------------------------------------------+ //| 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_DEF_MQH #define BASESPARSERSLAN_SRC_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 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]; if(CheckPointer(ptr) == POINTER_DYNAMIC && ptr.m_ctx == &this ) 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 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) { 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_DEF_MQH