Canvas - это круто! - страница 90

 
Nikolai Semko #:

Канвас это объект, к которому привязан массив пикселей. За привязку этого массива пикселей отвечает Ресурс (см. функцию bool CCanvas::Create())
Плохая практика все время удалять и пересоздавать канвас. 
Хорошая практика создать канвас, когда он нужен и удалить его, когда он больше не будет нужен, например в конце программы. 

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

Спасибо, стало немного понятнее, но не все. Я правильно понимаю, что если после создания канвас-объекта, я просто удаляю объект с графика с помощью ObjectDelete(), то массив пикселей привязанный к этому объекту остается нетронутым и... когда я снова создаю новый канвас-объект уже с другим именем, в памяти создается и новый массив пикселей, и таким образом теоретически можно забить всю память?

Или все-таки старый массив пикселей каждый раз просто перепривязывается к последнему созданному канвас-объекту (ведь именно и только с ним начинают работать все функции используемого экземпляра канвас-класса)

 
leon_17 #:

Спасибо, стало немного понятнее, но не все. Я правильно понимаю, что если после создания канвас-объекта, я просто удаляю объект с графика с помощью ObjectDelete(), то массив пикселей привязанный к этому объекту остается нетронутым и... когда я снова создаю новый канвас-объект уже с другим именем, в памяти создается и новый массив пикселей, и таким образом теоретически можно забить всю память?

конечно, бесхозные ресурсы будут множиться.

leon_17 #:

Или все-таки старый массив пикселей каждый раз просто перепривязывается к последнему созданному канвас-объекту (ведь именно и только с ним начинают работать все функции используемого экземпляра канвас-класса)

с фантазией у вас все просто супер. Аж завидно. До такого бы я не додумался. :))

впрочем, если сохранить имя бесхозного ресурса, то можно повторно привязать его к новому битмап объекту. Но это из области шизофрении. 

 
Nikolai Semko #:

впрочем, если сохранить имя бесхозного ресурса, то можно повторно привязать его к новому битмап объекту. Но это из области шизофрении. 

Беру свои слова обратно. Вроде нашел случай, когда такое могло бы пригодиться.
 
Nikolai Semko #:
Беру свои слова обратно. Вроде нашел случай, когда такое могло бы пригодиться.

Благодарю, я просто хотел понять, что происходить в памяти, если вместо Destroy() использовать ObjectDelete(). И понял, что в таком случае графические ресурсы (бесхозные пиксельные массивы и что-то там еще) будут множиться, если каждый раз для нового канвас объекта генерировать новое имя. 

А если использовать  использовать ObjectDelete(), но затем создать канвас-объект с тем же именем, пиксельный массив старый будет или все равно новый?

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


  

 
leon_17 #:

Благодарю, я просто хотел понять, что происходить в памяти, если вместо Destroy() использовать ObjectDelete(). И понял, что графические ресурсы (бесхозные пиксельные массивы и что-то там еще) будут множиться, если каждый раз для нового канвас объекта генерировать новое имя.   

Это ж легко проверить, написав простенький скрипт
 
Nikolai Semko #:
Это ж легко проверить, написав простенький скрипт

Подскажите как?

 
leon_17 #:

Подскажите как?

например так:

#define protected public
#include <Canvas\Canvas.mqh>
#undef protected

void OnStart() {
   while(!IsStopped()) {
      int Width =(ushort)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);  // получаем Ширину окна
      int Height=(ushort)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); // получаем Высоту окна
      CCanvas canvas;
      if(!canvas.CreateBitmapLabel("MyCanva"+string(rand()),0,0,Width,Height,COLOR_FORMAT_ARGB_NORMALIZE)) {
         Print("Error creating canvas: ",GetLastError());
      }
      canvas.FillRectangle(rand()%Width/2,rand()%Height/2,Width/2+rand()%Width/2,Height/2+rand()%Height/2,ARGB(128,rand()%255,rand()%255,rand()%255));
      canvas.Update();
      Comment("Задействовано памяти: - " + string(TerminalInfoInteger(TERMINAL_MEMORY_USED))+ " Mb");
      Sleep(500);
      ObjectDelete(canvas.m_chart_id,canvas.m_objname);
   }
}

и смотрим на коммент:

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


 
Nikolai Semko #:

например так:

и смотрим на коммент:

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


Большое спасибо за помощь! Не работал так с памятью раньше, буду тестировать.
За подсказку, что бесхозные ресурсы удаляются при перезагрузке терминала, отдельное спасибо! Многие подобные вещи для меня еще пока не очевидны.

p.s. в этом примере прекрасно всё! Есть на что посмотреть, над чем подумать и есть возможность поэкспериментировать... благо код короткий.

 
Подскажите еще, если канвас используется в советнике, нужно ли выполнять  Destroy(), при удалении советника с графика и при закрытии терминала? Тоже не знаю как это проверить. Имеется ввиду рабочий канвас с закрепленным объектом. Там разница в памяти в пределах погрешности (если выполнять и не выполнять Destroy().
 
leon_17 #:
Подскажите еще, если канвас используется в советнике, нужно ли выполнять  Destroy(), при удалении советника с графика и при закрытии терминала? Тоже не знаю как это проверить. Имеется ввиду рабочий канвас с закрепленным объектом. Там разница в памяти в пределах погрешности (если выполнять и не выполнять Destroy().

Не нужно. В деструкторе Canvas'а он автоматически отрабатывает:

                    ~iCanvas() { Destroy(); ChartRedraw();};