2026-08-31 20:49:50 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| Main.mqh |
|
| | | //| Copyright 2025, Niquel Mendoza. |
|
| | | //| https://www.mql5.com/es/users/nique_372 |
|
| | | //+------------------------------------------------------------------+
|
| | | #property copyright "Copyright 2025, Niquel Mendoza."
|
| | | #property link "https://www.mql5.com/es/users/nique_372"
|
| | | #property strict
|
| | |
|
| | | #ifndef MQLARTICLES_UTILS_SETFILES_MAIN_MQH
|
| | | #define MQLARTICLES_UTILS_SETFILES_MAIN_MQH
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | #include "..\\Basic.mqh"
|
| | | #include <TSN\\GCol\\GenericHashes.mqh>
|
| | | #include <TSN\\GCol\\HashMap.mqh>
|
| | |
|
2026-09-13 08:47:52 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | namespace TSN
|
| | | {
|
2026-08-31 20:49:50 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | enum ENUM_SETFILE_LINE_TYPE
|
| | | {
|
| | | SETFILE_LINE_TYPE_NOINPUT = 1,
|
| | | SETFILE_LINE_TYPE_INPUT = 0
|
| | | };
|
| | |
|
| | | //---
|
| | | string g_setfile_dyn_arr[5];
|
| | |
|
| | | //---
|
| | | struct SetFileParam
|
| | | {
|
| | | string name;
|
| | | string value;
|
| | | string start;
|
| | | string step;
|
| | | string stop;
|
| | |
|
| | | //---
|
| | | SetFileParam()
|
| | | : value(NULL), start(NULL), step(NULL), stop(NULL)
|
| | | {
|
| | | }
|
| | |
|
| | | //---
|
| | | // si start == NULL signfiica que es invalido para optimizar
|
| | | __forceinline string Format() { return start != NULL ? StringFormat("%s=%s||%s||%s||%s||N", name, value, start, step, stop) : (name + "=" + value); }
|
| | | };
|
| | |
|
| | | //---
|
| | | struct pack(4) SetFileLine
|
| | | {
|
| | | ENUM_SETFILE_LINE_TYPE type;
|
| | | int id;
|
| | | };
|
| | |
|
2026-09-13 08:47:52 -05:00 | | |
|
2026-08-31 20:49:50 -05:00 | | | //---
|
| | | SetFileParam EMPTY_SETFILE_PARAM;
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | class CSetFile : public CLoggerBase
|
| | | {
|
| | | private:
|
| | | //---
|
2026-09-13 08:47:52 -05:00 | | | CHashMapFast(string, int) m_hashmap_params;
|
2026-08-31 20:49:50 -05:00 | | | bool m_init;
|
| | |
|
| | | //--- Lines
|
| | | SetFileLine m_lines[];
|
| | | int m_lines_size;
|
| | |
|
| | | //--- Inputs
|
| | | int m_params_size;
|
| | | SetFileParam m_params[];
|
| | |
|
| | | //--- Strings
|
| | | int m_no_params_size;
|
| | | string m_no_params[];
|
| | |
|
| | | //--- Data
|
| | | string m_expert_name;
|
| | | datetime m_saved_time;
|
| | |
|
| | | //---
|
| | | void ChangeSavedTime(const datetime new_time);
|
| | |
|
| | |
|
| | | public:
|
| | | CSetFile(void);
|
| | | ~CSetFile(void);
|
| | |
|
| | | //---
|
| | | bool Init(const string& expert_name);
|
| | | bool InitByFile(const string& file_name, int extra_file_flags, uint reserve);
|
| | | bool InitBySrc(const string& src, ushort separator, uint reserve);
|
| | |
|
| | | //---
|
| | | bool Save(const string& file_name, int extra_file_flags);
|
| | |
|
| | | //---
|
| | | void Clean();
|
| | |
|
| | | //---
|
| | | void GetAsString(string &out) const;
|
| | | int GetAsStringArray(string& out[]) const;
|
| | |
|
| | | //---
|
| | | void Summary() const;
|
| | | void Imprimir() const;
|
| | | void ImprimirLinesArray() const { ArrayPrint(m_lines, 2, "|"); }
|
| | | void ImprimirParamsArray() const { ArrayPrint(m_params, 2, "|"); }
|
| | | void ImprimirNoParamsArray() const { ArrayPrint(m_no_params, 2, "|"); }
|
| | |
|
| | | //--- Getters \Setters
|
| | | __forceinline int ParamsSize() const { return m_params_size; }
|
| | | __forceinline SetFileParam GetParam(const int idx) const { return m_params[idx]; }
|
| | | __forceinline SetFileParam GetParam(const string str) const;
|
| | | __forceinline int GetParamIdx(const string str) const;
|
| | |
|
| | |
|
| | | __forceinline int NoParamsSize() const { return m_no_params_size; }
|
| | | __forceinline string GetNoParmas(const int idx) const { return m_no_params[idx]; }
|
| | |
|
| | | __forceinline int LinesSize() const { return m_lines_size; }
|
| | | __forceinline SetFileLine GetLine(const int idx) const { return m_lines[idx]; }
|
| | |
|
| | | // Expert name
|
| | | __forceinline string ExpertName() const { return m_expert_name; }
|
| | | void ExpertName(const string& v) { m_expert_name = v; }
|
| | |
|
| | | // Saved time
|
| | | __forceinline datetime SavedTime() const { return m_saved_time; }
|
| | |
|
| | | //--- Funciones para remover un alinea (idx indice en m_lines)
|
| | | bool RemoveLine(const int idx);
|
| | |
|
| | | //--- Funciones para trabajar con los parametros
|
| | | //- Agrega un parametro (al final) (por defecto start, etc es null osea que noe s optimizable si se espeicfia los 3 valores entonces si es optimzable)
|
| | | bool AddParamLineString(const string& name, const string& value);
|
| | |
|
| | | // Number
|
| | | template <typename TInteger>
|
| | | bool AddParamLineNumber(const string& name, const TInteger value, const TInteger start, const TInteger step, const TInteger stop);
|
| | |
|
| | | // Real
|
| | | template <typename TNumber>
|
| | | bool AddParamLineReal(const string& name, const TNumber value, int8_t presicion, const TNumber start, const TNumber step, const TNumber stop);
|
| | |
|
| | | // Bool
|
| | | bool AddParamLineBool(const string& name, const bool value);
|
| | |
|
| | | // Enum
|
| | | template <typename TEnum>
|
| | | bool AddParamLineEnum(const string& name, const TEnum value, const TEnum start, const TEnum stop);
|
| | |
|
| | | // Datetime
|
| | | bool AddParamLineDatetime(const string& name, const datetime value, const datetime start, const long step_sec, const datetime stop);
|
| | |
|
| | | // Color
|
| | | bool AddParamLineColor(const string& name, const color value);
|
| | |
|
| | |
|
| | | // Idx = indice del FILE
|
| | | //- Inserta
|
| | | bool InsertParamLineString(const int idx, const string& name, const string& value);
|
| | |
|
| | | template <typename TInteger>
|
| | | bool InsertParamLineNumber(const int idx, const string& name, const TInteger value, const TInteger start, const TInteger step, const TInteger stop);
|
| | |
|
| | | template <typename TNumber>
|
| | | bool InsertParamLineReal(const int idx, const string& name, const TNumber value, int8_t presicion, const TNumber start, const TNumber step, const TNumber stop);
|
| | |
|
| | | bool InsertParamLineBool(const int idx, const string& name, const bool value);
|
| | |
|
| | | template <typename TEnum>
|
| | | bool InsertParamLineEnum(const int idx, const string& name, const TEnum value, const TEnum start, const TEnum stop);
|
| | |
|
| | | bool InsertParamLineDatetime(const int idx, const string& name, const datetime value, const datetime start, const long step_sec, const datetime stop);
|
| | |
|
| | | bool InsertParamLineColor(const int idx, const string& name, const color value);
|
| | |
|
| | |
|
| | | //- Modificar
|
| | | // Nombre de parametro
|
| | | bool ModifyParamName(const string param_name, const string& new_name);
|
| | | bool ModifyParamName(const int idx, const string& new_name);
|
| | |
|
| | | // Valor de parametro (value)
|
| | | template <typename TInteger> // Todo tipo de numero integer uinteger | datetime | color
|
| | | bool ModifyParamValueNumber(const string param_name, const TInteger v);
|
| | | template <typename TNumber> // Double float
|
| | | bool ModifyParamValueRealNumber(const string param_name, const TNumber v, int8_t presicion);
|
| | | bool ModifyParamValueBoolean(const string param_name, const bool v);
|
| | | bool ModifyParamValueString(const string param_name, const string v);
|
| | | template <typename TEnum> // Double float
|
| | | bool ModifyParamValueEnum(const string param_name, const TEnum v);
|
| | | bool ModifyParamValueDatetime(const string param_name, const datetime v);
|
| | | bool ModifyParamValueColor(const string param_name, const color v);
|
| | |
|
| | |
|
| | | // ModifyParamOptNumber
|
| | | template <typename TInteger>
|
| | | bool ModifyParamOptNumberStart(const string param_name, const TInteger start);
|
| | | template <typename TInteger>
|
| | | bool ModifyParamOptNumberStep(const string param_name, const TInteger step);
|
| | | template <typename TInteger>
|
| | | bool ModifyParamOptNumberStop(const string param_name, const TInteger stop);
|
| | |
|
| | | // ModifyParamOptRealNumber
|
| | | template <typename TNumber>
|
| | | bool ModifyParamOptRealNumberStart(const string param_name, const TNumber start, int8_t presicion);
|
| | | template <typename TNumber>
|
| | | bool ModifyParamOptRealNumberStep(const string param_name, const TNumber step, int8_t presicion);
|
| | | template <typename TNumber>
|
| | | bool ModifyParamOptRealNumberStop(const string param_name, const TNumber stop, int8_t presicion);
|
| | |
|
| | |
|
| | | // Modify opt datetime
|
| | | bool ModifyParamOptDatetimeStart(const string param_name, const datetime start);
|
| | | bool ModifyParamOptDatetimeStep(const string param_name, const long step_sec);
|
| | | bool ModifyParamOptDatetimeStop(const string param_name, const datetime stop);
|
| | |
|
| | |
|
| | | // ModifyParamOptEnum
|
| | | template <typename TEnum>
|
| | | bool ModifyParamOptEnumStart(const string param_name, const TEnum start);
|
| | | template <typename TEnum>
|
| | | bool ModifyParamOptEnumStop(const string param_name, const TEnum stop);
|
| | |
|
| | | //- Verificar exisitencia
|
2026-09-13 08:47:52 -05:00 | | | __forceinline bool ParamExist(const string& param_name) { return m_hashmap_params.ContainsKey(param_name); }
|
2026-08-31 20:49:50 -05:00 | | |
|
| | |
|
| | | //- Lectura
|
| | | string ReadParamValueString(const string param_name) const;
|
| | |
|
| | | template <typename TInteger>
|
| | | TInteger ReadParamValueInteger(const string param_name) const;
|
| | |
|
| | | template <typename TNumber>
|
| | | TNumber ReadParamValueReal(const string param_name) const;
|
| | |
|
| | | datetime ReadParamValueDatetime(const string param_name) const;
|
| | | color ReadParamValueColor(const string param_name) const;
|
| | | bool ReadParamValueBool(const string param_name) const;
|
| | |
|
| | | //--- Funciones para trabajar con no parametyros
|
| | | //- Añade al final
|
| | | void AddNoParamsLine(const string& line);
|
| | |
|
| | | // Mencionar que idx es el indice en el FILE
|
| | | //- Inserta
|
| | | void InsertNoParamLine(const int idx, const string& line);
|
| | |
|
| | | //- Modifica
|
| | | void ModifyNoParamLine(const int idx, const string& new_line);
|
| | |
|
| | | //---
|
| | | bool IsValidIdxLine(const int idx) { return idx >= 0 && idx < m_lines_size; }
|
| | |
|
| | | //---
|
2026-09-13 08:47:52 -05:00 | | | CHashMapFast(string, int)* HashMapPointer() { return &m_hashmap_params; }
|
2026-08-31 20:49:50 -05:00 | | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | CSetFile::CSetFile(void)
|
| | | {
|
| | | Clean(); // Inicilizacion
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | CSetFile::~CSetFile()
|
| | | {
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void CSetFile::Clean(void)
|
| | | {
|
| | | m_hashmap_params.Clear();
|
| | | m_lines_size = ArrayResize(m_lines, 0);
|
| | | m_params_size = ArrayResize(m_params, 0);
|
| | | m_no_params_size = ArrayResize(m_no_params, 0);
|
| | | m_expert_name = NULL;
|
| | | m_saved_time = 0;
|
| | | m_init = false;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Funciones de carga Load |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::Init(const string &expert_name)
|
| | | {
|
| | | //---
|
| | | if(m_init)
|
| | | {
|
| | | LogWarning("Limpiando dado que se inicia denuevo", FUNCION_ACTUAL);
|
| | | Clean();
|
| | | }
|
| | |
|
| | | //---
|
| | | m_expert_name = expert_name;
|
| | | m_saved_time = TimeLocal();
|
| | | m_init = true;
|
| | |
|
| | | //---
|
| | | m_no_params_size = ArrayResize(m_no_params, 4);
|
| | | m_no_params[0] = StringFormat("; saved on %s", TimeToString(m_saved_time, TIME_DATE | TIME_MINUTES | TIME_SECONDS));
|
| | | m_no_params[1] = StringFormat("; this file contains input parameters for testing/optimizing %s expert advisor", m_expert_name);
|
| | | m_no_params[2] = "; to use it in the strategy tester, click Load in the context menu of the Inputs tab";
|
| | | m_no_params[3] = ";";
|
| | |
|
| | | //---
|
| | | m_lines_size = ArrayResize(m_lines, 4);
|
| | | m_lines[0].type = SETFILE_LINE_TYPE_NOINPUT;
|
| | | m_lines[0].id = 0;
|
| | | m_lines[1].type = SETFILE_LINE_TYPE_NOINPUT;
|
| | | m_lines[1].id = 1;
|
| | | m_lines[2].type = SETFILE_LINE_TYPE_NOINPUT;
|
| | | m_lines[2].id = 2;
|
| | | m_lines[3].type = SETFILE_LINE_TYPE_NOINPUT;
|
| | | m_lines[3].id = 3;
|
| | |
|
| | | //---
|
| | | return true;
|
| | | }
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::InitBySrc(const string &src, ushort separator, uint reserve)
|
| | | {
|
| | | //---
|
| | | if(m_init)
|
| | | {
|
| | | LogWarning("Limpiando dado que se inicia denuevo", FUNCION_ACTUAL);
|
| | | Clean();
|
| | | }
|
| | |
|
| | | //---
|
| | | string arr[];
|
| | | const int size = StringSplit(src, separator, arr);
|
| | | if(size == -1)
|
| | | {
|
| | | LogError("Fallo al hacer split", FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | | //---
|
| | | int ilec = 0;
|
| | |
|
| | | //--- Reservamos para no params
|
| | | reserve = fmax(3, reserve); // Como minimo un valor de 2
|
| | | int cn = ArrayResize(m_no_params, reserve);
|
| | |
|
| | | //---
|
| | | int rl = ArrayResize(m_lines, reserve);
|
| | |
|
| | |
|
| | | //--- Extramoes el tiempo de guardado
|
| | | string line = arr[ilec++];
|
| | | int len = StringLen(line);
|
| | | int pos = 0;
|
| | | while(line[pos] < '0' || line[pos] > '9') // Solo iterar mientras el caracter pos no sea un nuemro
|
| | | {
|
| | | pos++;
|
| | | if(pos >= len)
|
| | | {
|
| | | LogError("En la primera linea debe de ubicarse un nuermo (fecha de creacion)", FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | m_saved_time = StringToTime(StringSubstr(line, pos)); // Desde el inicio del numero hasta el fin del string
|
| | |
|
| | | // Add
|
| | | m_lines[m_lines_size].type = SETFILE_LINE_TYPE_NOINPUT;
|
| | | m_lines[m_lines_size++].id = m_no_params_size;
|
| | | m_no_params[m_no_params_size++] = line;
|
| | |
|
| | | //--- Extraemos el nombre del bot
|
| | | line = arr[ilec++];
|
| | | len = StringLen(line);
|
| | | pos = 0;
|
| | |
|
| | | // Primero buscaremos /
|
| | | while(line[pos] != '/')
|
| | | {
|
| | | pos++;
|
| | | if(pos >= len)
|
| | | {
|
| | | LogError("En la segunda linea del archivo se debe de ubicar el caracter / ", FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | // Avanzamos hasta el siguiente espacio
|
| | | while(line[pos] != ' ')
|
| | | {
|
| | | pos++;
|
| | | if(pos >= len)
|
| | | {
|
| | | LogError("En la segunda linea del archivo se debe de ubicar el caracter / ", FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | pos++; // Luego del espacio (inicio del nombre del bot)
|
| | |
|
| | | // Comenzamos desde el fin hasta el 2do espacio
|
| | | int c = 2;
|
| | | int end = len - 1;
|
| | | while(c > 0)
|
| | | {
|
| | | end--;
|
| | | if(end < 0)
|
| | | {
|
| | | LogError("En la segunda linea del archivo deben de al menos haber dos espacios empezados desde atras ", FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | | if(line[end] == ' ')
|
| | | c--;
|
| | | }
|
| | |
|
| | | m_expert_name = StringSubstrRange(line, pos, end);
|
| | |
|
| | | // Add
|
| | | m_lines[m_lines_size].type = SETFILE_LINE_TYPE_NOINPUT;
|
| | | m_lines[m_lines_size++].id = m_no_params_size;
|
| | | m_no_params[m_no_params_size++] = line;
|
| | |
|
| | |
|
| | | //---
|
| | | c = ArrayResize(m_params, reserve);
|
| | |
|
| | | //--- Cargamos todos los parametros
|
| | | while(ilec < size)
|
| | | {
|
| | | line = arr[ilec++];
|
| | | if(line == NULL)
|
| | | continue;
|
| | |
|
| | | //---
|
| | | if(line[0] == ';') // Comentarios | Sinput
|
| | | {
|
| | | //---
|
| | | m_lines[m_lines_size].type = SETFILE_LINE_TYPE_NOINPUT;
|
| | | m_lines[m_lines_size++].id = m_no_params_size;
|
| | |
|
| | | //---
|
| | | m_no_params[m_no_params_size++] = line;
|
| | | if(m_no_params_size >= cn)
|
| | | {
|
| | | cn <<= 1;
|
| | | ArrayResize(m_no_params, cn);
|
| | | }
|
| | | }
|
| | | else
|
| | | {
|
| | | //---
|
| | | int vs = line.Find("=");
|
| | | if(vs == -1)
|
| | | {
|
| | | LogWarning(StringFormat("Omitiendo linea corrupta:\n'%s'", line), FUNCION_ACTUAL);
|
| | | continue;
|
| | | }
|
| | |
|
| | | //---
|
| | | m_lines[m_lines_size].type = SETFILE_LINE_TYPE_INPUT;
|
| | | m_lines[m_lines_size++].id = m_params_size;
|
| | |
|
| | | //---
|
| | | m_params[m_params_size].name = StringSubstr(line, 0, vs);
|
| | | if(!m_hashmap_params.Add(m_params[m_params_size].name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("Fallo al agregar el parametro =%s al hashmap", m_params[m_params_size].name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | | //---
|
| | | vs++;
|
| | |
|
| | | //---
|
2026-09-13 08:47:52 -05:00 | | | const int t = CStringFunc::StringSplitStr(StringSubstr(line, vs), "||", g_setfile_dyn_arr, 5);
|
2026-08-31 20:49:50 -05:00 | | | if(t < 1)
|
| | | {
|
| | | LogCriticalError("El split debe dar como minimo 1 cadena de resultado", FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | | //---
|
| | | m_params[m_params_size].value = g_setfile_dyn_arr[0];
|
| | |
|
| | | //---
|
| | | if(t == 5 && g_setfile_dyn_arr[4].Find("N") >= 0) // Optimizable
|
| | | {
|
| | | m_params[m_params_size].start = g_setfile_dyn_arr[1];
|
| | | m_params[m_params_size].step = g_setfile_dyn_arr[2];
|
| | | m_params[m_params_size].stop = g_setfile_dyn_arr[3];
|
| | | }
|
| | |
|
| | | //---
|
| | | m_params_size++;
|
| | |
|
| | | //---
|
| | | if(m_params_size >= c)
|
| | | {
|
| | | c <<= 1;
|
| | | ArrayResize(m_params, c);
|
| | | }
|
| | | }
|
| | |
|
| | | //---
|
| | | if(m_lines_size >= rl)
|
| | | {
|
| | | rl <<= 1;
|
| | | ArrayResize(m_lines, rl);
|
| | | }
|
| | | }
|
| | |
|
| | | //--- Truncamos
|
| | | ArrayResize(m_params, m_params_size);
|
| | | ArrayResize(m_no_params, m_no_params_size);
|
| | | ArrayResize(m_lines, m_lines_size);
|
| | |
|
| | | //---
|
| | | m_init = true;
|
| | |
|
| | | //--- Exito
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::InitByFile(const string &file_name, int extra_file_flags, uint reserve)
|
| | | {
|
| | | //---
|
| | | if(m_init)
|
| | | {
|
| | | LogWarning("Limpiando dado que se inicia denuevo", FUNCION_ACTUAL);
|
| | | Clean();
|
| | | }
|
| | |
|
| | | //---
|
| | | ResetLastError();
|
| | | const int fh = FileOpen(file_name, FILE_READ | FILE_TXT | extra_file_flags);
|
| | | if(fh == INVALID_HANDLE)
|
| | | {
|
| | | LogError(StringFormat("Fallo al abrir el archivo '%s', ultimo error = %d", file_name, GetLastError()), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | |
|
| | | //--- Reservamos para no params
|
| | | reserve = fmax(3, reserve); // Como minimo un valor de 2
|
| | | int cn = ArrayResize(m_no_params, reserve);
|
| | |
|
| | | //---
|
| | | int rl = ArrayResize(m_lines, reserve);
|
| | |
|
| | |
|
| | | //--- Extramoes el tiempo de guardado
|
| | | string line = FileReadString(fh);
|
| | | int len = StringLen(line);
|
| | | int pos = 0;
|
| | | while(line[pos] < '0' || line[pos] > '9') // Solo iterar mientras el caracter pos no sea un nuemro
|
| | | {
|
| | | pos++;
|
| | | if(pos >= len)
|
| | | {
|
| | | LogError("En la primera linea debe de ubicarse un nuermo (fecha de creacion)", FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | m_saved_time = StringToTime(StringSubstr(line, pos)); // Desde el inicio del numero hasta el fin del string
|
| | |
|
| | | // Add
|
| | | m_lines[m_lines_size].type = SETFILE_LINE_TYPE_NOINPUT;
|
| | | m_lines[m_lines_size++].id = m_no_params_size;
|
| | | m_no_params[m_no_params_size++] = line;
|
| | |
|
| | | //--- Extraemos el nombre del bot
|
| | | line = FileReadString(fh);
|
| | | len = StringLen(line);
|
| | | pos = 0;
|
| | |
|
| | | // Primero buscaremos /
|
| | | while(line[pos] != '/')
|
| | | {
|
| | | pos++;
|
| | | if(pos >= len)
|
| | | {
|
| | | LogError("En la segunda linea del archivo se debe de ubicar el caracter / ", FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | // Avanzamos hasta el siguiente espacio
|
| | | while(line[pos] != ' ')
|
| | | {
|
| | | pos++;
|
| | | if(pos >= len)
|
| | | {
|
| | | LogError("En la segunda linea del archivo se debe de ubicar el caracter / ", FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | pos++; // Luego del espacio (inicio del nombre del bot)
|
| | |
|
| | | // Comenzamos desde el fin hasta el 2do espacio
|
| | | int c = 2;
|
| | | int end = len - 1;
|
| | | while(c > 0)
|
| | | {
|
| | | end--;
|
| | | if(end < 0)
|
| | | {
|
| | | LogError("En la segunda linea del archivo deben de al menos haber dos espacios empezados desde atras ", FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | | if(line[end] == ' ')
|
| | | c--;
|
| | | }
|
| | |
|
| | | m_expert_name = StringSubstrRange(line, pos, end);
|
| | |
|
| | | // Add
|
| | | m_lines[m_lines_size].type = SETFILE_LINE_TYPE_NOINPUT;
|
| | | m_lines[m_lines_size++].id = m_no_params_size;
|
| | | m_no_params[m_no_params_size++] = line;
|
| | |
|
| | |
|
| | | //---
|
| | | c = ArrayResize(m_params, reserve);
|
| | |
|
| | | //--- Cargamos todos los parametros
|
| | | while(!FileIsEnding(fh))
|
| | | {
|
| | | line = FileReadString(fh);
|
| | | if(line == NULL)
|
| | | continue;
|
| | |
|
| | | //---
|
| | | if(line[0] == ';') // Comentarios | Sinput
|
| | | {
|
| | | //---
|
| | | m_lines[m_lines_size].type = SETFILE_LINE_TYPE_NOINPUT;
|
| | | m_lines[m_lines_size++].id = m_no_params_size;
|
| | |
|
| | | //---
|
| | | m_no_params[m_no_params_size++] = line;
|
| | | if(m_no_params_size >= cn)
|
| | | {
|
| | | cn <<= 1;
|
| | | ArrayResize(m_no_params, cn);
|
| | | }
|
| | | }
|
| | | else
|
| | | {
|
| | | //---
|
| | | int vs = line.Find("=");
|
| | | if(vs == -1)
|
| | | {
|
| | | LogWarning(StringFormat("Omitiendo linea corrupta:\n'%s'", line), FUNCION_ACTUAL);
|
| | | continue;
|
| | | }
|
| | |
|
| | |
|
| | | //---
|
| | | m_lines[m_lines_size].type = SETFILE_LINE_TYPE_INPUT;
|
| | | m_lines[m_lines_size++].id = m_params_size;
|
| | |
|
| | | //---
|
| | | m_params[m_params_size].name = StringSubstr(line, 0, vs);
|
| | | if(!m_hashmap_params.Add(m_params[m_params_size].name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("Fallo al agregar el parametro =%s al hashmap", m_params[m_params_size].name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | | //---
|
| | | vs++;
|
| | |
|
| | | //---
|
2026-09-13 08:47:52 -05:00 | | | const int t = CStringFunc::StringSplitStr(StringSubstr(line, vs), "||", g_setfile_dyn_arr, 5);
|
2026-08-31 20:49:50 -05:00 | | | if(t < 1)
|
| | | {
|
| | | LogCriticalError("El split debe dar como minimo 1 cadena de resultado", FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | | //---
|
| | | m_params[m_params_size].value = g_setfile_dyn_arr[0];
|
| | |
|
| | | //---
|
| | | if(t == 5 && g_setfile_dyn_arr[4].Find("N") >= 0) // Optimizable
|
| | | {
|
| | | m_params[m_params_size].start = g_setfile_dyn_arr[1];
|
| | | m_params[m_params_size].step = g_setfile_dyn_arr[2];
|
| | | m_params[m_params_size].stop = g_setfile_dyn_arr[3];
|
| | | }
|
| | |
|
| | | //---
|
| | | m_params_size++;
|
| | |
|
| | | //---
|
| | | if(m_params_size >= c)
|
| | | {
|
| | | c <<= 1;
|
| | | ArrayResize(m_params, c);
|
| | | }
|
| | | }
|
| | |
|
| | | //---
|
| | | if(m_lines_size >= rl)
|
| | | {
|
| | | rl <<= 1;
|
| | | ArrayResize(m_lines, rl);
|
| | | }
|
| | | }
|
| | |
|
| | | //--- Truncamos
|
| | | ArrayResize(m_params, m_params_size);
|
| | | ArrayResize(m_no_params, m_no_params_size);
|
| | | ArrayResize(m_lines, m_lines_size);
|
| | |
|
| | | //--- Cerramos
|
| | | FileClose(fh);
|
| | |
|
| | | //---
|
| | | m_init = true;
|
| | |
|
| | | //--- Exito
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::Save(const string &file_name, int extra_file_flags)
|
| | | {
|
| | | //---
|
| | | ResetLastError();
|
| | | const int fh = FileOpen(file_name, FILE_WRITE | FILE_TXT | extra_file_flags);
|
| | | if(fh == INVALID_HANDLE)
|
| | | {
|
| | | LogError(StringFormat("Fallo al abrir el archivo = %s, ultimo error = %d", file_name, GetLastError()), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | | //---
|
| | | ChangeSavedTime(TimeLocal());
|
| | |
|
| | | //---
|
| | | for(int i = 0; i < m_lines_size; i++)
|
| | | {
|
| | | if(m_lines[i].type == SETFILE_LINE_TYPE_INPUT)
|
| | | {
|
| | | FileWrite(fh, m_params[m_lines[i].id].Format());
|
| | | }
|
| | | else
|
| | | {
|
| | | FileWrite(fh, m_no_params[m_lines[i].id]);
|
| | | }
|
| | | }
|
| | |
|
| | | //---
|
| | | FileClose(fh);
|
| | |
|
| | | //---
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void CSetFile::GetAsString(string &out) const
|
| | | {
|
| | | //ArrayPrint(m_lines);
|
| | | for(int i = 0; i < m_lines_size; i++)
|
| | | {
|
| | | if(m_lines[i].type == SETFILE_LINE_TYPE_INPUT)
|
| | | {
|
| | | //Print(m_lines[i].id);
|
| | | out += m_params[m_lines[i].id].Format() + "\n";
|
| | | }
|
| | | else
|
| | | {
|
| | | out += m_no_params[m_lines[i].id] + "\n";
|
| | | }
|
| | | }
|
| | | if(m_lines_size > 0)
|
| | | out.Truncate(out.Length() - 1);
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | int CSetFile::GetAsStringArray(string &out[]) const
|
| | | {
|
| | | int s = ArrayResize(out, m_lines_size);
|
| | | for(int i = 0; i < m_lines_size; i++)
|
| | | {
|
| | | if(m_lines[i].type == SETFILE_LINE_TYPE_INPUT)
|
| | | {
|
| | | out[i] = m_params[m_lines[i].id].Format();
|
| | | }
|
| | | else
|
| | | {
|
| | | out[i] = m_no_params[m_lines[i].id];
|
| | | }
|
| | | }
|
| | | return s;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void CSetFile::Summary(void) const
|
| | | {
|
| | | Print("---- Expert name: ", m_expert_name);
|
| | | Print(" Saved time: ", m_saved_time);
|
| | | Print(" Total lines: ", m_lines_size);
|
| | | Print(" Total params: ", m_params_size);
|
| | | Print(" Total no params: ", m_no_params_size);
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | void CSetFile::Imprimir(void) const
|
| | | {
|
| | | string str = "";
|
| | | GetAsString(str);
|
| | | Print(str);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | __forceinline SetFileParam CSetFile::GetParam(const string str) const
|
| | | {
|
| | | //---
|
| | | static int real_idx;
|
| | | ((CSetFile*)&this).m_hashmap_params.TryGet(str, real_idx);
|
| | | return m_params[real_idx]; // Sin comprobacion en caso de error INVALID
|
| | | // La idea es que si el parametro es invalido (no existe) y se llame a esta funcion entonces de error
|
| | | // En caso de las demas funcoines se retonan un bool (por algo) para saber si se modifico o no
|
| | | // En cambio aqui retonamos directamente un valor
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | __forceinline int CSetFile::GetParamIdx(const string str) const
|
| | | {
|
| | | //---
|
| | | int real_idx = INVALID_INDEX;
|
| | | ((CSetFile*)&this).m_hashmap_params.TryGet(str, real_idx);
|
| | | return real_idx;
|
| | | }
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Modificar el nombre del parametro |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::ModifyParamName(const int idx, const string &new_name)
|
| | | {
|
| | | //---
|
| | | const int real_idx = m_lines[idx].id;
|
| | |
|
| | | //---
|
| | | if(!m_hashmap_params.Remove(m_params[real_idx].name))
|
| | | {
|
| | | LogError(StringFormat("No se pudo remover del hashmap, param name = %s", m_params[real_idx].name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | | //---
|
| | | m_params[real_idx].name = new_name;
|
| | |
|
| | | //---
|
| | | if(m_hashmap_params.Add(new_name, real_idx))
|
| | | {
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("No se pudo agregatr el parametro con nombre = %s, al hashamp", new_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::ModifyParamName(const string param_name, const string &new_name)
|
| | | {
|
| | | //---
|
| | | static int real_idx;
|
| | |
|
| | | //---
|
| | | if(!m_hashmap_params.TryGet(param_name, real_idx))
|
| | | {
|
| | | LogError(StringFormat("El parametro = %s, no existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | | //---
|
| | | if(!m_hashmap_params.Remove(m_params[real_idx].name))
|
| | | {
|
| | | LogError(StringFormat("No se pudo remover del hashmap, param name = %s", m_params[real_idx].name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | | //---
|
| | | m_params[real_idx].name = new_name;
|
| | |
|
| | | //---
|
| | | if(m_hashmap_params.Add(new_name, real_idx))
|
| | | {
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("No se pudo agregatr el parametro con nombre = %s, al hashamp", new_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Modify value |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TInteger>
|
| | | bool CSetFile::ModifyParamValueNumber(const string param_name, const TInteger v)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].value = string(v);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TNumber>
|
| | | bool CSetFile::ModifyParamValueRealNumber(const string param_name, const TNumber v, int8_t presicion)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].value = DoubleToString(v, presicion);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::ModifyParamValueBoolean(const string param_name, const bool v)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].value = v ? "true" : "false";
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::ModifyParamValueString(const string param_name, const string v)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].value = v;
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TEnum>
|
| | | bool CSetFile::ModifyParamValueEnum(const string param_name, const TEnum v)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].value = string((int)v);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::ModifyParamValueDatetime(const string param_name, const datetime v)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].value = string(long(v));
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::ModifyParamValueColor(const string param_name, const color v)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].value = string((int)v);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Modify datetime |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::ModifyParamOptDatetimeStart(const string param_name, const datetime start)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].start = string(long(start));
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::ModifyParamOptDatetimeStep(const string param_name, const long step_sec)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].step = string(step_sec);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::ModifyParamOptDatetimeStop(const string param_name, const datetime stop)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].stop = string(long(stop));
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Modificar Number Opt |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TInteger>
|
| | | bool CSetFile::ModifyParamOptNumberStart(const string param_name, const TInteger start)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].start = string(start);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TInteger>
|
| | | bool CSetFile::ModifyParamOptNumberStep(const string param_name, const TInteger step)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].step = string(step);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TInteger>
|
| | | bool CSetFile::ModifyParamOptNumberStop(const string param_name, const TInteger stop)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].stop = string(stop);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Modificar Real Number Opt |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TNumber>
|
| | | bool CSetFile::ModifyParamOptRealNumberStart(const string param_name, const TNumber start, int8_t presicion)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].start = DoubleToString(start, presicion);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TNumber>
|
| | | bool CSetFile::ModifyParamOptRealNumberStep(const string param_name, const TNumber step, int8_t presicion)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].step = DoubleToString(step, presicion);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TNumber>
|
| | | bool CSetFile::ModifyParamOptRealNumberStop(const string param_name, const TNumber stop, int8_t presicion)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].stop = DoubleToString(stop, presicion);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Enum |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TEnum>
|
| | | bool CSetFile::ModifyParamOptEnumStart(const string param_name, const TEnum start)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].start = string((int)start);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TEnum>
|
| | | bool CSetFile::ModifyParamOptEnumStop(const string param_name, const TEnum stop)
|
| | | {
|
| | | static int idx;
|
| | | if(m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | m_params[idx].stop = string((int)stop);
|
| | | return true;
|
| | | }
|
| | | else
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Funcion general para remover una linea |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::RemoveLine(const int idx)
|
| | | {
|
| | | //---
|
| | | const int ri = m_lines[idx].id;
|
| | | const ENUM_SETFILE_LINE_TYPE type = m_lines[idx].type;
|
| | | for(int i = idx; i < m_lines_size - 1; i++)
|
| | | {
|
| | | m_lines[i] = m_lines[i + 1];
|
| | | }
|
| | | ArrayResize(m_lines, (--m_lines_size));
|
| | | //---
|
| | | /*
|
| | | S = Parametro REAl Pararm (params)
|
| | | N = No paramero (no_params)
|
| | | LTYPE= Tipo de linea, como valores toma 2 = [S, N]
|
| | |
|
| | | # Ejemplo de array
|
| | | m_lines m_params m_no_params
|
| | | LTYPE PARAMIDX NOPARAMIDX
|
| | | S 0 -
|
| | | S 1 -
|
| | | S 2 -
|
| | | S 3 -
|
| | | S 4 -
|
| | |
|
| | | # Eliminamos linea 0
|
| | | m_lines m_params m_no_params
|
| | | LTYPE PARAMIDX NOPARAMIDX
|
| | | S 1 -
|
| | | S 2 -
|
| | | S 3 -
|
| | | S 4 -
|
| | |
|
| | | # Aqui habria que reducir paramidx en los restantes?¿
|
| | | Ahora mismo pasaria esto:
|
| | | Hariamos un swap entre elemtno eliminamo y utlimo
|
| | | asi que se camiba de posicon 4->0
|
| | | asi que el indice sero apunta al 4
|
| | |
|
| | | m_lines m_params m_no_params
|
| | | LTYPE PARAMIDX NOPARAMIDX
|
| | | S 1 -
|
| | | S 2 -
|
| | | S 3 -
|
| | | S 0 -
|
| | |
|
| | | # Vale enotnces deberimaos de ubicar y reponde "Donde se ubica el linea con real index = last" ?
|
| | | # Una vez tengamos su indice poor ejemplo en nuestro ejemplo seria el indice 4 entonces modificamos m_lines[4].id = ri
|
| | | */
|
| | |
|
| | | //---
|
| | | if(type == SETFILE_LINE_TYPE_INPUT)
|
| | | {
|
| | | //---
|
| | | if(!m_hashmap_params.Remove(m_params[ri].name))
|
| | | {
|
| | | LogError(StringFormat("Fallo al eliminar el parametro '%s' del hashmap", m_params[ri].name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | |
|
| | | //---
|
| | | const int last = (--m_params_size);
|
| | | if(ri != last) // Solo si no es igual no es 0 como minimo hayt 1 elemneo
|
| | | {
|
| | | m_params[ri] = m_params[last];
|
| | |
|
| | | if(!m_hashmap_params.TrySet(m_params[ri].name, ri))
|
| | | {
|
| | | LogError(StringFormat("Error al modificar el valor de %s a idx = %d", m_params[ri].name, ri), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
|
| | | //---
|
| | | // Ahora su RI de ester parametro cambia ya no apunta a
|
| | | for(int i = 0; i < m_lines_size; i++)
|
| | | {
|
| | | if(m_lines[i].type == SETFILE_LINE_TYPE_INPUT && m_lines[i].id == last) //
|
| | | {
|
| | | m_lines[i].id = ri;
|
| | | break;
|
| | | }
|
| | | }
|
| | |
|
| | | //---
|
| | | ArrayResize(m_params, m_params_size);
|
| | | }
|
| | | else
|
| | | {
|
| | | int last = --m_no_params_size;
|
| | | if(ri != last)
|
| | | {
|
| | | m_no_params[ri] = m_no_params[last];
|
| | | for(int i = 0; i < m_lines_size; i++) // Redirigir la linea que apuntaba a last
|
| | | {
|
| | | if(m_lines[i].type == SETFILE_LINE_TYPE_NOINPUT && m_lines[i].id == last)
|
| | | {
|
| | | m_lines[i].id = ri;
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | | ArrayResize(m_no_params, m_no_params_size);
|
| | | }
|
| | |
|
| | | //---
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Funciones para trabnajar con lineas no param |
|
| | | //+------------------------------------------------------------------+
|
| | | void CSetFile::AddNoParamsLine(const string &line)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | m_lines[m_lines_size].id = m_no_params_size;
|
| | | m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_NOINPUT;
|
| | | ArrayResize(m_no_params, m_no_params_size + 1);
|
| | | m_no_params[m_no_params_size++] = line;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | void CSetFile::InsertNoParamLine(const int idx, const string &line)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | for(int i = m_lines_size; i > idx; i--)
|
| | | m_lines[i] = m_lines[i - 1];
|
| | | m_lines[idx].type = SETFILE_LINE_TYPE_NOINPUT;
|
| | | m_lines[idx].id = m_no_params_size;
|
| | | m_lines_size++;
|
| | |
|
| | | ArrayResize(m_no_params, m_no_params_size + 1);
|
| | | m_no_params[m_no_params_size++] = line;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | void CSetFile::ModifyNoParamLine(const int idx, const string &new_line)
|
| | | {
|
| | | // NO hay check de idx
|
| | | m_no_params[m_lines[idx].id] = new_line;
|
| | | }
|
| | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Añadir parametros al final |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::AddParamLineString(const string &name, const string &value)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | m_lines[m_lines_size].id = m_params_size;
|
| | | m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size++].value = value;
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TInteger>
|
| | | bool CSetFile::AddParamLineNumber(const string &name, const TInteger value, const TInteger start, const TInteger step, const TInteger stop)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | m_lines[m_lines_size].id = m_params_size;
|
| | | m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size].value = string(value);
|
| | | m_params[m_params_size].start = string(start);
|
| | | m_params[m_params_size].step = string(step);
|
| | | m_params[m_params_size++].stop = string(stop);
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TNumber>
|
| | | bool CSetFile::AddParamLineReal(const string &name, const TNumber value, int8_t presicion, const TNumber start, const TNumber step, const TNumber stop)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | m_lines[m_lines_size].id = m_params_size;
|
| | | m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size].value = DoubleToString(value, presicion);
|
| | | m_params[m_params_size].start = DoubleToString(start, presicion);
|
| | | m_params[m_params_size].step = DoubleToString(step, presicion);
|
| | | m_params[m_params_size++].stop = DoubleToString(stop, presicion);
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::AddParamLineBool(const string &name, const bool value)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | m_lines[m_lines_size].id = m_params_size;
|
| | | m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size].value = value ? "true" : "false";
|
| | | m_params[m_params_size].start = "false";
|
| | | m_params[m_params_size].step = "0";
|
| | | m_params[m_params_size++].stop = "true";
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TEnum>
|
| | | bool CSetFile::AddParamLineEnum(const string &name, const TEnum value, const TEnum start, const TEnum stop)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | m_lines[m_lines_size].id = m_params_size;
|
| | | m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size].value = string((int)value);
|
| | | m_params[m_params_size].start = string((int)start);
|
| | | m_params[m_params_size].step = "0";
|
| | | m_params[m_params_size++].stop = string((int)stop);
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::AddParamLineDatetime(const string &name, const datetime value, const datetime start, const long step_sec, const datetime stop)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | m_lines[m_lines_size].id = m_params_size;
|
| | | m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size].value = string(long(value));
|
| | | m_params[m_params_size].start = string(long(start));
|
| | | m_params[m_params_size].step = string(step_sec);
|
| | | m_params[m_params_size++].stop = string(long(stop));
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::AddParamLineColor(const string &name, const color value)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | m_lines[m_lines_size].id = m_params_size;
|
| | | m_lines[m_lines_size++].type = SETFILE_LINE_TYPE_INPUT;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size++].value = string((int)value);
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::InsertParamLineString(const int idx, const string &name, const string &value)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | for(int i = m_lines_size; i > idx; i--)
|
| | | m_lines[i] = m_lines[i - 1];
|
| | | m_lines[idx].id = m_params_size;
|
| | | m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
|
| | | m_lines_size++;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size++].value = value;
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TInteger>
|
| | | bool CSetFile::InsertParamLineNumber(const int idx, const string &name, const TInteger value, const TInteger start, const TInteger step, const TInteger stop)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | for(int i = m_lines_size; i > idx; i--)
|
| | | m_lines[i] = m_lines[i - 1];
|
| | | m_lines[idx].id = m_params_size;
|
| | | m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
|
| | | m_lines_size++;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size].value = string(value);
|
| | | m_params[m_params_size].start = string(start);
|
| | | m_params[m_params_size].step = string(step);
|
| | | m_params[m_params_size++].stop = string(stop);
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TNumber>
|
| | | bool CSetFile::InsertParamLineReal(const int idx, const string &name, const TNumber value, int8_t presicion, const TNumber start, const TNumber step, const TNumber stop)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | for(int i = m_lines_size; i > idx; i--)
|
| | | m_lines[i] = m_lines[i - 1];
|
| | | m_lines[idx].id = m_params_size;
|
| | | m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
|
| | | m_lines_size++;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size].value = DoubleToString(value, presicion);
|
| | | m_params[m_params_size].start = DoubleToString(start, presicion);
|
| | | m_params[m_params_size].step = DoubleToString(step, presicion);
|
| | | m_params[m_params_size++].stop = DoubleToString(stop, presicion);
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::InsertParamLineBool(const int idx, const string &name, const bool value)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | for(int i = m_lines_size; i > idx; i--)
|
| | | m_lines[i] = m_lines[i - 1];
|
| | | m_lines[idx].id = m_params_size;
|
| | | m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
|
| | | m_lines_size++;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size].value = value ? "true" : "false";
|
| | | m_params[m_params_size].start = "false";
|
| | | m_params[m_params_size].step = "0";
|
| | | m_params[m_params_size++].stop = "true";
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TEnum>
|
| | | bool CSetFile::InsertParamLineEnum(const int idx, const string &name, const TEnum value, const TEnum start, const TEnum stop)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | for(int i = m_lines_size; i > idx; i--)
|
| | | m_lines[i] = m_lines[i - 1];
|
| | | m_lines[idx].id = m_params_size;
|
| | | m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
|
| | | m_lines_size++;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size].value = string((int)value);
|
| | | m_params[m_params_size].start = string((int)start);
|
| | | m_params[m_params_size].step = "0";
|
| | | m_params[m_params_size++].stop = string((int)stop);
|
| | | return true;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::InsertParamLineDatetime(const int idx, const string &name, const datetime value, const datetime start, const long step_sec, const datetime stop)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | for(int i = m_lines_size; i > idx; i--)
|
| | | m_lines[i] = m_lines[i - 1];
|
| | | m_lines[idx].id = m_params_size;
|
| | | m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
|
| | | m_lines_size++;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size].value = string(long(value));
|
| | | m_params[m_params_size].start = string(long(start));
|
| | | m_params[m_params_size].step = string(step_sec);
|
| | | m_params[m_params_size++].stop = string(long(stop));
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::InsertParamLineColor(const int idx, const string &name, const color value)
|
| | | {
|
| | | ArrayResize(m_lines, m_lines_size + 1);
|
| | | for(int i = m_lines_size; i > idx; i--)
|
| | | m_lines[i] = m_lines[i - 1];
|
| | | m_lines[idx].id = m_params_size;
|
| | | m_lines[idx].type = SETFILE_LINE_TYPE_INPUT;
|
| | | m_lines_size++;
|
| | | if(!m_hashmap_params.Add(name, m_params_size))
|
| | | {
|
| | | LogError(StringFormat("No se puede agregar el parametro con el nombre = %s", name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | ArrayResize(m_params, m_params_size + 1);
|
| | | m_params[m_params_size].name = name;
|
| | | m_params[m_params_size++].value = string((int)value);
|
| | | return true;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Read value |
|
| | | //+------------------------------------------------------------------+
|
| | | string CSetFile::ReadParamValueString(const string param_name) const
|
| | | {
|
| | | static int idx;
|
| | | if(!((CSetFile*)&this).m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return NULL;
|
| | | }
|
| | | return m_params[idx].value;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TInteger>
|
| | | TInteger CSetFile::ReadParamValueInteger(const string param_name) const
|
| | | {
|
| | | static int idx;
|
| | | if(!((CSetFile*)&this).m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return (TInteger)0;
|
| | | }
|
| | | return TInteger(m_params[idx].value);
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename TNumber>
|
| | | TNumber CSetFile::ReadParamValueReal(const string param_name) const
|
| | | {
|
| | | static int idx;
|
| | | if(!((CSetFile*)&this).m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return (TNumber)0.0;
|
| | | }
|
| | | return TNumber(m_params[idx].value);
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | datetime CSetFile::ReadParamValueDatetime(const string param_name) const
|
| | | {
|
| | | static int idx;
|
| | | if(!((CSetFile*)&this).m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return 0;
|
| | | }
|
| | | return datetime(long(m_params[idx].value));
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | color CSetFile::ReadParamValueColor(const string param_name) const
|
| | | {
|
| | | static int idx;
|
| | | if(!((CSetFile*)&this).m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return clrNONE;
|
| | | }
|
| | | return color(int(m_params[idx].value));
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | bool CSetFile::ReadParamValueBool(const string param_name) const
|
| | | {
|
| | | static int idx;
|
| | | if(!((CSetFile*)&this).m_hashmap_params.TryGet(param_name, idx))
|
| | | {
|
| | | LogError(StringFormat("El parametro '%s' No existe", param_name), FUNCION_ACTUAL);
|
| | | return false;
|
| | | }
|
| | | return m_params[idx].value == "true";
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | void CSetFile::ChangeSavedTime(const datetime new_time)
|
| | | {
|
| | | if(m_lines_size < 1)
|
| | | {
|
| | | LogCriticalError("SetFile vacio", FUNCION_ACTUAL);
|
| | | return;
|
| | | }
|
| | |
|
| | | //---
|
| | | const int ri = m_lines[0].id;
|
| | |
|
| | | //---
|
| | | int len = StringLen(m_no_params[ri]);
|
| | | int pos = 0;
|
| | | while(m_no_params[ri][pos] < '0' || m_no_params[ri][pos] > '9') // Solo iterar mientras el caracter pos no sea un nuemro
|
| | | {
|
| | | pos++;
|
| | | if(pos >= len)
|
| | | {
|
| | | LogError("En la primera linea debe de ubicarse un nuermo (fecha de creacion)", FUNCION_ACTUAL);
|
| | | return;
|
| | | }
|
| | | }
|
| | | // Truincamos el nombre del string hasta el pos (la idea es eliminar el time)
|
| | | m_no_params[ri].Truncate(pos);
|
| | | m_no_params[ri] += TimeToString(new_time, TIME_MINUTES | TIME_DATE | TIME_SECONDS);
|
| | | }
|
2026-09-13 08:47:52 -05:00 | | | }
|
2026-08-31 20:49:50 -05:00 | | | //+------------------------------------------------------------------+
|
| | | #endif // MQLARTICLES_UTILS_SETFILES_MAIN_MQH
|