La tela è forte! - pagina 90

 
Nikolai Semko #:

Un canvas è un oggetto a cui è legato un array di pixel. La risorsa è responsabile del legame di questo array di pixel (vedere bool CCanvas::Create())
È una cattiva pratica cancellare e ricreare una tela in continuazione.
È una buona pratica creare una tela quando è necessaria e cancellarla quando non è più necessaria, ad esempio alla fine del programma.

Una volta creato un oggetto canvas, è possibile ripulirlo, sovrascrivere l'array di pixel a ogni fotogramma, ridimensionare il canvas e spostarlo dove si vuole.

Grazie, è diventato un po' più chiaro, ma non tutto. Ho capito bene che se dopo aver creato un oggetto canvas, cancello semplicemente l'oggetto dal grafico usando ObjectDelete(), allora la matrice di pixel legata a questo oggetto rimane intatta e... Quando creo nuovamente un nuovo oggetto canvas con un nome diverso, viene creato un nuovo array di pixel in memoria e quindi, teoricamente, è possibile riempire l'intera memoria?

Oppure il vecchio array di pixel viene semplicemente rilegato all'ultimo oggetto canvas creato ogni volta (perché è solo con esso che tutte le funzioni dell'istanza utilizzata della classe canvas iniziano a funzionare)?

 
leon_17 #:

Grazie, è diventato un po' più chiaro, ma non tutto. Ho capito bene che se dopo aver creato un oggetto canvas, cancello semplicemente l'oggetto dal grafico usando ObjectDelete(), l'array di pixel legato a questo oggetto rimane intatto e.... Quando creo di nuovo un nuovo oggetto canvas con un nome diverso, viene creato un nuovo array di pixel in memoria e quindi, teoricamente, è possibile riempire tutta la memoria?

Ovviamente le risorse senza proprietario si moltiplicheranno.

leon_17 #:

Oppure il vecchio array di pixel viene semplicemente rilegato all'ultimo oggetto kanvas creato ogni volta (perché è solo con esso che tutte le funzioni dell'istanza utilizzata della classe kanvas iniziano a funzionare).

La tua immaginazione è superba. Ti invidio. Non avrei mai pensato a una cosa del genere. :))

Comunque, se salvate il nome di una risorsa senza proprietario, potete rilegarla a un nuovo oggetto bitmap. Ma questo viene dal campo della schizofrenia.

 
Nikolai Semko #:

Tuttavia, se si salva il nome di una risorsa priva di proprietario, è possibile reinderizzarla a un nuovo oggetto bitmap. Ma questo viene dal campo della schizofrenia.

Ritiro le mie parole. Credo di aver trovato un caso in cui una cosa del genere potrebbe essere utile.
 
Nikolai Semko #:
Mi rimangio tutto. Penso di aver trovato un caso in cui questo potrebbe essere utile.

Grazie, volevo solo capire cosa succede in memoria se si usa ObjectDelete () invece di Destroy (). E mi sono reso conto che in questo caso le risorse grafiche (array di pixel senza proprietario e quant'altro) saranno moltiplicate se ogni volta viene generato un nuovo nome per un nuovo oggetto canvas.

E se uso ObjectDelete(), ma poi creo un oggetto canvas con lo stesso nome, l'array di pixel sarà vecchio o ancora nuovo?

p.s. le domande sono probabilmente stupide, ma mi servono per capire il meccanismo del canvas


.

 
leon_17 #:

Grazie, volevo solo capire cosa succede in memoria se si usa ObjectDelete () invece di Destroy (). E mi sono reso conto che le risorse grafiche (array di pixel senza proprietario e altro) si moltiplicano se ogni volta viene generato un nuovo nome per un nuovo oggetto canvas.

È facile verificare questo aspetto scrivendo un semplice script
 
Nikolai Semko #:
È facile da controllare scrivendo un semplice script.

Può dirmi come fare?

 
leon_17 #:

Può dirmi come?

come questo:

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

e guardate il commento:

Dopo aver eseguito questo script, non dimenticate di ricaricare il terminale per liberare memoria per le risorse orfane.


 
Nikolai Semko #:

come questo:

e guardate il commento:

Dopo aver eseguito questo script, non dimenticate di ricaricare il terminale per liberare memoria per le risorse orfane.


Grazie mille per l'aiuto! Non ho mai lavorato con la memoria in questo modo, lo proverò.
Grazie per il suggerimento che le risorse orfane vengono cancellate quando si ricarica il terminale! Molte di queste cose non sono ancora ovvie per me.

p.s. Tutto in questo esempio è perfetto! C'è qualcosa da guardare, qualcosa su cui riflettere e un'opportunità per sperimentare... Il codice è breve.

 
Se kanvas viene utilizzato in un Expert Advisor, è necessario eseguire Destroy() quando si rimuove l'Expert Advisor dal grafico e si chiude il terminale? Non so nemmeno come verificare questo aspetto. Intendo un canvas funzionante con un oggetto fisso. La differenza di memoria è all'interno dell'errore (se si esegue e non si esegue Destroy().
 
leon_17 rimuove l'Expert Advisor dal grafico e si chiude il terminale? Non so nemmeno come verificare questo aspetto. Intendo un canvas funzionante con un oggetto fisso. La differenza di memoria è all'interno dell'errore (se si esegue e non si esegue Destroy().

Non è necessario. Nel distruttore della tela viene eseguito automaticamente:

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