Acquista i nostri libri consigliati su Amazon.it
+ Rispondi al messaggio
Visualizzazione dei risultati da 1 a 9 su 9

[OOP] Implements e Callback

  1. #1
    L'avatar di @Alex
    @Alex non è in linea Moderatore Globale
    Quesito un po fuori standard, sulla logica OOP.
    Ho 3 Classi + 1 Interfaccia:
    1) cBuilder
    2) cCollection
    3) cItem
    4) IEventsNotifier

    La [cBuilder] gestisce il progetto, istanzia la [cCollection] come ROOT, ed espone l'interfaccia [IEventsNotifier]
    La [cCollection] è una classe di gestione di una Collection di [cItem] e dichiara l'istanza di [IEventsNotifier] per effettuare il CallBack a [cBuilder]
    La [cItem] è una classe oggetto gerarchico che a sua volta istanzia [cCollection] sempre con il riferimento in callback a cBuilder
    L'interfaccia [IEventsNotifier] espone 3 Sub che sono 3 Eventi
    [ItemAfterInsert]/[ItemBeforeDelConfirm]/[ItemAfterDelConfirm]

    [cBuilder]
     └---> [cCollection]
                 └--1--> [cItem]
                 │           └--> [cCollection]
    	         │				        └-->[cItem]
    	         │
     	         └--1--> [cItem]
     
    ecc...
    
    Questo in quanto gli eventi di cui sopra, gestiti dalle varie istanze di classe [cCollection] a tutti i Livelli gerarchici... devono generare azioni sulla [cBuilder]
    Ora se io elimino un [cItem] che ha figli, quindi che ha una [cCollection] mi vengono generati tante invocazioni alla [cBuilder] quante sono i Livelli gerarchici, peraltro in ordine inverso ovviamente in quanto l'eliminazione è ricorsiva e prima di eliminare scende di livello... quindi si comporta come un LiFo.
    Vorrei condizionare la gestione dei Reminder a seconda del Livello, cosa che ora faccio invocando 2 metodi diversi [Remove] sulla 1° Istanza e [RemoveDeep] poi a seguire sui figli.
    La cosa mi piace poco... ma non riesco a trovare un metodo per andare a definire sempre a livello di interfaccia la possibilità di modificare gli eventi da generare...
    Ultima modifica di @Alex; 10-06-2021 12:03 
    ℹ️ Leggi di più su @Alex ...

  2. #2
    L'avatar di @Alex
    @Alex non è in linea Moderatore Globale
    Se mi rileggo non mi sono capito nemmeno io...!
    Al momento ho inserito nella [cBuilder] una Proprietà di EventFiring in cui memorizzo la Key della Classe che ha generato la FirstCall per inibire le successive, ed ovviamente la resetto a fine evento.

    Soluzione che non mi soddisfa proprio...
    Ultima modifica di @Alex; 11-06-2021 09:55 
    ℹ️ Leggi di più su @Alex ...

  3. #3
    Quote Originariamente inviato da @Alex Visualizza il messaggio
    Se mi rileggo non mi sono capito nemmeno io...!
    Non avevo il coraggio di dirlo.
    Quote Originariamente inviato da @Alex Visualizza il messaggio
    ... ed ovviamente la resetto a fine evento.
    Ovviamente. Dopo questa precisazione ... continuo a non capire ma il motivo è che OOP per me è l'onomatopea di un salto. Basta, su questo thread ho già detto troppo.

  4. #4
    L'avatar di @Alex
    @Alex non è in linea Moderatore Globale
    Sicuramente è argomento poco usuale... ed infatti sono in difficoltà, perchè la logica è un poco sfuggevole almeno per me...
    ℹ️ Leggi di più su @Alex ...

  5. #5
    Sgrubak non è in linea Scribacchino
    Quote Originariamente inviato da @Alex Visualizza il messaggio
    Se mi rileggo non mi sono capito nemmeno io...!
    Mah... Io il filo l'ho più o meno seguito. Quel che mi sfugge è perché non ti piace... (Ricordiamo che son pivello autodidatta, eh! )

    Un alternativa che mi viene in mente sarebbe quella di un parametro Boolean opzionale ad un Remove unico, così da effettuare la chiamata ai callback se e soltanto se il parametro è esplicitato. Ma sarebbe praticamente la stessa cosa che hai già fatto tu.

    Quindi discriminare tra un cCollection.Remove(cItem) e un cCollection.Remove(cItem, True)

    Se ho scritto dabbenaggini, non risparmiatevi così continuo a studiare

  6. #6
    L'avatar di @Alex
    @Alex non è in linea Moderatore Globale
    Il problema è che siamo in un sistema gerarchico ricorsivo... quindi i parametri in questi casi si rincorrono... e non è così banale capire se l'istanza di Classe che sta eseguendo il codice sia la Prima o la seconda...
    Ad esempio quando Muovo un Nodo Gerarchico da una posizione ad un'altra, essendo inseriti in Collection, devo effettuare un REMOVE ed un ADD, il REMOVE in questo caso non è ricorsivo in quanto mi porto appresso anche i figli...
    Se invece voglio ELIMINARE il Nodo ed i figli inclusi dai vari riferimenti delle collection, la cosa si complica in quanto devo generare ricorsione passando appunto i parametri...

    Ti faccio un esempio pratico, anche se credo non sia facile da capire.
    Tralasciamo la gestione errori...
    Sono 2 Metodi della stessa classe [cCollection] che contiene [cNode]
    Ogni [cNode] istanzia anche una [cCollection] chiamata [Childs]

    Quindi prendendo un Nodo, nella sua Colletion di appartenenza chiamo Remove(Me) per eliminare il Nodo dalla Collection... verifico se ha figli in quel caso richiamo il metodo RemoveChilds, ma dell'istanza Childs... che a sua volta richiama sempre il metodo Remove... e via in gerarchia.
    In questo cas se ho N figli, come vedi mi si generano N(x2 in quanto sono 2 gli eventi delegati) per ogni figlio e figlio del figlio... ;-)

    Se metto un Boolean, per inibire il Delegate, non è così banale capire come gestirlo tra le Istanze della stessa classe...
    Dal Nodo parte tutto così
    NodesParent.Remove (me)
    
    dove [NodesParent] è l'istanza di [cCollection] che contiene il Nodo.
    Ora il codice nella [cCollection] il metodo appena richiamato...
    Public Sub Remove(Node As cNode)
        On Error GoTo Err_Handler
        Dim iCancel     As Integer
     
        ' Questo è EVENTO Delegato alla classe [cBuilder]
        EventsDelegate.RaiseBeforeDelConfirm Node, iCancel, False
                        
        If iCancel = True Then Exit Sub
        If Node.HasChilds Then Node.Childs.RemoveChilds
        Nodes.Remove pNode.Key    
    
        ' Questo è EVENTO Delegato alla classe [cBuilder]
        EventsDelegate.RaiseAfterDelConfirm
    End Sub
    
    Public Sub RemoveChilds()
        Dim Index       As Long
        Dim Node        As cNode
        For Index = Nodes.Count To 1 Step -1
            Set Node = Nodes.Item(Index)
            Remove Node
        Next
    End Sub
    
    Se riesci a seguire sei a buon punto... ;-)

    Per questo volevo implementare un IEnabler come controller di eventi ma sto perdendomi...
    Ultima modifica di @Alex; 11-06-2021 15:07 
    ℹ️ Leggi di più su @Alex ...

  7. #7
    Sgrubak non è in linea Scribacchino
    Grazie dell'esempio.
    Si il ragionamento riesco a seguirlo (la ricorsione mi ha sempre affascinato e cerco di usarla quando riesco).
    Ci ho solo messo tutto il fine settimana a capire perché la mia idea fosse difficile da gestire. E ci sono più o meno riuscito.
    Altra idea: e se nel [EventsDelegate.RaiseBeforeDelConfirm] oltre ad iCancel, tu potessi gestire anche l'innesco degli eventi?
    Dalla chiamata al primo Remove passi alla RaiseBeforeDelConfirm. Li decidi se annullare o se proseguire (il tuo [iCancel]). Se prosegui, hai la possibilità di determinare il motivo per cui è stato chiamato il Remove? Se così fosse, potresti aggiungere un EnableEvents al cBuilder. A quel punto, nessun evento si scatena, fino a che non ripristini la situazione.

    Onestamente in VBA non mi sono mai spinto a livelli così avanzati. Col .NET trovo sia tutto molto più agevole.


  8. #8
    L'avatar di @Alex
    @Alex non è in linea Moderatore Globale
    Il Remove o Delete come vogliamo intenderlo ma l'azione è quella... come ti ho spiegato Genera più del solo Evento specifico di Remove...
    Ipotizza un TreeView, voglio eliminare un Nodo, e questo ha dei figli... N non dato a sapersi quanti ed in che rapporto gerarchico.

    La funzione di Remove sul Nodo selezionato non avviene finchè non ho Eliminato i nodi figlio in modalità Bottom_Up... questo perchè prima di Eliminarlo controllo se ha figli e se li ha li passo alla funzione di Eliminazione ma siccome ogni singolo Nodo può avere figli... genera ricorsione, alla fine, eliminati tutti i Livelli N-1, vado a fare il Remove del Nodo selezionato.
    Quindi la funzione sopra non deve chiedermi conferma ogni volta... ma solo alla 1°... i Nodi Childs non hanno diritto di generare la Richiesta di Cancel.

    Ho per ora risolto con una memorizzazione di Node ed Evento da Triggerare... in questo modo funziona correttamente, la Classe DELEGATA prima di sparare il CallBack verifica di essere stata attivata su un Nodo e che il Nodo che l'ha invocata sia quello Settato...

    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    ...
    Onestamente in VBA non mi sono mai spinto a livelli così avanzati. Col .NET trovo sia tutto molto più agevole.
    Vuoi dire che con NET la ricorsione non funziona uguale...? ;-)
    ℹ️ Leggi di più su @Alex ...

  9. #9
    Sgrubak non è in linea Scribacchino
    Quote Originariamente inviato da @Alex Visualizza il messaggio
    Vuoi dire che con NET la ricorsione non funziona uguale...? ;-)
    No, ovvio. Ma avrei avrei sganciato gli handlers prima della cancellazione. Cosa che non credo sia facile in VBA (o meglio, non saprei come implementarla).
    Ma sarebbe stata comunque una corbelleria ora che ci penso perché dovrebbero essere comunque due funzioni di cancellazione distinte. Una di cancellazione vera e propria più un wrapper che sgancia e poi richiama la cancellazione...

    Niente... Non vado bene nemmeno come papera da debug.

+ Rispondi al messaggio

Potrebbero interessarti anche ...

  1. passare oggetto json da callback a funzione chiamante
    Da BennyB nel forum HTML, CSS e JavaScript
    Risposte: 4
    Ultimo Post: 13-05-2021, 09:12
  2. Intercettare callback dei ribbon/shortcut menu di sistema
    Da Max.Riservo nel forum Microsoft Access
    Risposte: 10
    Ultimo Post: 18-04-2020, 21:47
  3. delphi callback da c++ dll
    Da GianPiero nel forum Delphi
    Risposte: 1
    Ultimo Post: 22-10-2012, 20:47
  4. VB 2010 callback funzione DLL c++ 6.0
    Da mattew75 nel forum Visual Basic .Net
    Risposte: 5
    Ultimo Post: 22-09-2010, 17:16