Очередь сообщений как в Виндовсе. Упрощаем себе loop()

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017
b707
Offline
Зарегистрирован: 26.05.2017

Сразу вопрос. Выдержка из примера в README

void setup()
{
 MessageList=new TMessageList();      // очередь глубиной 16 сообщений	
 TimerList.AddSeconds(tmrClock,1);    // функция tmrClock будет вызываца 1 раз в секунду
}

разве в этом случае  MessageList не будет локальной переменной setup() ?

и еще есть вопросы... но пока этот

 

UPD - отвечаю сам себе, я попутал, это не обьявление переменной, а инициализация... Обьявление ее должно быть глобальным, верно?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017
у меня так
 
extern TMessageList     *MessageList;
 
b707
Offline
Зарегистрирован: 26.05.2017

не знаю, стоит ли упоминать это для новичков, но вообще так описанный класс может изпользоваться только в глобальном контексте, иначе будут утечки памяти.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Можно и не делать ее extern, а объявить в главном файле проекта, но удобно, когда все классы проекта её видят и кладут сообщения сами.  Например по таймеру вызывается опрос датчика дыма, который для удобства сделан классом.  У этого класса есть свойство Treshold(порог срабатывания), который можно менять снаружи.  Так вот, по таймеру я вызываю функцию чтения значения дыма, и если порог превышен, этот класс сам кладет соответствующее сообщение в очередь. В loop() по этому сообщению дается команда включить вентилятор и стартует другой таймер, которым настраивается длительность его работы (1 минута после возвращения дыма в нормальное состояние). Пока дым выше заданного порога,  таймер длительности вентилятора постоянно сбрасывается на 1 минуту.  

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Нинаю, у меня эта хня и на ATtiny85 работает, только очередь сообщений длиной 8, а таймеров - 4.  На меге вообще памяти завались, 8 кб целых, туда аж текстовый экранный буфер помещается. 

b707
Offline
Зарегистрирован: 26.05.2017

DetSimen пишет:

Можно и не делать ее extern, а объявить в главном файле проекта,

не, я не об этом. Класс, в котором есть ссылочные переменные - обязательно должен иметь деструктор с очисткой памяти, на которые эти переменные ссылаются... т.к. компилятор сам такую память чистить не умеет. Ну или использовать класс только в глобале - тогда это непринципиально. Там и еще есть ограничения...

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

b707 пишет:

DetSimen пишет:

Можно и не делать ее extern, а объявить в главном файле проекта,

не, я не об этом. Класс, в котором есть ссылочные переменные - обязательно должен иметь деструктор с очисткой памяти, на которые эти переменные ссылаются... т.к. компилятор сам такую память чистить не умеет. Ну или использовать класс только в глобале - тогда это непринципиально. Там и еще есть ограничения...

если посмотреть в h файл, там

~TMessageList();
 
а в cpp
 
TMessageList::~TMessageList()
{
delete[] Items;
}
 
по-хорошему надо еще и Messages из Items удалять, если оне тама есть.  
Но я вообще ни разу не видел, чтоб этот деструктор хоть раз вызывался. 

 

b707
Offline
Зарегистрирован: 26.05.2017

DetSimen пишет:

если посмотреть в h файл, там

~TMessageList();
 
а в cpp
 
TMessageList::~TMessageList()
{
delete[] Items;
}
 
по-хорошему надо еще и Messages из Items удалять, если оне тама есть.  
Но я вообще ни разу не видел, чтоб этот деструктор хоть раз вызывался. 

 

ага сорри, просмотрел.

Деструктор вызывается неявно, например при выходе из функции, в которой экземпляр класса создан локально. Но если класс только глобальный, это не важно.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

дык, деструктор объекта класса, объявленного где-то в подпрограмме, вызывается автоматом после завершения подпрограммы.

откуда там утечки?

b707
Offline
Зарегистрирован: 26.05.2017

Клапауций 112 пишет:

дык, деструктор объекта класса, объявленного где-то в подпрограмме, вызывается автоматом после завершения подпрограммы.

откуда там утечки?

Если у класса нет явно обьявленного деструктора, будет вызван стандартный, который не чистит память по указателям

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

деструктор я переделаю, буду и очередь очищать....  Тогда можно будет наплодить мааааленьких лупов со своей локальной очередью сапщений. :)

Только я пока не вижу зачем. 

b707
Offline
Зарегистрирован: 26.05.2017

Если по хорошему, одного деструктора мало :)

вот статейка есть интересная на эту тему http://pages.cs.wisc.edu/~hasti/cs368/CppTutorial/NOTES/CLASSES-PTRS.html (на английском)

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

b707 пишет:

Клапауций 112 пишет:

дык, деструктор объекта класса, объявленного где-то в подпрограмме, вызывается автоматом после завершения подпрограммы.

откуда там утечки?

Если у класса нет явно обьявленного деструктора, будет вызван стандартный, который не чистит память по указателям

ок. но тогда у ТС проблема не с деструктором, а в архитектуре балалайки - где-то оно автоматом должно заботиться об утилизации.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

деструктор переделан. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Похоже или я ничего не понял или одно из двух. Начнем с того что Ардуина построена по гарвардской системе. Отдельно ОЗУ, отдельно ПЗУ. У винды Сплошное ОЗУ. Винде ОЗУ экономить за счет ПЗУ не надо.

char *msd="massage";

 Сколько это занимает памяти в ОЗУ - 1 указатель на char и все. Остальное в ПЗУ.

Что надо написать, что бы это сообщение добавить в очередь.

queue->Add(/*сообщение*/msd,/*квакнуть в это время*/time);

И сообщение уйдет куда надо в нужное время.

Logik
Offline
Зарегистрирован: 05.08.2014

Ну что Вы такое пишите?! "Высокоуровневым" о таком заморачиватся не кошерно, главное что класс есть. С деструктором. И как у винды. А что 800 байт на кнопки - то фигня, главное маневры ;)

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Logik пишет:

А что 800 байт на кнопки - то фигня, главное маневры ;)

главное, критиковать и кукарекать, что можешь лучше, но не делать лучше потому, что невозможно. :D