El lienzo es genial. - página 90

 
Nikolai Semko #:

Un lienzo es un objeto al que se vincula una matriz de píxeles. El recurso es responsable de vincular esta matriz de píxeles (véase bool CCanvas::Create())
Es una mala práctica borrar y volver a crear un lienzo todo el tiempo.
Es una buena práctica crear un lienzo cuando se necesita y borrarlo cuando ya no se necesita, por ejemplo, al final del programa.

Una vez creado un objeto lienzo, puedes limpiarlo, sobrescribir la matriz de píxeles en cada fotograma, cambiar el tamaño del lienzo y moverlo a donde quieras.

Gracias, me ha quedado un poco más claro, pero no todo. ¿Entiendo correctamente que si después de crear un objeto canvas, simplemente borro el objeto del gráfico usando ObjectDelete(), entonces el array de pixels ligado a este objeto permanece intacto y... Cuando vuelvo a crear un nuevo objeto canvas con un nombre diferente, se crea una nueva matriz de píxeles en la memoria y, por tanto, teóricamente, ¿es posible llenar toda la memoria?

¿O la antigua matriz de píxeles es simplemente re-ligada al último objeto-lienzo creado cada vez (porque es y sólo con él que todas las funciones de la instancia usada de la clase-lienzo empiezan a trabajar)?

 
leon_17 #:

Gracias, me ha quedado un poco más claro, pero no del todo. ¿Entiendo correctamente que si después de crear un objeto canvas, simplemente borro el objeto del gráfico usando ObjectDelete(), entonces el array de píxeles ligado a este objeto permanece intacto y.... Cuando vuelvo a crear un nuevo objeto canvas con un nombre diferente, se crea una nueva matriz de píxeles en memoria, y por lo tanto, teóricamente, es posible llenar toda la memoria?

Por supuesto, los recursos sin propietario se multiplicarán.

leon_17 #:

O todavía la vieja matriz de píxeles es simplemente re-ligada al último objeto kanvas creado cada vez (porque es y sólo con él que todas las funciones de la instancia utilizada de la clase kanvas comienzan a trabajar)

Tu imaginación es magnífica. Te envidio. A mi no se me hubiera ocurrido tal cosa. :))

Sin embargo, si guardas el nombre de un recurso sin propietario, puedes volver a vincularlo a un nuevo objeto bitmap. Pero esto es del campo de la esquizofrenia.

 
Nikolai Semko #:

Sin embargo, si guardas el nombre de un recurso sin propietario, puedes volver a vincularlo a un nuevo objeto de mapa de bits. Pero esto es del campo de la esquizofrenia.

Retiro mis palabras. Creo que he encontrado un caso en el que algo así podría ser útil.
 
Nikolai Semko #:
Retiro lo dicho. Creo que he encontrado un caso en el que esto podría ser útil.

Gracias, sólo quería entender qué pasa en memoria si usas ObjectDelete () en lugar de Destroy (). Y me he dado cuenta de que en ese caso los recursos gráficos (arrays de píxeles sin propietario y demás) se multiplicarán si cada vez se genera un nuevo nombre para un nuevo objeto canvas.

¿Y si utilizo ObjectDelete(), pero luego creo un objeto canvas con el mismo nombre, la matriz de píxeles será vieja o seguirá siendo nueva?

p.d. las preguntas son probablemente estúpidas, pero lo necesito para entender el mecanismo del canvas


.

 
leon_17 #:

Gracias, sólo quería entender qué pasa en memoria si se usa ObjectDelete () en lugar de Destroy (). Y me di cuenta de que los recursos gráficos (matrices de píxeles sin propietario y algo más) se multiplicarán si se genera un nuevo nombre para un nuevo objeto canvas cada vez.

Es fácil comprobarlo escribiendo un simple script
 
Nikolai Semko #:
Es fácil de comprobar escribiendo un simple script.

¿Puede decirme cómo?

 
leon_17 #:

¿Puede decirme cómo?

así:

#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);
   }
}

y mira el comentario:

!!! después de ejecutar este script, no olvides recargar el terminal para liberar memoria para recursos huérfanos.


 
Nikolai Semko #:

así:

y mira el comentario:

!!! después de ejecutar este script, no olvides recargar el terminal para liberar memoria para recursos huérfanos.


¡Muchas gracias por tu ayuda! No he trabajado antes con la memoria de esta manera, lo probaré.
¡Gracias por la pista de que los recursos huérfanos se borran al recargar el terminal! Muchas cosas así no son obvias para mí todavía.

p.d. ¡todo en este ejemplo es perfecto! Hay algo que mirar, algo que pensar y una oportunidad para experimentar... El código es corto.

 
Me puedes decir más, si se usa kanvas en un Expert Advisor, ¿es necesario ejecutar Destroy() al quitar el Expert Advisor del gráfico y cerrar el terminal? Tampoco se como comprobar esto. Me refiero a un lienzo de trabajo con un objeto fijo. Ahí la diferencia de memoria está dentro del error (si ejecutas y no ejecutas Destroy( ).
 
leon_17 quitar el Expert Advisor del gráfico y cerrar el terminal? Tampoco se como comprobar esto. Me refiero a un lienzo de trabajo con un objeto fijo. Ahí la diferencia de memoria está dentro del error (si ejecutas y no ejec utas Destroy( ).

No hace falta que lo hagas. En el destructor del Canvas se ejecuta automáticamente:

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