WorkflowsByLeo/Src/Core/Def.mqh

325 lines
11 KiB
MQL5

//+------------------------------------------------------------------+
//| Def.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 WORKFLOWSBYLEO_SRC_CORE_DEF_MQH
#define WORKFLOWSBYLEO_SRC_CORE_DEF_MQH
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include <TSN\\MQLArticles\\Utils\\Basic.mqh>
#include <TSN\\MQLArticles\\Utils\\Dict.mqh>
#include <TSN\\YAML\\Yaml.mqh>
//+------------------------------------------------------------------+
//| Callback |
//+------------------------------------------------------------------+
#define WORKFLOWBYLEO_CALLBACK_ON_START (1)
#define WORKFLOWBYLEO_CALLBACK_ON_STEP (2)
#define WORKFLOWBYLEO_CALLBACK_ON_END (4)
#define WORKFLOWBYLEO_CALLBACK_ALL_FLAGS (WORKFLOWBYLEO_CALLBACK_ON_START|WORKFLOWBYLEO_CALLBACK_ON_STEP|WORKFLOWBYLEO_CALLBACK_ON_END)
//---
//#define WORKFLOW_CALLBACK_PADRE CLoggerBase
//---
#ifdef WORKFLOW_CALLBACK_PADRE
class IWorkflowCallback : public WORKFLOW_CALLBACK_PADRE
#else
class IWorkflowCallback
#endif // WORKFLOW_CALLBACK_PADRE
{
public:
virtual inline uint8_t FlagsCall() const = 0;
virtual bool OnWorkflowStart() { return true; }
virtual void OnWorkflowEnd(int code, int step_index) {} // en caso de exito contendra el ultimo paso de lo contraio el pase fallido
virtual void OnWorkflowStep(int code, int step_index) {}
};
//+------------------------------------------------------------------+
//| Clase base de workflow |
//+------------------------------------------------------------------+
// Declaracion previa
class CWorkflowStep;
//---
class CWorkflow : public CSpecializedManager
{
private:
//---
CYmlParser m_yml;
bool m_initialized;
string m_name;
bool m_is_running;
//--- Hashamp
// Aqui se ubicaran las variables de entorno \ secreots
CDict m_hash_str_val_to_str;
// Vairables extra
CDict m_hash_str_to_val_env;
//---
CWorkflowStep* m_steps[];
int m_steps_size;
int m_step_curr_pos;
//---
IWorkflowCallback* m_call_on_step[];
int m_call_on_step_size;
IWorkflowCallback* m_call_on_start[];
int m_call_on_start_size;
IWorkflowCallback* m_call_on_end[];
int m_call_on_end_size;
//---
bool Procesar();
//---
// p = curr pos
void OnEnd(const int p, const int res);
public:
CWorkflow(void);
~CWorkflow(void);
//--- Init
bool Init(const string& yml);
bool Init(const string& file_name, bool comon_flag); // solo utf16 le
//--- Callbacks
__forceinline int CallBackOnStartSize() const { return m_call_on_start_size; }
__forceinline int CallBackOnEndSize() const { return m_call_on_end_size; }
__forceinline int CallBackOnStepSize() const { return m_call_on_step_size; }
void AddCallBack(IWorkflowCallback* callback);
//--- Run
int First();
void _RecibedEvent(const int res, bool flag = false);
//---
__forceinline void ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam);
__forceinline void TimerEvent();
//--- Initilized
__forceinline bool IsInitialized() const { return m_initialized; }
__forceinline int StepCount() const { return m_steps_size; }
__forceinline string Name() const { return m_name; }
__forceinline bool IsRuning() const { return m_is_running; }
__forceinline int CurrentStepIndex() const { return m_step_curr_pos; }
//--- Get pointers
CYmlParser* YmlParser() { return &m_yml; }
CWorkflowStep* GetStep(const int index) { return m_steps[index]; }
CDict* Variables() { return &m_hash_str_val_to_str; }
CDict* Env() { return &m_hash_str_to_val_env; }
//--- Translate
// node ya debe de ser el valor objetivo.. no key ni nada...
template <typename TNumber>
TNumber TranslateNumber(const CYmlNode& val, const string& def);
bool TranslateBool(const CYmlNode& val, const string& def);
string TranslateStr(const CYmlNode& val, const string& def);
template <typename TEnum> // Mencionar que el enum que se desea registar debe de estar regisrado en ENUM REG
TEnum TranslateEnum(const CYmlNode& val, const string& def);
// Assing
bool AssingMqlParam(MqlParam& param, CYmlNode& node, ENUM_DATATYPE force_type);
bool AssingMqlParam(MqlParam& param, CYmlNode& node, const string stype);
//--- Enviroment
__forceinline string EnvStr(const string& key);
__forceinline bool EnvBool(const string& key);
template<typename TNumber>
__forceinline TNumber EnvNumber(const string& key);
template<typename TPtr>
__forceinline TPtr* EnvPtr(const string& key);
};
//+------------------------------------------------------------------+
//| Step |
//+------------------------------------------------------------------+
#define WORKFLOWBYLEO_STEP_FLAG_ON_CHART_EVENT (1)
#define WORKFLOWBYLEO_STEP_FLAG_ON_TIMER_EVENT (2)
//---
class CWorkflowStep : public CLoggerBase
{
private:
int m_allowed_res[];
bool m_allowd_any;
protected:
const string m_name;
const string m_namespace;
CWorkflow* m_wf;
public:
CWorkflowStep(const string& name, const string& _namespace, bool async, uint8_t async_f)
: m_name(name), m_namespace(_namespace), m_async_flags(async_f), m_async(async), m_wf(NULL) {}
~CWorkflowStep(void) {}
//---
const bool m_async;
const uint8_t m_async_flags;
//---
void MainPointer(CWorkflow* wf) { m_wf = wf; }
CWorkflow* MainPointer() { return m_wf; }
//---
virtual bool Init(const CYmlNode& parameters) = 0;
//---
__forceinline string Name() const { return m_name; }
__forceinline string Namespace() const { return m_namespace; }
//---
virtual int Run() = 0;
//---
virtual void ChartEvent(const int32_t id, const long& lparam, const double& dparam, const string& sparam) {}
virtual void OnTimerEvent() {}
//---
__forceinline bool IsPassed(const int res) { return m_allowd_any || ArrayFindValue(m_allowed_res, res) >= 0; }
void ParseIndexes(CYmlNode& arr);
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CWorkflowStep::ParseIndexes(CYmlNode &arr)
{
//---
//Print((arr.IsValid()) , " | " , arr.Size());
//---
ArrayResize(m_allowed_res, 0);
m_allowd_any = false;
//---
const int t = arr.Size();
if(t == 0)
{
ArrayResize(m_allowed_res, 1);
m_allowed_res[0] = 0; //
}
else
{
ArrayResize(m_allowed_res, t);
int k = 0;
CYmlIteratorArray it = arr.BeginArr();
while(it.IsValid())
{
CYmlNode val = it.Val();
ENUM_YML_CLASIFIER_TYPE_VAL val_type = val.GetType();
if(val_type == YML_CLASIFIER_TOKEN_TYPE_INTEGER)
{
m_allowed_res[k++] = int(val.ToInt(0)); // 0 siempre pased
}
else
{
// Any (ya con uno basta)
//Print("aa");
m_allowd_any = true;
}
it.Next();
}
}
}
//+------------------------------------------------------------------+
//| Creacdor (para factory) |
//+------------------------------------------------------------------+
class CWorflowStepCreator
{
public:
CWorflowStepCreator(void) {}
~CWorflowStepCreator(void) {}
virtual CWorkflowStep* Create() = 0;
};
//+------------------------------------------------------------------+
//| Factory |
//+------------------------------------------------------------------+
class CWorflowsFactory
{
public:
CWorflowsFactory(void) {}
~CWorflowsFactory(void) {}
//---
static CHashMap<string, CWorflowStepCreator*> s_hash_str_to_creator;
//---
static void Deinit(const int reason);
static CWorkflowStep* GetWorkflowStep(const string& module, const string& name);
};
//+------------------------------------------------------------------+
static CWorkflowStep* CWorflowsFactory::GetWorkflowStep(const string &module, const string &name)
{
CWorflowStepCreator* creator = NULL;
if(s_hash_str_to_creator.TryGetValue(module + "\\" + name, creator))
return creator.Create();
else
{
return NULL;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static void CWorflowsFactory::Deinit(const int reason)
{
//---
string temp[];
CWorflowStepCreator* vals[];
const int t = s_hash_str_to_creator.CopyTo(temp, vals);
//---
for(int i = 0; i < t; i++)
delete vals[i];
}
//+------------------------------------------------------------------+
CHashMap<string, CWorflowStepCreator*> CWorflowsFactory::s_hash_str_to_creator;
//+------------------------------------------------------------------+
//| Adder |
//+------------------------------------------------------------------+
//---
//bool g_worflow_boolean_dummy = true;
//---
#define WORKFLOWS_FACTORY_DEFINE_CREATOR(class_name, prefix, name, module) \
class CWorkflowStepCreator_##prefix : public CWorflowStepCreator \
{ \
public: \
CWorkflowStepCreator_##prefix(void) {} \
~CWorkflowStepCreator_##prefix(void) {} \
CWorkflowStep* Create() override final { return new class_name(); } \
}; \
const bool g_worflow_b_dummy_##prefix = CWorflowsFactory::s_hash_str_to_creator.Add(((module) + "\\" + (name)), new CWorkflowStepCreator_##prefix());
//+------------------------------------------------------------------+
#endif // WORKFLOWSBYLEO_SRC_CORE_DEF_MQH