Создание многоуровневого графического меню

sadman41
Offline
Зарегистрирован: 19.10.2016

Инт в Лонг, инкрементация... Ты чего хочешь - штоп в структуре указатель на int x был? Ну так объяви в ней указатель и передай адрес при инициализации экземпляра структуры.

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

Лучше, ссылку. Указатель его до разбрызгиванья байт доведет.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Слушайте, без задачи мы, возможно говорим о разных сторонах слона.

Объясните толком, что это за "x"? Он один на всех? В том смысле, что если в программе 100500 экземпляров myStruct, то при инкрементировании "c" в любом из них, этот х должен тоже инкрементироваться? Так? Или как?

Кстати, что там делает typedef? Он не нужен, а если бы и был нужен, то он не так вводится.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Задача такая.

Структурное меню.

По нему передвигаемся(в моем случае энкодером, но можно чем угодно), выбираем той же кнопкой энкодера.

В некоторых подменю нужно задавать значение.

Там нет перехода perv/next(их значение задано как NULL), вход и выход по кнопке.

Так вот когда находимся в этих подменю , врещнние энкодера меня нет значение переменной.

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

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Это не какой то конечный продукт, просто изучение самой концепции.

#define EncA_PIN 2
#define EncB_PIN 3
#define EncBtn_PIN 5
#include <kakmyc_btn.h>
enum function{NONE,ENTER,INPUT_VAL,EXEC};

int volume=10;
typedef struct menuItem
{   char *name;
    menuItem *prev;
    menuItem *next;
    menuItem *ok;
    byte func_num;
    void (*Handler)();
    int value;
} menuItem;
menuItem m1,m2,m3,m4,m11,m111,m12,m13,m21,m22,m31,m32,m33;



volatile int Enc_tick;
boolean update_flag;
byte btn1state;
uint32_t time2update;
kakmyc_btn btn1(5,INPUT_PULLUP,2);

void blink(){
    Serial.println("blink");
    delay(20);
    digitalWrite(13,!digitalRead(13));
}

void EncA_ISR(){cli();
digitalRead(EncA_PIN)==digitalRead(EncB_PIN)?Enc_tick=1:Enc_tick=-1;
    sei();
}

void setup(){
    Serial.begin(9600);
    pinMode(13,1);
    pinMode(EncA_PIN,INPUT_PULLUP);
    pinMode(EncB_PIN,INPUT_PULLUP);
    attachInterrupt(0,EncA_ISR,RISING);
}

void loop(){
    btn1state=btn1.read();
m1={"Setup menu",&m4,&m2,&m11,1};
m11={"set volume",&m13,&m12,&m111,1,NULL};
 m111={"setup_volume",NULL,NULL,&m1,2,NULL,volume};
m12={"set brightness",&m11,&m13,&m1,1};
m13={"set value",&m12,&m11,&m1,1,NULL};
m2={"Time menu",&m1,&m3,NULL,1,NULL};
m3={"Power menu",&m2,&m4,NULL,3,NULL};
m4={"Light ON/OFF",&m3,&m1,NULL,3,blink}; 
        
    
    
static menuItem *curItem = &m1;
    
      switch(Enc_tick){
            case 1:
        if(curItem->func_num==2){
        curItem->value++;
        
    }else{       
curItem->next?curItem=curItem->next:NULL;}
        update_flag=1;
        Enc_tick=0;
            break;
        
            case -1:
        if(curItem->func_num==2){
        curItem->value--;
    }else{
    curItem->prev?curItem=curItem->prev:NULL;}
        update_flag=1;
        Enc_tick=0;
        break;
        }        
        if(btn1state==1){           
     update_flag=1;
        if(curItem->Handler){(*curItem->Handler)();}
else {curItem->ok?curItem=curItem->ok:NULL;
        }
    }
    if(update_flag){
    Serial.println(curItem->name);
        Serial.println(curItem->value);
        update_flag=0;
    }    
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Нет, в этом случае указатель не надо. Коль скоро переменная одна на всех, то пусть она одна и остаётся (и одна только память жрёт). А с указателем у Вас будет память жраться на переменную и на указатели во всех элементах - намного больше.

Это делается примерно так:

1. В саму структуру добавляете статическое поле 

struct Kaka {
    ...
    static int x = 0;
    ...
};

далее в функциях перехода пишем так:

struct Kaka {
    ...
    static int x = 0;
    ...
    void moveUp() {
        if (prev == NULL && next == NULL) x++;
        else {
            // здесь переход вверх как он и был
        }
    }
    ...
    void moveDown() {
        if (prev == NULL && next == NULL) x--;
        else {
            // здесь переход вниз как он и был
        }
    }
};

До значения x всегда можно добраться через название класса. В моём случае класс называется Kaka, так что добираемся так: Kaka::x

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Переменная не одна.

Иначе я не понимаю как хранить все эти значения и работать с ними.

 

Хочется сделать по аналогии с Handler'ом.

Из каждого подменю запускать свою функцию(если подменю это разрешает)

И точно так же в каждом подменю которое разрешает менять значение переменной, изменять свою переменную.

 

Вот мне и непонятен механизм .

Если мы указываем на переменную "х", то внутренняя переменная структуры , только принимает ее значение при входе в структуру.

И меняем мы только внутреннюю переменную структуры, никак не затрагивая переменную на которую структура ссылается при создании

nik182
Offline
Зарегистрирован: 04.05.2015

По хорошему, нужна только одна переменная в меню на которую можно скастовать любой тип. При входе в пункт меню, где возможно изменение величины любой переменной из программы, переменной из меню присваивается значение переменной из программы и на дисплей выводится экран с возможностью изменять. По выходу из этого пункта меню проверять - согласен пользователь с изменениями или нет. Если да, переменной программы присваивается изменённое значение, если нет - то и не надо. Бывает так, что наизменяв в меню переменную хочешь оставить начальное значение. Типа ENTER и ESC для ввода значения - длинное короткое нажатие на джойстик. Можно такое организовать?      

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Написать то можно всё что угодно,  но нужно сделать это понятно и компактно.

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Kakmyc пишет:

Переменная не одна.

Ну, вот смотрите, я долго спрашивал Вас одна она или не одна (ещё в #53 жирным шрифтом!). Ответ получил только после того, как пример написал. Вам трудно было раньше ответить? Вы правда думаете, что мне больше нечего делать, как писать примеры один за другим, после каждого узнавая что-то новое? Мне вот жалко потраченного на тот пример времени. давайте Вы будете чётко отвечать на вопросы.

Итак, что такое не одна? Своя на каждый экземпляр структуры? Или пара-тройка на все? Объясните Вы толком, без этого Вам нельзя помочь.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Скажем имеем переменные:

Громкость,яркость, скважность, длительность, время и тд.

Все они задаются через меню, каждая из своего подпункта.

Т.е. и каждый подпункт должен менять значение только своей переменной.

Портянка типа:

if(val_increment){
switch(curItem>menu_id){
case 11:
Яркость++
break;
case 151:
громкость++;
break;
.....
....
....
case 100501:
Ещекакаятохерь++;
break;
}

Какой то вариант некрасивый

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Сейчас подробнее есть набор структур вот такого типа

typedef struct menuItem
{   char *name;
    struct menuItem *prev;
    struct menuItem *next;
    struct menuItem *ok;
    byte func_num;
    void (*Handler)();
    int value;
} menuItem;

menuItem m1,m2,m3,m4,m11,m111,m121,m12,m13,m21,m22,m31,m32,m33;
//Конкретно здесь переменные 
int volume,PWM;

 

Объявлены они вот так:

 

m1={"Setup menu",&m4,&m2,&m11,1};
m11={"set volume",&m13,&m12,&m111,1,NULL};
 m111={"setup_volume",NULL,NULL,&m1,2,NULL,*&volume};//так как объявлено тут не работает
m12={"set brightness",&m11,&m13,&m121,1};
    m121={"set_brightness",NULL,NULL,&m1,2,NULL,*&PWM};
m13={"set value",&m12,&m11,&m1,1,NULL};
m2={"Time menu",&m1,&m3,NULL,1,NULL};
m3={"Power menu",&m2,&m4,NULL,3,NULL};
m4={"Light ON/OFF",&m3,&m1,NULL,3,blink}; 
        

 

Переходы заложены в самих структурах.

Так же там есть идентификатор того, что делать при том или ином типе идентификатора.

1 просто меню с переходами

2 подменю где выставляются значения переменных

3 по нажатию "ок" вызывается обработчик функции.

 

Так вот, нужно к каждому пункту меню типа 2, привязать ссылку на свою переменную.

 

 

Вопрос: как это сделать ?

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Kakmyc пишет:

Скажем имеем переменные:

Громкость,яркость, скважность, длительность, время и тд.

Все они задаются через меню, каждая из своего подпункта.

Т.е. и каждый подпункт должен менять значение только своей переменной.

Ну, тогда зачем изобретать велосипед? В моём изначальном примере есть метод action - он как раз для этого - чтобы делать то, что нужно, когда данный элемент меню выбран! Вот в него это  надо пихать. Пусть меняет что хочет.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Может я не тот пример смотрел, но метод action кроме вывода в монитор ничего не делает и ни где не вызывается.

 

(*Handler)() и у меня вполне работает, но тогда опять же нужно знать, что в него передавать и опять же на переменную ссылка в нем нужна

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Пока остановился на таком варианте:

Создаём массив с переменными.

За место переменной в экземпляре структуры указываем литерал указывающий на номер члена массива. И работаем с переменной через него.

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Kakmyc пишет:

Может я не тот пример смотрел, но метод action кроме вывода в монитор ничего не делает и ни где не вызывается.

Вы комментарии не читали. Он должен "делать то, что нужно, когда вызвали" - у меня в примере печатал, у Вас может видео с порхаба скачивать. Что нужно, то и делает.

Kakmyc пишет:

(*Handler)() и у меня вполне работает, но тогда опять же нужно знать, что в него передавать и опять же на переменную ссылка в нем нужна

Какая ссылка? Сделайте эту переменную свойством структуры (как prev) и он всегда будет иметь доступ именно к своей, а не к чужой.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

ЕвгенийП пишет:

Kakmyc пишет:

Может я не тот пример смотрел, но метод action кроме вывода в монитор ничего не делает и ни где не вызывается.

Вы комментарии не читали. Он должен "делать то, что нужно, когда вызвали" - у меня в примере печатал, у Вас может видео с порхаба скачивать. Что нужно, то и делает.

Kakmyc пишет:

(*Handler)() и у меня вполне работает, но тогда опять же нужно знать, что в него передавать и опять же на переменную ссылка в нем нужна

Какая ссылка? Сделайте эту переменную свойством структуры (как prev) и он всегда будет иметь доступ именно к своей, а не к чужой.

Я все читал.
Просто я не знаю , как сделать указатель
на ссылку в структуре.
Кучу инфы перелопатил решения не нашел.
Колхозю по своему, по колхозному.
Давая советы , учитывайте, что не все знают ЯП'ы на вашем уровне.
Я вот знаю, что такое ссылка/указатель, но у меня компилятор ругается, когда я ссылку пытаюсь засунуть в структуру, я знаю, что сделать это можно 100%, но я просто не знаю синтаксиса

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Kakmyc пишет:
Я вот знаю, что такое ссылка/указатель

Да, в том-то и проблема, что не знаете. Вы даже не знаете. что ссылка и указатель - это совершенно разные вещи. Например, в С++ есть и то и другое, а в С ссылок нет - есть только указатели.

Kakmyc пишет:
ссылку пытаюсь засунуть в структуру, я знаю, что сделать это можно 100%, но я просто не знаю синтаксиса

Да, не надо Вам этого. Просто заведите там обыкновенную переменную. Зачем Вам ссылка? Я думал, что Вы хотите иметь одну переменную на всех - для того и ссылка, а если нет, то никакая ссылка Вам не нужна. Просто заведите там переменную (как prev заведёт) и пользуйте её на здоровье.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

ЕвгенийП пишет:

Kakmyc пишет:
Я вот знаю, что такое ссылка/указатель

Да, в том-то и проблема, что не знаете. Вы даже не знаете. что ссылка и указатель - это совершенно разные вещи. Например, в С++ есть и то и другое, а в С ссылок нет - есть только указатели.

Kakmyc пишет:
ссылку пытаюсь засунуть в структуру, я знаю, что сделать это можно 100%, но я просто не знаю синтаксиса

Да, не надо Вам этого. Просто заведите там обыкновенную переменную. Зачем Вам ссылка? Я думал, что Вы хотите иметь одну переменную на всех - для того и ссылка, а если нет, то никакая ссылка Вам не нужна. Просто заведите там переменную (как prev заведёт) и пользуйте её на здоровье.

Мне ненужна одна переменная на все структуры, мне нужна одна типовая структура со ссылкой на множество переменных в каждом из этих экземпляров своя переменная

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Блин, я Вам ХЗ какой раз раз пишу. Давайте напишу помедленнее и покрупнее

просто заведите поле в структуре (точно также, как заведено поле prev - ну точно также!). Назовите его, например, kaka. И эта самая kaka будет своя в каждом экземпляре. Никакие указатели и ссылки для этого не нужны от слова нахрен.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Тогда придется всегда хранить все структуры в памяти, что не есть хорошо.
Меню оно создаётся не ради меню, это всего лишь подпрограмма. Одно дело когда 5 пунктов меню, и совсем другое, когда 50.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А Вам по-любому придётся их хранить все в памяти. А где ещё Вы их собрались хранить?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Ну оно понятно, что в памяти, но одно дело всегда, и совсем другое, только в момент обращения к меню.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

В момент необращения где оно будет? На складе?

Kakmyc
Offline
Зарегистрирован: 15.01.2018

ЕвгенийП пишет:

В момент необращения где оно будет? На складе?

Меню- отдельная функция с локальными структурами.
Которые создаются каждый раз при входе в функцию и уничтожаются при выходе
В момент необращения его просто не будет.
А так же ещё может быть рабочий режим, в котором меню будет неактивно и дисплей будет отображать совсем иную информацию.
Так вот зачем все время держать в ОЗУ эти структуры ?

nik182
Offline
Зарегистрирован: 04.05.2015

Наверно, потому что это МК и правила программирования немножко другие, отличные от большого брата? Программа одна. Все требуемые ресурсы известны на стадии проектирования и освобождать память для других программ нет необходимости? Можно создать все объекты на стадии инициализации и потом не тратить на это время.   

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Kakmyc пишет:
Меню- отдельная функция с локальными структурами. Которые создаются каждый раз при входе в функцию и уничтожаются при выходе В момент необращения его просто не будет. А так же ещё может быть рабочий режим, в котором меню будет неактивно и дисплей будет отображать совсем иную информацию. Так вот зачем все время держать в ОЗУ эти структуры ?

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

А кроме того, таким приёмом Вы не сэкономите ничего. Ну, нет у Вас меню, а что статические элементы типа названий пунктов куда-то исчезли? Всё равно всё будет сидеть в памяти.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

nik182 пишет:

Наверно, потому что это МК и правила программирования немножко другие, отличные от большого брата? Программа одна. Все требуемые ресурсы известны на стадии проектирования и освобождать память для других программ нет необходимости? Можно создать все объекты на стадии инициализации и потом не тратить на это время.   

Так вот именно поэтому, если у меня 1кб ОЗУ из которых меню будет жрать половину и может не хватить каким то другим задачам в том числе и отрисовке и хочется отделить теплое от мягкого

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Цитата:

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

А кроме того, таким приёмом Вы не сэкономите ничего. Ну, нет у Вас меню, а что статические элементы типа названий пунктов куда-то исчезли? Всё равно всё будет сидеть в памяти.

Не будет ничего забывать, потому что static menuItem *curItem = &m1;

Опробовал и потестил, все работает примерно как и представлял, разница по памяти 386/516 в байтах.

Замерял функцией

int freeRam () {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

 

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Kakmyc пишет:

Не будет ничего забывать, потому что static menuItem *curItem = &m1;

А вот это попадалово на грабли!

Это будет работать только если между удалением объекта, на который указывает статический указатель и созданием его снова ничего не происходит с памятью и он будет создан точно в том же месте, где и был. Если же он будет создан хоть на байт в другом месте, Вы прибежите сюда вопросом типа: "рандомный глюк! несовместимость с библиотекой кнопки/сервы/экрана/"чесания задницы" - вот так всё работает, а стоит включить проверку кнопки, как всё зависает!".

Никогда ни используйте статический указатель на динамический объект!

nik182
Offline
Зарегистрирован: 04.05.2015

Kakmyc пишет:

 Так вот именно поэтому, если у меня 1кб ОЗУ из которых меню будет жрать половину и может не хватить каким то другим задачам в том числе и отрисовке и хочется отделить теплое от мягкого

В том и дело, что нет никаких других задач. Сейчас у Вас задача одна. В ней известно всё. Отрисовка это часть  задачи и про неё тоже всё известно. Как может чего то не хватить? А теплое от мягкого отделять  - это Вам в Виду надо, а не в АВР.  

Kakmyc
Offline
Зарегистрирован: 15.01.2018

ЕвгенийП пишет:

Kakmyc пишет:

Не будет ничего забывать, потому что static menuItem *curItem = &m1;

А вот это попадалово на грабли!

Это будет работать только если между удалением объекта, на который указывает статический указатель и созданием его снова ничего не происходит с памятью и он будет создан точно в том же месте, где и был. Если же он будет создан хоть на байт в другом месте, Вы прибежите сюда вопросом типа: "рандомный глюк! несовместимость с библиотекой кнопки/сервы/экрана/"чесания задницы" - вот так всё работает, а стоит включить проверку кнопки, как всё зависает!".

Никогда ни используйте статический указатель на динамический объект!

 

В моем случае такого быть не должно.

Работает потому, что немного

menuItem m1,m2,m3,m4,m11,m111,m121,m12,m13,m21,m22,m31,m32,m33;
    
m1={"Setup menu",&m4,&m2,&m11,1};
m11={"set volume",&m13,&m12,&m111,1,NULL};
m111={"setup_volume",NULL,NULL,&m1,2,NULL,1};
m12={"set brightness",&m11,&m13,&m121,1};
    m121={"set_brightness",NULL,NULL,&m1,2,NULL,2};
m13={"set value",&m12,&m11,&m1,1,NULL};
m2={"Time menu",&m1,&m3,NULL,1,NULL};
m3={"Power menu",&m2,&m4,NULL,3,NULL};
m4={"Light ON/OFF",&m3,&m1,NULL,3,blink};    

static menuItem *curItem = &m1;

по другому.

Просто копируем динамическую структуру в статическую и работаем только со статической.

Остальное можно даже в PROGMEM запихать.

Не дошел пока до этого

 

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

А так нельзя? static PROGMEM

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Вот вся функция меню.

Для лучшего понимания

void menu(){
    menuItem m1,m2,m3,m4,m11,m111,m121,m12,m13,m21,m22,m31,m32,m33;
    
m1={"Setup menu",&m4,&m2,&m11,1};
m11={"set volume",&m13,&m12,&m111,1,NULL};
m111={"setup_volume",NULL,NULL,&m1,2,NULL,1};
m12={"set brightness",&m11,&m13,&m121,1};
    m121={"set_brightness",NULL,NULL,&m1,2,NULL,2};
m13={"set value",&m12,&m11,&m1,1,NULL};
m2={"Time menu",&m1,&m3,NULL,1,NULL};
m3={"Power menu",&m2,&m4,NULL,3,NULL};
m4={"Light ON/OFF",&m3,&m1,NULL,3,blink};    
static menuItem *curItem = &m1;
    
      switch(Enc_tick){
            case 1:
        if(curItem->func_num==2){
        arr[curItem->value]++;
        
    }else{       
curItem->next?curItem=curItem->next:NULL;}
        update_flag=1;
        Enc_tick=0;
            break;
        
            case -1:
        if(curItem->func_num==2){
         arr[curItem->value]--;
    }else{
    curItem->prev?curItem=curItem->prev:NULL;}
        update_flag=1;
        Enc_tick=0;
        break;
        }        
        if(btn1state==1){           
     update_flag=1;
        if(curItem->Handler){(*curItem->Handler)();}
else {curItem->ok?curItem=curItem->ok:NULL;
        }
    }
    if(update_flag){
    Serial.println(curItem->name);
        Serial.println(arr[1]);
        Serial.println(arr[2]);
        update_flag=0;
    }    
}

 

Вот структура:

typedef struct  menuItem
{   char *name; //первые 4 пункта понятны должны быть
    struct menuItem *prev;
    struct menuItem *next;
    struct menuItem *ok;
    byte func_num; //функциональное назначение: 1 проходное меню, 2 меню из которого меняются переменные, 3 вызываем обработчик
    void (*Handler)(); //название обработчика
    int value; //в моем случае номер элемента массива с переменными
} menuItem;

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Kakmyc пишет:

Вот вся функция меню.

НУ, в таком случае, всё, как я сказал

ЕвгенийП пишет:
в таком случае при выходе из функции она будет забывать всё (например, какой элемент сейчас выбран) и каждый раз рисоваться с чистого листа.

А также, готовьтесь к неожиданным ниоткуда возникающим и исчезающим в никуда глюкам. Это я Вам гарантирую.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

ЕвгенийП пишет:

А также, готовьтесь к неожиданным ниоткуда возникающим и исчезающим в никуда глюкам. Это я Вам гарантирую.

 

Достаточно наглядный тест будет ?

void stress(){
    byte stress_byte[1500];
    for(int i=0;i<1500;i++)stress_byte[i]=random(255);
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Я не понимаю, о чём Вы.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

ЕвгенийП пишет:

Я не понимаю, о чём Вы.

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

Потому, что по коду я ничего подобного не вижу

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Как повезёт, ибо в этой функции Вы память как забьёте, так и освободите. Но если она пропорет кучу, то сломается, а если нет - то нет.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

ЕвгенийП пишет:

Как повезёт, ибо в этой функции Вы память как забьёте, так и освободите. Но если она пропорет кучу, то сломается, а если нет - то нет.

 

В общем , размер кучи 1642байта.

При размере массива 1600байт, все работает в штатном режиме.

При 2000байт, меню работает в штатном режиме, размер переменных пляшет (они глобальные).

 

Ни в одном из случаев ваши предсказания работать не желают.

Что я делаю не так ?

Как смоделировать процесс ?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Kakmyc пишет:

Ни в одном из случаев ваши предсказания работать не желают.

Вы, знаете, я далёк от мысли с Вами спорить и что-то Вам доказывать. Уже второй день я Вам говорю, что так не делается, а Вы мне доказываете обратное. Да, не вопрос, делайте как хотите, мне-то собственно что?

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

#import "menu1.h"

#import "menu2.h"

#import "menu3.h"....

....

....

int x1 =1;

int y1=8;

int sizeX=50;

int sizeY=52;

int x2....

int y2...

....

У меня очередной вопрос. Как сюда

  const char * itemText;  // Название данного элемента (тут может быть не текст, а адрес картинки. Функция show знает, что с этим делать) строка кода из примера Евгения

воткнуть адрес картинки. tft.pushImage(1, 8, 50, 52, menu1); Я так понимаю мой адрес картинки это мои координаты, размер и название (1, 8, 50, 52, menu1);

Функция show знает, что с этим делать

Serial.println(itemText);

меняем на tft.pushImage(x1, y1, sizeX, sizeY, file);

Не понятно как быть с параметром file, как прописывать.

И скорее всего нужно менять конструктор. Сюда мне вообще страшно лезть...

 SMenuItem(const char * const _itemText, SMenuItem * _prev = nullptr, SMenuItem * _parent = nullptr) {
    itemText = _itemText;
    prev = _prev;
    parent = _parent;
    children = nullptr;
    next = nullptr;

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

Kakmyc пишет:

Просто копируем динамическую структуру в статическую и работаем только со статической.

Кактус. покажите мне в коде место. где вы "копируете динамическую структуру в статическую" ? я такого не вижу, вижу только сохранение ссылки. а не самой структуры.

Мне тоже кажется, что ваш код заведомо глючный. Сохранение ссылки на уничтоженную динамическую переменную будет работать только если участок памяти, где лежала переменная - не меняется между вызовами функции. А это означает, вообще-то, что эта память вам между вызовами не нужна и весь этот "цирк с конями" - создание кучи менюшек при входе в функцию и удаление при выходе - никому не нужен.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:
будет работать только если участок памяти, где лежала переменная - не меняется между вызовами функции.
Да, я это уже писал об этом в #81. Если бы человек спросил, я бы и пример привёл в котором она сваливается. Но, человек пришёл сюда не учиться а спорить и свою правоту доказывать. В добрый путь :-)

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

Люди, подскажите плз как переделать конструктор под графическое меню.

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

Туцик пишет:

Люди, подскажите плз как переделать конструктор под графическое меню.

Туцик, вы уже спрашивали -  нет никакой разницы между "графическим" и "текстовым" меню.

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

теоретически да. Но практически нет. Вот и спрашиваю как переделать конструкто под графическое меню. Мне нужно каждый пункт меню т.е файл картинки отобразить в нужной точке. соотвевтсвенно вместо пункта Menu1 нужно прописать координаты x,y, размер картинкиХ, размер картинкиY и сам файл с картинкой в конструктор. вот и спрашиваю как это сделать?

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

у вас все пункты меню будут рисованные, например в виде иконок? - или просто текст красивым шрифтом на цветном фоне?

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

Если же меню - это красивый текст на графическом экране - то это, вообще-то, обычное текстовое меню

Туцик
Туцик аватар
Offline
Зарегистрирован: 31.03.2020

А я Вам о чем?

Вот картинка моего меню, то, что и хочу получить.

https://ibb.co/m8DrRs3