Skip to content

Commit

Permalink
WIP. End up with include loop.
Browse files Browse the repository at this point in the history
  • Loading branch information
nseam committed Jan 9, 2023
1 parent da13c54 commit ff982e3
Show file tree
Hide file tree
Showing 22 changed files with 551 additions and 295 deletions.
101 changes: 55 additions & 46 deletions Dict.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "Convert.basic.h"
#include "DictBase.mqh"
#include "DictIteratorBase.mqh"
#include "Matrix.mqh"
#include "Serializer/Serializer.h"
#include "Serializer/SerializerNodeIterator.h"
Expand All @@ -41,12 +42,12 @@ class DictIterator : public DictIteratorBase<K, V> {
/**
* Constructor.
*/
DictIterator(DictBase<K, V>& dict, unsigned int slotIdx) : DictIteratorBase(dict, slotIdx) {}
DictIterator(DictBase<K, V>& dict, unsigned int slotIdx) : DictIteratorBase<K, V>(dict, slotIdx) {}

/**
* Copy constructor.
*/
DictIterator(const DictIterator& right) : DictIteratorBase(right) {}
DictIterator(const DictIterator& right) : DictIteratorBase<K, V>(right) {}
};

/**
Expand All @@ -70,37 +71,37 @@ class Dict : public DictBase<K, V> {
Clear();
Resize(right.GetSlotCount());
for (unsigned int i = 0; i < (unsigned int)ArraySize(right._DictSlots_ref.DictSlots); ++i) {
_DictSlots_ref.DictSlots[i] = right._DictSlots_ref.DictSlots[i];
THIS_ATTR _DictSlots_ref.DictSlots[i] = right._DictSlots_ref.DictSlots[i];
}
_DictSlots_ref._num_used = right._DictSlots_ref._num_used;
_current_id = right._current_id;
_mode = right._mode;
THIS_ATTR _DictSlots_ref._num_used = right._DictSlots_ref._num_used;
THIS_ATTR _current_id = right._current_id;
THIS_ATTR _mode = right._mode;
}

void operator=(const Dict<K, V>& right) {
Clear();
Resize(right.GetSlotCount());
for (unsigned int i = 0; i < (unsigned int)ArraySize(right._DictSlots_ref.DictSlots); ++i) {
_DictSlots_ref.DictSlots[i] = right._DictSlots_ref.DictSlots[i];
THIS_ATTR _DictSlots_ref.DictSlots[i] = right._DictSlots_ref.DictSlots[i];
}
_DictSlots_ref._num_used = right._DictSlots_ref._num_used;
_current_id = right._current_id;
_mode = right._mode;
THIS_ATTR _DictSlots_ref._num_used = right._DictSlots_ref._num_used;
THIS_ATTR _current_id = right._current_id;
THIS_ATTR _mode = right._mode;
}

void Clear() {
for (unsigned int i = 0; i < (unsigned int)ArraySize(_DictSlots_ref.DictSlots); ++i) {
if (_DictSlots_ref.DictSlots[i].IsUsed()) _DictSlots_ref.DictSlots[i].SetFlags(0);
for (unsigned int i = 0; i < (unsigned int)ArraySize(THIS_ATTR _DictSlots_ref.DictSlots); ++i) {
if (THIS_ATTR _DictSlots_ref.DictSlots[i].IsUsed()) THIS_ATTR _DictSlots_ref.DictSlots[i].SetFlags(0);
}

_DictSlots_ref._num_used = 0;
THIS_ATTR _DictSlots_ref._num_used = 0;
}

/**
* Inserts value using hashless key.
*/
bool Push(V value) {
if (!InsertInto(_DictSlots_ref, value)) return false;
if (!InsertInto(THIS_ATTR _DictSlots_ref, value)) return false;
return true;
}

Expand All @@ -113,15 +114,15 @@ class Dict : public DictBase<K, V> {
* Inserts or replaces value for a given key.
*/
bool Set(K key, V value) {
if (!InsertInto(_DictSlots_ref, key, value, true)) return false;
if (!InsertInto(THIS_ATTR _DictSlots_ref, key, value, true)) return false;
return true;
}

V operator[](K key) {
if (_mode == DictModeList) return GetSlot((unsigned int)key).value;
if (THIS_ATTR _mode == DictModeList) return THIS_ATTR GetSlot((unsigned int)key).value;

int position;
DictSlot<K, V>* slot = GetSlotByKey(_DictSlots_ref, key, position);
DictSlot<K, V>* slot = GetSlotByKey(THIS_ATTR _DictSlots_ref, key, position);

if (!slot) return (V)NULL;

Expand All @@ -136,7 +137,7 @@ class Dict : public DictBase<K, V> {
*/
V GetByKey(const K _key, V _default = NULL) {
unsigned int position;
DictSlot<K, V>* slot = GetSlotByKey(_DictSlots_ref, _key, position);
DictSlot<K, V>* slot = GetSlotByKey(THIS_ATTR _DictSlots_ref, _key, position);

if (!slot) {
return _default;
Expand All @@ -149,7 +150,7 @@ class Dict : public DictBase<K, V> {
* Returns value for a given position.
*/
V GetByPos(unsigned int _position) {
DictSlot<K, V>* slot = GetSlotByPos(_DictSlots_ref, _position);
DictSlot<K, V>* slot = GetSlotByPos(THIS_ATTR _DictSlots_ref, _position);

if (!slot) {
Alert("Invalid DictStruct position \"", _position, "\" (called by GetByPos()). Returning empty structure.");
Expand All @@ -164,10 +165,12 @@ class Dict : public DictBase<K, V> {
/**
* Checks whether dictionary contains given key => value pair.
*/
#ifdef __MQL__
template <>
#endif
bool Contains(const K key, const V value) {
unsigned int position;
DictSlot<K, V>* slot = GetSlotByKey(_DictSlots_ref, key, position);
DictSlot<K, V>* slot = GetSlotByKey(THIS_ATTR _DictSlots_ref, key, position);

if (!slot) return false;

Expand All @@ -177,9 +180,11 @@ class Dict : public DictBase<K, V> {
/**
* Returns index of dictionary's value or -1 if value doesn't exist.
*/
#ifdef __MQL__
template <>
#endif
int IndexOf(V& value) {
for (DictIteratorBase<K, V> i(Begin()); i.IsValid(); ++i) {
for (DictIteratorBase<K, V> i(THIS_ATTR Begin()); i.IsValid(); ++i) {
if (i.Value() == value) {
return (int)i.Index();
}
Expand All @@ -192,7 +197,7 @@ class Dict : public DictBase<K, V> {
* Checks whether dictionary contains given value.
*/
bool Contains(const V value) {
for (DictIterator<K, V> i = Begin(); i.IsValid(); ++i) {
for (DictIterator<K, V> i = THIS_ATTR Begin(); i.IsValid(); ++i) {
if (i.Value() == value) {
return true;
}
Expand Down Expand Up @@ -232,16 +237,17 @@ class Dict : public DictBase<K, V> {
if ((_is_full || !_is_performant) && allow_resize) {
// We have to resize the dict as it is either full or have perfomance problems due to massive number of conflicts
// when inserting new values.
if (overflow_listener == NULL) {
if (THIS_ATTR overflow_listener == NULL) {
// There is no overflow listener so we can freely grow up the dict.
if (!GrowUp()) {
// Can't resize the dict. Error happened.
return false;
}
} else {
// Overflow listener will decide if we can grow up the dict.
if (overflow_listener(_is_full ? DICT_LISTENER_FULL_CAN_RESIZE : DICT_LISTENER_NOT_PERFORMANT_CAN_RESIZE,
dictSlotsRef._num_used, 0)) {
if (THIS_ATTR overflow_listener(
_is_full ? DICT_LISTENER_FULL_CAN_RESIZE : DICT_LISTENER_NOT_PERFORMANT_CAN_RESIZE,
dictSlotsRef._num_used, 0)) {
// We can freely grow up the dict.
if (!GrowUp()) {
// Can't resize the dict. Error happened.
Expand All @@ -268,11 +274,12 @@ class Dict : public DictBase<K, V> {
(!dictSlotsRef.DictSlots[position].HasKey() || dictSlotsRef.DictSlots[position].key != key)) {
++_num_conflicts;

if (overflow_listener != NULL) {
if (THIS_ATTR overflow_listener != NULL) {
// We had to skip slot as it is already occupied. Now we are checking if
// there is too many conflicts/skips and thus we can overwrite slot in
// the starting position.
if (overflow_listener(DICT_LISTENER_CONFLICTS_CAN_OVERWRITE, dictSlotsRef._num_used, _num_conflicts)) {
if (THIS_ATTR overflow_listener(DICT_LISTENER_CONFLICTS_CAN_OVERWRITE, dictSlotsRef._num_used,
_num_conflicts)) {
// Looks like dict is working as buffer and we can overwrite slot in the starting position.
position = _starting_position;
break;
Expand Down Expand Up @@ -309,9 +316,9 @@ class Dict : public DictBase<K, V> {
* Inserts hashless value into given array of DictSlots.
*/
bool InsertInto(DictSlotsRef<K, V>& dictSlotsRef, V value) {
if (_mode == DictModeUnknown)
_mode = DictModeList;
else if (_mode != DictModeList) {
if (THIS_ATTR _mode == DictModeUnknown)
THIS_ATTR _mode = DictModeList;
else if (THIS_ATTR _mode != DictModeList) {
Alert("Warning: Dict already operates as a dictionary, not a list!");
DebugBreak();
return false;
Expand All @@ -322,7 +329,7 @@ class Dict : public DictBase<K, V> {
if (!GrowUp()) return false;
}

unsigned int position = Hash((unsigned int)dictSlotsRef._list_index) % ArraySize(dictSlotsRef.DictSlots);
unsigned int position = THIS_ATTR Hash((unsigned int)dictSlotsRef._list_index) % ArraySize(dictSlotsRef.DictSlots);

// Searching for empty DictSlot<K, V>.
while (dictSlotsRef.DictSlots[position].IsUsed()) {
Expand All @@ -342,14 +349,15 @@ class Dict : public DictBase<K, V> {
* Expands array of DictSlots by given percentage value.
*/
bool GrowUp(int percent = DICT_GROW_UP_PERCENT_DEFAULT) {
return Resize(MathMax(10, (int)((float)ArraySize(_DictSlots_ref.DictSlots) * ((float)(percent + 100) / 100.0f))));
return Resize(
MathMax(10, (int)((float)ArraySize(THIS_ATTR _DictSlots_ref.DictSlots) * ((float)(percent + 100) / 100.0f))));
}

/**
* Shrinks or expands array of DictSlots.
*/
bool Resize(int new_size) {
if (new_size <= MathMin(_DictSlots_ref._num_used, ArraySize(_DictSlots_ref.DictSlots))) {
if (new_size <= MathMin(THIS_ATTR _DictSlots_ref._num_used, ArraySize(THIS_ATTR _DictSlots_ref.DictSlots))) {
// We already use minimum number of slots possible.
return true;
}
Expand All @@ -367,36 +375,37 @@ class Dict : public DictBase<K, V> {
new_DictSlots._num_used = 0;

// Copies entire array of DictSlots into new array of DictSlots. Hashes will be rehashed.
for (i = 0; i < ArraySize(_DictSlots_ref.DictSlots); ++i) {
if (!_DictSlots_ref.DictSlots[i].IsUsed()) continue;
for (i = 0; i < ArraySize(THIS_ATTR _DictSlots_ref.DictSlots); ++i) {
if (!THIS_ATTR _DictSlots_ref.DictSlots[i].IsUsed()) continue;

if (_DictSlots_ref.DictSlots[i].HasKey()) {
if (!InsertInto(new_DictSlots, _DictSlots_ref.DictSlots[i].key, _DictSlots_ref.DictSlots[i].value, false))
if (THIS_ATTR _DictSlots_ref.DictSlots[i].HasKey()) {
if (!InsertInto(new_DictSlots, THIS_ATTR _DictSlots_ref.DictSlots[i].key,
THIS_ATTR _DictSlots_ref.DictSlots[i].value, false))
return false;
} else {
if (!InsertInto(new_DictSlots, _DictSlots_ref.DictSlots[i].value)) return false;
if (!InsertInto(new_DictSlots, THIS_ATTR _DictSlots_ref.DictSlots[i].value)) return false;
}
}
// Freeing old DictSlots array.
ArrayFree(_DictSlots_ref.DictSlots);
ArrayFree(THIS_ATTR _DictSlots_ref.DictSlots);

_DictSlots_ref = new_DictSlots;
THIS_ATTR _DictSlots_ref = new_DictSlots;

return true;
}

public:
#ifdef __cplusplus
#ifdef __MQL__
template <>
#endif
SerializerNodeType Serialize(Serializer& s) {
if (s.IsWriting()) {
for (DictIteratorBase<K, V> i(Begin()); i.IsValid(); ++i) {
for (DictIteratorBase<K, V> i(THIS_ATTR Begin()); i.IsValid(); ++i) {
V value = i.Value();
s.Pass(THIS_REF, GetMode() == DictModeDict ? i.KeyAsString() : "", value);
s.Pass(THIS_REF, THIS_ATTR GetMode() == DictModeDict ? i.KeyAsString() : "", value);
}

return (GetMode() == DictModeDict) ? SerializerNodeObject : SerializerNodeArray;
return (THIS_ATTR GetMode() == DictModeDict) ? SerializerNodeObject : SerializerNodeArray;
} else {
SerializerIterator<V> i;

Expand Down Expand Up @@ -432,9 +441,9 @@ class Dict : public DictBase<K, V> {
*/
template <typename X>
Matrix<X>* ToMatrix() {
Matrix<X>* result = new Matrix<X>(Size());
Matrix<X>* result = new Matrix<X>(THIS_ATTR Size());

for (DictIterator<K, V> i = Begin(); i.IsValid(); ++i) result[i.Index()] = (X)i.Value();
for (DictIterator<K, V> i = THIS_ATTR Begin(); i.IsValid(); ++i) result[i.Index()] = (X)i.Value();

return result;
}
Expand Down
36 changes: 19 additions & 17 deletions Draw.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ class Chart;
class Draw;

// Includes.
#include "Chart.mqh"
#include "Data.define.h"
#include "Object.extern.h"
#include "Platform.h"
#include "Terminal.define.h"

#ifndef __MQL4__
// Defines macros (for MQL4 backward compatibility).
Expand All @@ -41,21 +43,6 @@ class Draw;
#define SetIndexShift(_index, _value) (PlotIndexSetInteger(_index, PLOT_SHIFT, _value))
#endif

#ifndef __MQL4__
// Defines global functions (for MQL4 backward compatibility).
bool ObjectCreate(string _name, ENUM_OBJECT _otype, int _swindow, datetime _t1, double _p1) {
return Draw::ObjectCreate(0, _name, _otype, _swindow, _t1, _p1);
}
bool ObjectDelete(string _name) { return Draw::ObjectDelete(_name); }
bool ObjectSet(string _name, int _prop_id, double _value) { return Draw::ObjectSet(_name, _prop_id, _value); }
int ObjectsTotal(int _type = EMPTY) { return Draw::ObjectsTotal(); }
string ObjectName(int _index) { return Draw::ObjectName(_index); }
void SetIndexLabel(int _index, string _text) { Draw::SetIndexLabel(_index, _text); }
void SetIndexStyle(int _index, int _type, int _style = EMPTY, int _width = EMPTY, color _clr = CLR_NONE) {
Draw::SetIndexStyle(_index, _type, _style, _width, _clr);
}
#endif

#define WINDOW_MAIN 0

#ifdef __MQL5__
Expand Down Expand Up @@ -85,7 +72,7 @@ class Draw : public Object {
/**
* Class constructor.
*/
Draw(long _chart_id = 0) : chart_id(_chart_id != 0 ? _chart_id : ChartID()) {}
Draw(long _chart_id = 0) : chart_id(_chart_id != 0 ? _chart_id : Platform::ChartID()) {}

/* Graphic object related methods */

Expand Down Expand Up @@ -335,3 +322,18 @@ class Draw : public Object {
return true;
}
};

#ifndef __MQL4__
// Defines global functions (for MQL4 backward compatibility).
bool ObjectCreate(string _name, ENUM_OBJECT _otype, int _swindow, datetime _t1, double _p1) {
return Draw::ObjectCreate(0, _name, _otype, _swindow, _t1, _p1);
}
bool ObjectDelete(string _name) { return Draw::ObjectDelete(_name); }
bool ObjectSet(string _name, int _prop_id, double _value) { return Draw::ObjectSet(_name, _prop_id, _value); }
int ObjectsTotal(int _type = EMPTY) { return Draw::ObjectsTotal(); }
string ObjectName(int _index) { return Draw::ObjectName(_index); }
void SetIndexLabel(int _index, string _text) { Draw::SetIndexLabel(_index, _text); }
void SetIndexStyle(int _index, int _type, int _style = EMPTY, int _width = EMPTY, color _clr = CLR_NONE) {
Draw::SetIndexStyle(_index, _type, _style, _width, _clr);
}
#endif
1 change: 1 addition & 0 deletions File.extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

// Define external global functions.
#ifndef __MQL__
#pragma once

MemoryFileSystem _memfs;

Expand Down
5 changes: 5 additions & 0 deletions File.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
* - Files with which file operations are conducted means cannot be outside the file sandbox.
*/

#ifndef __MQL__
// Allows the preprocessor to include a header file when it is needed.
#pragma once
#endif

// Includes.
#include "File.define.h"
#include "File.extern.h"
Expand Down
4 changes: 2 additions & 2 deletions Indicator/Indicator.define.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
#define DUMMY

#define ICUSTOM_DEF(SET_HANDLE, PARAMS) \
double _res[]; \
if (_handle == NULL || _handle == INVALID_HANDLE) { \
ARRAY(double, _res); \
if (_handle == 0 || _handle == INVALID_HANDLE) { \
if ((_handle = ::iCustom(_symbol, _tf, _name PARAMS)) == INVALID_HANDLE) { \
SetUserError(ERR_USER_INVALID_HANDLE); \
return EMPTY_VALUE; \
Expand Down
5 changes: 2 additions & 3 deletions Indicator/IndicatorBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@
#include "../Array.mqh"
#include "../BufferStruct.mqh"
#include "../Chart.struct.tf.h"
//#include "../ChartBase.h"
#include "../ChartMt.h"
#include "../DateTime.mqh"
#include "../Log.mqh"
#include "../Object.mqh"
#include "../Platform.extern.h"
#include "../Refs.mqh"
#include "../Serializer/Serializer.h"
#include "../Serializer/SerializerCsv.h"
Expand Down Expand Up @@ -192,7 +191,7 @@ class IndicatorBase : public Object {
/**
* Get name of the indicator.
*/
virtual string GetName() = NULL;
virtual string GetName() = 0;

/**
* Get full name of the indicator (with "over ..." part).
Expand Down
Loading

0 comments on commit ff982e3

Please sign in to comment.