Italian Matrici 'flessibili'

LordZenzo

Well-Known Member
Licensed User
Longtime User
una domanda sulle matrici
se dichiaro
Dim job(10) As HttpJob
ho 11 elementi
se dichiaro
Dim job() As HttpJob
dovrei poter avere tutti gli elementi che voglio, ma come crearli?
perché poi se nel codice ho
job(12).Initialize("Crisorse",Me)
mi restituisce errore, e potrei starci, ma come faccio a dirgli che deve creare il tredicesimo elemento?
 

LucaMs

Expert
Licensed User
Longtime User
A parte che, purtroppo:
Dim job(10)...
ha 10 elementi, da 0 a 9, a differenza di altri linguaggi...

tu puoi reinizializzare un array (anche se l'hai dichiarato job(10) anziché job() ), però perdi tutto il contenuto precedente.

Quindi, o conosci "al priore di Anzio" la quantità di oggetti che dovrà contenere, oppure meglio usare una List (questo in linea generale).

Ora ho fuso, è tutto il giorno che scrivo su qualunque argomento, quindi non ricordo un tubo riguardo gli HttpJob. Mi sembra che ci sia una classe creata da Erel per metterli in coda ed eliminarli al momento opportuno... mo guardo e poi svengo nel letto :p
 

LucaMs

Expert
Licensed User
Longtime User
Boh, non la trovo.

Sono "vagamente" stanco; cercala tu oppure cerca di implementare una cosa simile, usando una List o meglio ancora una Map.
Nella map potresti usare come chiave il nome del tuo httpjob e come valore l'oggetto httpjob stesso.

Scusa ma sto crollando :(:)
 

LucaMs

Expert
Licensed User
Longtime User
No, il problema (in generale, adesso non ricordo esattamente come funzionino gli httpjob) non è lo stesso, perché sia con le List che con le Map puoi aggiungere e togliere elementi quando ti pare, conservando i precedenti immessi.
 

LucaMs

Expert
Licensed User
Longtime User
B4X:
Process_Globals

Dim mapHJobs As Map

'...

mapHJobs.Initialize


Sub AddHJob(HJobName As String)
   Dim HJob As HttpJob
   HJob.Initialize(HJobName, Me)
   mapHJobs.Put(HJobName, HJob)
End Sub

Sub JobDone (job As HttpJob)
'...
    mapHJobs.Remove(job.JobName)
End Sub
 
Last edited:

LordZenzo

Well-Known Member
Licensed User
Longtime User
B4X:
globals 
Dim job(100) As HttpJob

Sub AvviaJob(nome As String,htp As String)
Dim    i As Int =0
    Do Until i>99
        If job(i).IsInitialized Then
            If job(i).JobName<>"" Then
                i=i+1
            Else
                job(i).Initialize(nome,Me)   
                job(i).Download(htp)  
                Return
            End If
        Else      
                job(i).Initialize(nome,Me)   
                job(i).Download(htp)  
                Return
        End If
    Loop  
End Sub

Sub JobDone(jobd As HttpJob)
   If jobd.Success = False Then
     Log("Error: " & job(0).ErrorMessage)
    Return
   Else
      Select Case jobd.JobName
        Case "InsertName"
           ........
    End Select
   End If 
   jobd.Release
   jobd.JobName=""
End Sub
 

LucaMs

Expert
Licensed User
Longtime User
Capisco che non ti piacciano le Map perché non le conosci e sei abituato agli array, ma guarda quanto è più semplice e conciso il codice con la Map.

Cmq, se vuoi usare il tuo codice:

1) non potresti passare l'indice alla routine AvviaJob? In questo modo eviteresti di scorrere tutto l'array;
2) penso che tu abbia volutamente sovraddimensionato l'array (100) non conoscendo a priori quanti ne userai; immagina di creare un server e non sai quanti utenti avrai contemporaneamente: che fai, dim Utenti(1000000) - un milione?
3) non ho capito perché inizializzi il job in due posti diversi, a seconda di due condizioni diverse: se non è inizializzato, lo fai ma lo fai anche se il suo nome è una stringa nulla (?)
Ah si, ho capito adesso, vedendo le ultime righe di Jobdone; allora puoi usare:

If Not(Job(i).IsInitialized) Or Job(i).JobName = "" Then
' qui inizializzi il job

perché la seconda condizione non viene esaminata se già la prima è vera.

Cmq, non farti spaventare da cose nuove, se queste sono semplici. Le map non sono certo complicate:

Le dichiari e inizializzi (una volta per tutte)
Usi Put per aggiungere un elemento (se esiste già viene sovrascritto)
Usi Get per ottenere l'elemento.

Oltre a Get per ottenere l'elemento, puoi usare anche GetValueAt(Indice) ed in questo modo è proprio identico ad un Array.

Hanno il vantaggio che sia la chiave (che corrisponde un po' all'indice dell'Array) sia il valore (che ovviamente corrisponde al valore dell'Array) possono essere di qualunque tipo, a differenza degli Array il cui indice è obbligatoriamente un numero.

Puoi eliminare un elemento, risparmiando memoria, cosa che non puoi fare con un array.

Se, ad esempio, anziché un numero usi un testo come indice (ad esempio, i cognomi e i valori sono oggetti che contengono tutti i dati che corrispondono a quel cognome) puoi vedere le la map contiene quel cognome, usando ContainsKey.

Etc.

Insomma, le map sono molto più potenti degli array e facilissime da usare!
 
Last edited:

LordZenzo

Well-Known Member
Licensed User
Longtime User
Insomma, le map sono molto più potenti degli array e facilissime da usare!
e lo so, uso anche map di map:)
Cmq, non farti spaventare da cose nuove, se queste sono semplici
no no, ti do ragione in pieno
If Not(Job(i).IsInitialized) Or Job(i).JobName = "" Then
' qui inizializzi il job

perché la seconda condizione non viene esaminata se già la prima è vera.
di solito lascio separati gli 'OR' perché in un secondo momento posso cambiare il comportamento senza cambiare altro (per abitudine)

in effetti non servirebbe inizializzare se gia inizializzato, potrei solo cambiare nome e http
1) non potresti passare l'indice alla routine AvviaJob? In questo modo eviteresti di scorrere tutto l'array;
no il senso è, trova il primo job libero ed usalo, prima di fare questa routine usavo un indice diverso per ogni azione, ed ero arrivato a 18 avendo fatto forse il 10% del gioco, ma so che non ci sono mai più di tre o quattro richieste contemporanee, anche perche ogni volta che serve una richiesta dal server metto una 'pausa' al gioco ossia impedisco che il giocatore faccia richieste a catena
non ho usato le map perché avevo già fatto buona parte del lavoro e cambiare a map dovrei cambiare molto codice....ma credo che farò il cambio
 
Top