forked from rosh/MQL5Book
114 lines
3.7 KiB
MQL5
114 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
| |
//+------------------------------------------------------------------+
|