Iniziamo con l'esempio pratico:
preloadLoadVars
e il fla dell'esempio:
preloadLoadVars.zip
Fino ad oggi non avevo mai cercato di trovare un modo per creare un preload di dati dinamici caricati dal server!
Avevamo sempre utilizzato infatti l'evento(metodo) onLoad() di LoadVars per verificare semplicemente l'avvenuto caricamento di dati dal server, il problema a prima vista insormontabile era quello che il numero totale di bytes da caricare sembrava indefinibile!
Leggendo la guida di flash MX invece mi hanno stuzzicato queste parole a proposito del metodo getBytesTotal() di LoadVars:
Metodo;
restituisce il numero totale di byte che vengono scaricati mediante un'operazione load o sendAndLoad. Il metodo getBytesTotal restituisce undefined se non è in corso alcuna operazione load o se l'operazione load non è stata ancora avviata. Questo metodo restituisce undefined anche quando il numero totale di byte non può essere determinato, ad esempio nel caso in cui lo scaricamento è cominciato ma il server non ha trasmesso un HTTP in formato Content-Length.
Questo significa che dobbiamo impostare un'opzione nell'header della pagina server, e in particolare proprio il Content-Length dimensionato con il numero totale di bytes da caricare!
Questo passo l'ho risolto grazie al grande Bubu Sette Sette moderatore del forum php uilizzando delle funzioni di php che ci permettono di calcolare la dimensione dell'output, e alla funzione Header che ci permette appunto di impostare il testo dell'header della pagina!
Grazie anche al Mitico Negatyve che mi ha dato la conferma che questo era possibile!(nonstante qualcuno volesse metterci i bastoni tra le ruote
)
Per chi non lo sapesse l'header sarebbe proprio l'intestazione di ogni pagina web dove sono specificati vari parametri e opzioni che a noi restano invisibili durante la navigazione ma in realtà sono sempre presenti in testa alla pagina!
Premetto che questo metodo utilizzerà php insieme ad AS, anche se credo che pure con altri linguaggi server/side si possa fare ugualmente quello di cui parleremo più avanti in questa pillola (basterebbe conoscerli
)
A questo punto riassumiamo un pò:
Per fare un preload ci servono due parametri, bytesTotali e bytesCaricati!
Grazie a php e a quello che abbiamo detto riusciamo a far ricevere a flash all'inizio della comunicazione il numero totale di bytes grazie a getBytesTotal()!
Il problema a questo punto è:
Come facciamo a sapere il momento in cui inizia la comunicazione?
E' semplice dalla guida si dice che getBytesTotal() restituisce undefined fino a quando l'operazione di load non è avviata quindi controllando lo stato di getBytesTotal() grazie ad un semplice setInterval abbiamo esattamente il momento in cui inizia la comunicazione!
A questo proposito ho creato due metodi di LoadVars (uno pubblico e uno privato) che mi hanno permesso di creare l'evento onStart() che al contrario di onLoad() si verifica all'inizio del flusso dei dati! sempre però che l'header della pagina è stato impostato correttamente!
codice:
// metodo pubblico da richiamare dopo le istruzioni di load o sendAndLoad
LoadVars.prototype.checkHeader = function() {
this.idHeader = setInterval(this, "getTotal", 1);
};
LoadVars.prototype.getTotal = function() {
if (this.getBytesTotal() != undefined) {
this.onStart();
clearInterval(this.idHeader);
}
};
grazie a questi semplici prototipi della superClasse LoadVars noi possiamo a questo punto impostare il nostro preload utilizzando il nuovo evento onStart() di LoadVars:
codice:
this.preload._visible = false;
result = new LoadVars();
result.load("prova.php");
/* attiviamo il listener creato da noi che verifica l'inizio del
flusso dei dati */
result.checkHeader();
/*Scrivo le istruzioni del nostro preload nell'evento onStart()
cioè all'inizio del flusso dei dati */
result.onStart = function() {
/* setto una variabile con i ms trascorsi dall'inizio della riproduzione del filmato */
this.startTime = getTimer();
_root.textLabel1.text = "inizio flusso";
/* mi salvo nel mio preload un riferimento al nostro oggetto
LoadVars per poterne utilizzare al suo interno i suoi metodi */
_root.preload.loadVarsObject = this;
_root.preload.totalBytes = this.getBytesTotal();
_root.preload.onEnterFrame = function() {
this.loadedBytes = this.loadVarsObject.getBytesLoaded();
this.percent = this.loadedBytes/this.totalBytes*100;
this.barra._xscale = this.percent;
this._visible = true;
this.text1.text = "Percentuale: "+Math.round(this.percent)+"%";
this.text2.text = "Bytes caricati: "+this.loadedBytes;
if (this.loadedBytes == this.totalBytes) {
delete this.onEnterFrame;
}
};
};
// Scrivo le istruzioni che si verificano alla fine del flusso dei dati
result.onLoad = function() {
_root.textLabel2.text = "fine flusso, bytes scaricati: "+this.getBytesLoaded()+" in "+(getTimer()-this.startTime)+"ms";
};
A questo punto andiamo a spiegare alla meno peggio come impostare la nostra pagina php che mi ha ispirato Negatyve infatti per flussi di dati brevi il preload forse non avrebbe neanche senso:
Codice PHP:
$myresult="result=";
ob_start(); // qua inizio il conteggio dei bytes dell'output
for($a=0;$a<10000;$a++)
$myresult.="riga numero $a";//imposto la variabile di output
echo $myresult; //stampo il risultato che riceverà flash è solo una dimostrazione quindi non fate caso al contenuto
header("Content-Length: ".ob_get_length()); //qui imposto l'header con il numero di bytes totali
ob_end_flush();
Spero di essere stato abbastanza chiaro sono cmq bene accetti consigli e commenti!