Πέμπτη 24 Μαρτίου 2016

Παραδείγματα με Delegates και Events

Θέλουμε μια συνάρτηση, την Beta() να μπορεί να αλλάζει, και εκτός από το να κάνουμε άμεση χρήση της θέλουμε να την περάσουμε σε ένα τμήμα για να χρησιμοποιηθεί εκεί.

Function DelegateA {
      read X,Y
      Print X*Y
}
Function DelegateB {
      read X,Y
      Print X*2+Y
}
\\ Delagate function
Function Beta {}

\\ Passing Delegate
Module Theta {
      Read &Alfa()
      Call Alfa(2,2)
}
Link DelegateA() to Beta()
Call Beta(2,2)
Module Theta &Beta()
Link DelegateB() to Beta()
Call Beta(2,2)
Module Theta &Beta()

Αντι να δώσουμε σε τμήμα τον Αντιπρόσωπο...εδώ θα δώσουμε πότε τη μία και πότε την άλλη συνάρτηση σε μια υπορουτίνα (οι υπορουτίνες βλέπουν τις μεταβλητές του τμήματος σαν δικές τους). Χρησιμοποιούμε και εδώ το σύμβολο & που σημαίνει πέρασμα με αναφορά.

Function DelagateA {
      read X,Y
      =X*Y
}
Function DelagateB {
      read X,Y
      =X*2+Y
}
PrintMe(&DelagateA())
PrintMe(&DelagateB())

Sub PrintMe(&Beta())
Print Beta(2,2)
End Sub
Το ίδιο αλλά με ομάδες, τα αντικείμενα της Μ2000 (αυτά είναι στατικά)

Group One {
      Z=200
      Function DelagateA {
            read X,Y
            =X*Y+.Z
      }
}
Group Two {
      Z=100
      Function DelagateB {
            read X,Y
            =X*2+Y+.Z
      }
}
PrintMe(&One.DelagateA())
PrintMe(&Two.DelagateB())

End  \\ optional - Sub is like End
Sub PrintMe(&Beta())
Print Beta(2,2)
End Sub

Τώρα θέλουμε η κλήση να γίνεται μέσω ενός γεγονότος, ώστε να μπορούμε να στέλνουμε παραμέτρους σε περισσότερες από μία συναρτήσεις..με μια εντολή (multicast). Στο παράδειγμα κάνουμε και ενέργεις όπως απενεργοποίηση/ενεργοποίηση του γεγονότος, προσθήκη, αφαίρεση, καθαρισμός! Δείτε ότι στην πρώτη κλήση αλλάζει η Β γιατί μπαίνει με αναφορά, αλλά και οι δυο συναρτήσεις πήραν αντίγραφο τιμών!

Event Alfa {
      Read X, Y
}
Function DelegateA {
      Read X,Y
      Print X*Y
}
Function DelegateB {
      Read X,Y
      Print X*2+Y
}
\\ Add two functions and do a multicast call
Event Alfa New DelegateA(), DelegateB()
Call Event Alfa, 2, 2

\\ Parameters evaluated before
Function AddOne { Read &A : A++: =A}
B=1
Call Event Alfa, AddOne(&B),B
Event Alfa Hold
Call Event Alfa, 2, 2 \\ nothing
Event Alfa Release
Call Event Alfa, 2, 2 \\ 4 and  6  
Event Alfa Drop DelegateB()
Call Event Alfa, 2, 2 \\ 4
Event Alfa Clear
Call Event Alfa, 2, 2

Απλή περίπτωση περάσματος πίνακα με αναφορά. Στην EventA αλλάζει τιμή το Κ(3) και στην EventB() την εμφανίζουμε.

Event Alfa {
      Read &A(), Item, X, Y
}

Function EventA {
      Read &A(), Item, X, Y
      A(Item)=X*2+Y
}
Function EventB {
      Read &A(), Item, X, Y
      Print A(Item)
}
Dim K(20)
Event Alfa New EventA(), EventB()
Call Event Alfa &K(), 3, 2,2
Print K(3)

Χρήση δεικτών! Η Μ2000 έχει δείκτες σε μορφή αλφαριθμητικών. Από το Κ(3) πήραμε μια ισχνή αναφορά. Ουσιαστικά παραμένει ως Κ(3) αλλά συνοδεύεται από το περιβάλλον που βρίσκεται (δεν μπορούμε να περνάμε κανονικές αναφορές σε στοιχεία πίνακα, αλλά με την ισχνή αναφορά το καταφέρνουμε). Δείτε την τελεία μετά το $. αυτό δείχνει ότι έχουμε δείκτη.

Event Alfa {
      Read Pointer$, X, Y
}

Function EventA {
      Read W$, X, Y
      W$.=X*2+Y
}
Function EventB {
      Read W$, X, Y
      Print Eval(W$.)
}
Dim K(20)
Event Alfa New EventA(), EventB()
Call Event Alfa weak$(K(3)), 2,2
Print K(3)

Χρήση  οκνηρής αποτίμησης. Δίνουμε τις συναρτήσεις ως μέρη του τμήματος εκτός συνάρτησης! Έτσι η Ζ μπορεί να διαβαστεί και να αλλαχθεί. Περνάμε δηλαδή το τρέχον περιβάλλον στη κλήση. Για να μην αλλάξουν άλλα Χ και Υ διαβάζουμε τοπικά με τον δείκτη New.

Event Alfa {
      Read X, Y
}
Z=100
Function DelegateA {
      Read New X,Y
      Print X*Y+Z
      Z+=100
}
Function DelegateB {
      Read New X,Y
      Print X*2+Y+Z
}
Event Alfa New lazy$(&DelegateA()), lazy$(&DelegateB())
Module OneLevelDown {
      Read &anEvent
      Call Event anEvent, 2,2
}
OneLevelDown &Alfa


Το ίδιο κάνει και αυτό με γενικές μεταβλητές, συναρτήσεις, γεγονότα: (οι γενικές αλλάζουν με <= όχι με =, αλλά τα ++, --, +=, -=, /= , -! και ~ δουλεύουν για όλα!


Global Event Alfa {
      Read X, Y
}
Global Z=100
Function Global DelegateA {
      Read X,Y
      Print X*Y+Z
      Z+=100
}
Function Global DelegateB {
      Read X,Y
      Print X*2+Y+Z
}
Event Alfa New lazy$(&DelegateA()), lazy$(&DelegateB())
Module OneLevelDown {
      Call Event Alfa, 2,2
}
OneLevelDown

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.