115 lines
3.7 KiB
MQL5
115 lines
3.7 KiB
MQL5
|
//+------------------------------------------------------------------+
|
||
|
//| Comments.mqh |
|
||
|
//| Copyright 2021, MetaQuotes Ltd. |
|
||
|
//| https://www.mql5.com |
|
||
|
//+------------------------------------------------------------------+
|
||
|
#include "StringUtils.mqh"
|
||
|
|
||
|
// default buffer size is 10 lines of text
|
||
|
#ifndef N_LINES
|
||
|
#define N_LINES 10
|
||
|
#define N_LINES_DEFINED
|
||
|
#endif
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Multiline comment storage and display tool |
|
||
|
//+------------------------------------------------------------------+
|
||
|
class Comments
|
||
|
{
|
||
|
const int capacity; // maximum number of lines
|
||
|
const bool reverse; // order of display (true means recents on top)
|
||
|
string lines[]; // text buffer
|
||
|
int cursor; // where to place next string
|
||
|
int size; // actual number of lines stored
|
||
|
|
||
|
public:
|
||
|
Comments(const int limit = N_LINES, const bool r = false):
|
||
|
capacity(limit), reverse(r), cursor(0), size(0)
|
||
|
{
|
||
|
ArrayResize(lines, capacity);
|
||
|
}
|
||
|
|
||
|
void add(const string line);
|
||
|
void clear();
|
||
|
};
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Clean up the chart comment and internal buffer |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void Comments::clear()
|
||
|
{
|
||
|
Comment("");
|
||
|
cursor = 0;
|
||
|
size = 0;
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Add new line(s) of text to the chart comment |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void Comments::add(const string line)
|
||
|
{
|
||
|
if(line == NULL)
|
||
|
{
|
||
|
clear();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// if input string contains several lines
|
||
|
// split it by newline character into array
|
||
|
string inputs[];
|
||
|
const int n = StringSplit(line, '\n', inputs);
|
||
|
|
||
|
// add new line(s) into the ring buffer
|
||
|
// at the cursor position (overwriting most outdated records)
|
||
|
// cursor is always incremented modulo capacity (reset to 0 on overflow)
|
||
|
for(int i = 0; i < n; ++i)
|
||
|
{
|
||
|
lines[cursor] = inputs[reverse ? n - i - 1 : i];
|
||
|
cursor = (cursor + 1) % capacity;
|
||
|
if(size < capacity) ++size;
|
||
|
}
|
||
|
|
||
|
// combine all text from the buffer in direct or reverse order
|
||
|
// newline character is used as a glue
|
||
|
string result = "";
|
||
|
for(int i = 0, k = size == capacity ? cursor % capacity : 0; i < size; ++i, k = ++k % capacity)
|
||
|
{
|
||
|
if(reverse)
|
||
|
{
|
||
|
result = lines[k] + "\n" + result;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
result += lines[k] + "\n";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// finally output the result
|
||
|
Comment(result);
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Continuous comment feed will show most recent posts on top |
|
||
|
//| in reverse chronological order |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void MultiComment(const string line = NULL)
|
||
|
{
|
||
|
static Comments com(N_LINES, true);
|
||
|
com.add(line);
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| Bulk posts with multiple lines are better to show in natural |
|
||
|
//| chronological order (full story reading goes from top to bottom) |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void ChronoComment(const string line = NULL)
|
||
|
{
|
||
|
static Comments com(N_LINES, false);
|
||
|
com.add(line);
|
||
|
}
|
||
|
|
||
|
#ifdef N_LINES_DEFINED
|
||
|
#undef N_LINES
|
||
|
#endif
|
||
|
//+------------------------------------------------------------------+
|