Τρίτη 8 Μαρτίου 2016

Γεγονότα και Αντικείμενα Εκτέλεσης (ανανεώθηκε)

Σχετίζεται με την αναθεώρηση 182.

Από τις 29/2 που  σκέφτηκα να βάλω τα γεγονότα την Μ2000, διερευνώ τις δυνατότητές τους. Πολλές φορές ο τρόπος που φτιάχνουμε κάτι, μας δίνει και άλλες δυνατότητες (από αυτές που αρχικά σκεφτήκαμε). Εδώ θα δούμε τα γεγονότα και στατικές μεταβλητές.

Aς δούμε ένα γεγονός Α με μια συνάρτηση  (χωρίς στατική μεταβλητή), απλά για να κατανοήσουμε ότι μπορούμε να συνδέσουμε μια άλλη συνάρτηση (εκτός από την ανώνυμη που περιλαμβάνεται στον ορισμό). Επίσης βλέπουμε ότι δεν έχει παραμέτρους.
Η πρώτη Κάλεσε Γεγονός θα μας τυπώσει το Γειά σου Κόσμε. Η δεύτερη θα το ξανατυπώσει αλλά θα τυπώσει και το Hello World.

Γεγονός Α {
      Συνάρτηση {
            Τύπωσε "Γειά Σου Κόσμε"
      }
}
Κάλεσε Γεγονός Α
Συνάρτηση ΚαιΑυτό {
      Τύπωσε "Hello World"
}
Γεγονός Α νέο ΚαιΑυτό()
Κάλεσε Γεγονός Α



Παρακάτω θα φτιάξουμε μια συνάρτηση που θα ονομάσουμε Βηματική και θα βάλουμε μια στατική Α. Στατικές φτιάχνουμε για απλές μεταβλητές, όχι για πίνακες ή αντικείμενα, και λέγονται στατικές όχι γιατί συνδέονται με τον κώδικα αλλά επειδή συνδέονται με το αντικείμενο εκτέλεσης του κώδικα. Αν από το ίδιο τμήμα καλούμε τη συνάρτηση τότε έχουμε το ίδιο αντικείμενο εκτέλεσης. Όμως αν κληθεί διαδοχικά από ένα γεγονός τότε αποδίδεται νέο αντικείμενο.

Καθαρό  \\ προσοχή σβήνει όλες τις μεταβλητές και τις στατικές
Συνάρτηση Βηματική {
      Στατική Α=1
      Επίλεξε Με Α
      Με 1
      Τύπωσε "Ένα",
      Με 2
      Τύπωσε "Δύο",
      Με 3
      Τύπωσε "Τρία",
      Αλλιώς
      {
            Τύπωσε "Τέσσερα",
            Α=0
      }
      Τέλος Επιλογής
      Α++
      Τύπωσε Αριθμός
}
Γεγονός Α { Διάβασε X }
Γεγονός Α Νέο Βηματική()
Κάλεσε Γεγονός Α, 0
Κάλεσε Γεγονός Α, 0
Τύπωσε Υπό
Γεγονός Α Νέο Βηματική()
Κάλεσε Γεγονός Α, 0
Τύπωσε Υπό
Γεγονός Α Νέο Βηματική()
Για Ι=1 έως 3 {
      Κάλεσε Γεγονός Α, Ι
      Τύπωσε Υπό
}
Γεγονός Α Πέτα Βηματική()
Κάλεσε Γεγονός Α, 0


Κάθε φορά που καλούμε το γεγονός τρέχουν ξεχωριστά αντικείμενα - συναρτήσεις! Κάθε μία έχει τη δική της στατική και ξέρει σε τι βήμα βρίσκεται! Περνάμε και μια τιμή η οποία λαμβάνεται από την Αριθμός στη τελευταία εντολή Τύπωσε Αριθμός. Έχουμε δώσει τρεις νέες συναρτήσεις Βηματική(). Στο τέλος πετάμε τη τελευταία που δώσαμε, και καλούμε τις άλλες δυο.

Πιο δύσκολο είναι το παρακάτω, αν και μοιάζει με το αρχικό, εδώ περνάμε δυο οκνηρές συναρτήσεις. Οκνηρές γιατί το ΚαιΑυτό() δεν είναι η συνάρτηση που δίνουμε αλλά αυτή που περιέχεται σε μια ανώνυμη. Όταν θα κληθεί από το Γεγονός τότε αυτή η ανώνυμη συνάρτηση θα βρεθεί στο χώρο του τμήματος, επειδή γνωρίζει σε ποιον τμήμα δημιουργήθηκε, και θα καλέσει την ΚαιΑυτό(100,Αριθμός) όπου ο αριθμός είναι αυτός που του δίνει το Γεγονός, ενώ το 100 θα μπορούσε να ήταν μια μεταβλητή από το τμήμα,

Καθαρό
Γεγονός Α {
      Διάβασε Χ
      Συνάρτηση {
            Τύπωσε "Γειά Σου Κόσμε"
      }
}
Συνάρτηση ΚαιΑκόμηΑυτό {
      Διάβασε Α
      Τύπωσε "Hello World 1"
}
Συνάρτηση ΚαιΑυτό {
      Διάβασε Α, Β
      Τύπωσε "Hello World", Α, Β
}
Γεγονός Α νέο Οκν$(ΚαιΑυτό(100, Αριθμός)), Οκν$(ΚαιΑυτό(150, Αριθμός)), ΚαιΑκόμηΑυτό()
Γεγονός Α νέο ΚαιΑκόμηΑυτό()
Κάλεσε Γεγονός Α, 10
Σωρός


Δείτε κάτι άλλο, που θα χρησιμοποιήσουμε αργότερα με την γεγονός: Έχω μια συνάρτηση που την καλώ και μου δίνει τον επόμενο ή το ίδιο χαρακτήρα (Ανάλογα με μια τιμή 1 ή 0). Η εσωτερική μεταβλητή Θέση δίνει τη θέση του δρομέα (στο Χ άξονα, για το Υ έχουμε την γραμμή).

Καθαρό
Συνάρτηση ΚάθεΧαρ$ {
      Στατική α$, β
      διάβασε κ$, βήμα_χαρ
      αν κ$<>α$ τότε β=1 : α$=κ$
      Αν β>0 τότε {
            =μέσ$(α$, β,1)
            β+=βήμα_χαρ
      } Αλλιώς =""
}
Γ$="Γιώργος"
Ενώ ΚάθεΧαρ$(Γ$, 0)<>"" {
      Αν θέση>0 τότε Τύπωσε "-";
      Τύπωσε ΚάθεΧαρ$(Γ$, 1);
}
Τύπωσε


Τυπώνει:
Γ-ι-ώ-ρ-γ-ο-ς


Παραλλαγή με γεγονός. Όσες φορές και να χρησιμοποιήσω τη συνάρτηση μέσα στο τμήμα θα έχει το ίδιο αντικείμενο εκτέλεσης. Αν όμως τη βάλω σε ένα γεγονός τότε μπορώ να έχω περισσότερα αντικείμενα εκτέλεσης. Αντί να παίρνω έναν χαρακτήρα, με την μεσ$()  ή Mid$() μπορώ να παίρνω από μια θέση όλους τους χαρακτήρες μέχρι το τέλους του αλφαριθμητικού.

Καθαρό
Κλάση ΚΧ {
      α$, β      
      Συνάρτηση ΚάθεΧαρ {
            διάβασε κ$, βήμα_χαρ, &αποτέλ$
            αν κ$<>.α$ τότε<=1 : .α$<=κ$
            Αν >0 τότε {
                  αποτέλ$=μέσ$(.α$, )
                  +=βήμα_χαρ
            } Αλλιώς αποτέλ$="" : .α$<=""
      }
}
Γ$="Γιώργος"
Δ$="Αλέξανδρος"
Γεγονός Α1 { Διάβασε αλφαριθμητικό$, &μετρητής, &Αποτέλεσμα$ }
Α=ΚΧ()
Γεγονός Α1 Νέο Α.ΚάθεΧαρ()
Γεγονός Α2 { Διάβασε αλφαριθμητικό$, &μετρητής, &Αποτέλεσμα$ }
Β=ΚΧ()
Γεγονός Α2 Νέο Β.ΚάθεΧαρ()
Τι$=""
{
      Κάλεσε Γεγονός Α1, Γ$, 1, &Τι$
       Αν Τι$<>"" τότε Τύπωσε Τι$
      Κάλεσε Γεγονός Α2, Δ$, 1, &Τι$
      Αν Τι$<>"" τότε Τύπωσε Τι$: Κυκλικά
}

Παρατήρηση: Στα γεγονότα δεν καταχωρούνται οι στατικές, οπότε η παραλλαγή μπορεί να γίνει με αντικείμενα, που έχουν μέλη τις μεταβλητές που θέλουμε για στατικές. (Έκδοση 10).



Μπορώ να περάσω και ανώνυμη συνάρτηση σε αλφαριθμητικό.

Γεγονός Α {
      Διάβασε Χ
}
Πρόσημο=-1
Ομάδα Αλφα {
      μια_τιμή=10
      Συνάρτηση Κ {
            διάβασε Χ, Προ
           Τύπωσε Χ*.μια_τιμή*Προ
      }
}


Γεγονός Α νέο οκν$(Αλφα.Κ(αριθμός, Πρόσημο)), "{Τύπωσε Αριθμός}"
Κάλεσε Γεγονός Α, 30


Δείτε μια τελευταία σκέψη. Ας υποθέσουμε ότι έχουμε μια συνάρτηση και θέλουμε να την κάνουμε σαν ένα αντικείμενο. Δηλαδή να μπορούμε να στέλνουμε μια τιμή και να μας στέλνει μια απάντηση. Όμως δεν θα επικοινωνούμε με όνομα αλλά με χειριστή, δηλαδή με αριθμό. Μπορούμε να απευθυνθούμε σε ένα ή σε όλα μαζί. Χρησιμοποιούμε έναν εξωτερικό μετρητή για να δώσουμε αριθμό σε κάθε "συνάρτηση αντικείμενο". Ο αριθμός γράφεται σε μια στατική συνάρτηση. Όταν καλούμε το γεγονός  Όλα (καλούμε το Δράση που είναι αναφορά του Όλα) τότε στέλνει τα δεδομένα σε όλες τις συναρτήσεις. Οι συναρτήσεις κάθε φορά φτιάχνονται σε ένα αντικείμενο και μαζί δίνονται και οι στατικές του. Τις στατικές τις κρατάει το αντικείμενο εκτέλεσης τους τμήματος. Μπορώ να φτιάξω και άλλα γεγονότα. Εδώ έχω έναν ακόμα για να τυπώνουμε, το οποίο το καλεί μια συνάρτηση από αυτές τους γεγονότος, δηλαδή από αυτές που καλούνται από ένα γεγονός και εμείς μπορούμε να καλέσουμε ένα άλλο, πριν πάμε στην επόμενη "συμβεβλημένη" συνάρτηση ή στο πέρας της κλήσης.(τερματισμός).

Παρατήρηση. Δεν έχουμε στατικές στη συνάρτηση Αντικείμενο(), αλλά φτιάχτηκε η κλάση ΜεΑντικείμενο που δίνει τις Ποιός, και Αποθήκη, σαν να είναι στατικές. Απλά φτιάχνουμε τρια αντικείμενα Α1, Α2, Α3 και δίνουμε σαν συναρτήσεις τις αντίστοιχες συναρτήσεις από το καθένα. Επίσης χρησιμοποιήθηκε η εντολή Σταθερές (ή Σταθερή) που δημιουργεί ονόματα με τιμές που δεν αλλάζουν.

Καθαρό
Άδειασε
Γενική Ομάδα Λογάριασε {
      Μετρητής=1
      Συνάρτηση Άλλο {
            =.Μετρητής
            ? "Νέος="; .Μετρητής
            .Μετρητής++
      }
}
Γενικό Γεγονός Α {
      Διάβασε για_εκτύπωση$
      Συνάρτηση {
            Τύπωσε για_εκτύπωση$
      }
}


Κλάση ΜεΑντικείμενο {
Ποιός=-1, Αποθήκη$
Συνάρτηση Αντικείμενο {
      Αν .Ποιός=-1 τότε .Ποιός<=Λογάριασε.Άλλο()
      Διάβασε Χειριστής
      Αν .Ποιός=Χειριστής ή Χειριστής=0 τότε {
            Διάβασε ΟδηγίαΜου, &Κάτι$
            Επίλεξε Με ΟδηγίαΜου
            Με 1
                .Αποθήκη$<=Κάτι$
            Με 2
                Κάτι$<=.Αποθήκη$
            Με 3
                  Κάλεσε Γεγονός Α, .Αποθήκη$
            Τέλος Επιλογής
      }
}
}
Α1=ΜεΑντικείμενο()
Α2=ΜεΑντικείμενο()
Α3=ΜεΑντικείμενο()
Γεγονός Όλα { Διάβασε Χειριστής, ΟδηγίαΜου, &Κάτι$ }
Γεγονός Όλα Νέο Α1.Αντικείμενο(), Α2.Αντικείμενο(), Α3.Αντικείμενο()
Συνάρτηση ΚάλεσεΚάτι$ {
      Διάβασε &Δράση, Αντικείμενο, Εντολή, ΜιαΤιμή$
      Κάλεσε Γεγονός Δράση, Αντικείμενο, Εντολή, &ΜιαΤιμή$
      =ΜίαΤιμή$
}
Σταθερές ΒάλεΤιμή=1, ΠάρεΤιμή=2, ΤύπωσεΤιμή=3


Κάλεσε κενή ΚάλεσεΚάτι$(&Όλα, 1, ΒάλεΤιμή, "Πρώτο Θέμα")
Κάλεσε κενή ΚάλεσεΚάτι$(&Όλα, 2, ΒάλεΤιμή, "Άλλο Θέμα")
Κάλεσε κενή ΚάλεσεΚάτι$(&Όλα, 3, ΒάλεΤιμή, "Τελευταίο Θέμα")
Για Ι=1 έως 3 {
      Κάλεσε κενή ΚάλεσεΚάτι$(&Όλα, Ι, ΤύπωσεΤιμή, "")
}
\\  διαβάζω την 2 - η Παράθεση βάζει εισαγωγικά
Τύπωσε "Διαβάζω τη 2 ="+Παράθεση$(ΚάλεσεΚάτι$(&Όλα, 2,ΠάρεΤιμή, ""))
Τύπωσε "Με μια εντολή τυπώνω όλα"
Κάλεσε κενή ΚάλεσεΚάτι$(&Όλα, 0, ΤύπωσεΤιμή, "")



Αναθεώρηση 182

Εσωτερικές μεταβολές στην Τύπωσε και στο αντικείμενο Γεγονός. Για το δεύτερο θα κάνω νέα δημοσίευση. Η τύπωσε είχε ένα πρόβλημα όπου το πεδίο στην στήλη γέμιζε στην αναλογική γραφή τότε άλλαζε στο τέλος δυο γραμμές (και όχι μία). Γίνονταν σε εξαιρετικές περιπτώσεις, αλλά επιδιορθώθηκε.
Οι αλλαγές φαίνονται στο Git. Δείτε πλευρικό μενού.

Δευτέρα 7 Μαρτίου 2016

Εγχειρίδιο της Μ2000 - Τεύχος 26ο

16. Αναπαράσταση τιμών με γραφικά.

Είδαμε στα κεφάλαια 14 και 15 παρουσίαση στοιχείων σε στήλες και σε κείμενο. Εδώ μας ενδιαφέρουν οι γραφικές παραστάσεις. Η γραφική παράσταση είναι η αναπαράσταση που δηλώνει ποσότητα ή αναλογία ή ποιότητα όπου οι λέξεις και οι αριθμοί απλά συνοδεύουν, ή μπορεί και να λείπουν! Όμως όπως έχει εξηγηθεί ένα στοιχείο έχει νόημα όταν γνωρίζουμε τι περιγράφει, τι αναπαριστά. Έτσι μια γραφική αναπαράσταση οφείλει να δείχνει με κάποιο τρόπο στο που αναφέρεται. Και αυτός ο τρόπος συνήθως είναι μια λεζάντα, μια επιγραφή, ένας τίτλος, και αν η αναπαράσταση είναι σύνθετη, αν έχει μέρη διακριτά, τότε χρειαζόμαστε και επιμέρους λεζάντες ή επιγραφές και αυτά συνιστούν αυτό που λέμε Υπόμνημα.

Γενικά το υπόμνημα συνοδεύει πάντα ένα σχέδιο, οτιδήποτε και να δείχνει αυτό. Ένας πίνακας αριθμών στη θέση υπομνήματος έχει επικεφαλίδες, και ένα κείμενο αντί υπομνήματος έχει τίτλους. Άρα για το κεφάλαιο αυτό τα δυο προηγούμενα 14 και 15 είναι προϋπόθεση να είναι διαβασμένα!


16.1 Μονάδες Μέτρησης Twips

Οι εντολές γραφικών της Μ2000 είναι σε twips. Τα twips έχουν "λογική" υπόσταση και πραγματική. Στον εκτυπωτή έχουμε πραγματική υπόσταση, διότι εκεί 1440 twips είναι μια ίντσα, όσες είναι οι τελείες (dots) ανά ίντσα που μπορεί να τυπώσει ο Εκτυπωτής (dpi). Στην οθόνη του υπολογιστή μας τα twips έχουν μια άμεση σχέση με τα εικονοστοιχεία και αυτή έχει όνομα "λόγος twips ανά εικονοστοιχείο" δηλαδή πόσα twips έχει πλάτος ένα εικονοστοιχείο, ή ύψος αν ζητάμε το ύψος.

Λέμε ότι τα twips είναι λογικά στην οθόνη,  γιατί αν αλλάξουμε το μέσο προβολής με ένα άλλο με ίδια ανάλυση π,χ, 1280Χ1024 αλλά μεγαλύτερο μέγεθος εικονοστοιχείου, ο υπολογιστής δεν θα δώσει σημασία, δεν θα ενημερωθεί.Ο υπολογιστής λογαριάζει μια ανάλυση χωρίς να ασχολείται αν εμείς έχουμε μια 17 ιντσών Οθόνη ή μια 22 ιντσών. Αν όμως μιλάμε για τον εκτυπωτή τότε εκεί ο εκτυπωτής αναφέρει το μέγεθος σελίδας σε πραγματικό μέγεθος, και τα twips είναι πραγματικά και όχι "λογικά". (η έκφραση λογικά σημαίνει ότι αν έχουμε τα κατάλληλα στοιχεία θα μπορούσαμε να λογαριάσουμε το πραγματικό μέγεθος, άρα σαν τιμή έχει νόημα, απλά δεν έχουμε ή καλύτερα δεν μας ενδιαφέρουν τα στοιχεία όπως πόση μεγάλη είναι η οθόνη μας. Από τα 95 υπήρχε τρόπος να ρυθμίζει κανείς τα Dpi της οθόνης από το 96, που ήταν το λογικό σε πραγματικό, εμφανίζοντας ένα χάρακα. Εμείς βάζαμε έναν πραγματικό χάρακα και προσαρμόζαμε τον εμφανιζόμενο έτσι ώστε να εξάγει από την προσαρμογή το σύστημα τα σωστά dpi. Δυστυχώς τα περισσότερα προγράμματα δεν φτιάχτηκαν λογαριάζοντας ότι θα αλλάξουν τα dpi από τα 96 (σε Windows). Στις πιο σύγχρονες εκδόσεις των Windows υπάρχει τρόπος να προσομοιώσει το μέγεθος σε χαμηλότερα ενώ δουλεύει το σύστημα σε υψηλά (μεγαλύτερα από το στάνταρτ των 96dpi)


Έχει σημασία λοιπόν όταν σκεφτόμαστε ότι θα παρουσιάσουμε κάτι στην οθόνη και θέλουμε να δουλεύει  οθόνη, με οποιοδήποτε λόγο πλάτους προς ύψος και με οποιαδήποτε ανάλυση, πραγματικά εικονοστοιχεία σε πλάτος και σε ύψος, να χωρίσουμε κατάλληλα σε μέρη το χώρο της. Στα γραφικά δηλαδή έχει σημασία να αποφασίσουμε πως θα χωρίσουμε το χώρο μας και τι θα βάλουμε στο καθένα. Κάτι που με την Τύπωσε είχε να κάνει με τις στήλες, ενώ με το κείμενο με το χώρισμα της οθόνης και με το καθορισμό περιθωρίων.

16.2 Μέγεθος-Διαστάσεις Εικονοστοιχείου (Pixel)


Ένας λόγος που πολλά προγράμματα δεν λογαριάζουν σε twips είναι ότι επικεντρώνονται στην οθόνη. Στην οθόνη τα εικονοστοιχεία είναι τετράγωνα. Στους εκτυπωτές δεν ισχύει αυτό! Η ανάλυση κατά Πλάτος και κατά Ύψος δεν συμπίπτει. Μάλιστα ξεχωρίζουν το πλάτος σε τελείες dots (dpi) και το ύψος σε γραμμές lines per inch (lpi), και δίνουν συνήθως μια τιμή 2 επί τα lpi ως τα dpi κατά Y. Αν είχαμε 10 κάθετες τελείες και μετράγαμε το ύψος τους τότε θα το μετράγαμε από το κέντρο της τελείας ή από την άκρη; Λογικά θα έλεγε κανείς ότι μετράμε από το ένα κέντρο στο άλλο κέντρο..ή από την μια άκρη στην άλλη άκρη, αλλά δεν γίνεται αυτό, μετράμε από την πάνω άκρη στην τελεία στην πιο ψηλή θέση, ως την κάτω άκρη της τελείας στην πιο χαμηλή θέση. Οι τελείες δηλαδή έχουν μέγεθος, δεν είναι σημεία όπως τα σημεία (τα σημεία είναι αδιάσταστα στην γεωμετρία, δεν έχουν διαστάσεις)  που έχουμε μάθει στο χαρτί να σημειώνουμε και να κάνουμε σχήματα. Ανάμεσα σε δέκα τελείες υπάρχουν εννιά χωρίσματα. Αν έχουμε πέντε τελείες άσπρες και μετά πέντε μαύρες το μάτι μας θα διακρίνει το χώρισμα, και καμία τελεία! Αν έχουμε στις δέκα τελείες την 5η μαύρη και τις άλλες άσπρες το μάτι μας θα διακρίνει μια τελεία. Επειδή το μάτι μας διακρίνει τελείες και χωρίσματα, η πραγματική ανάλυση των 150 lpi είναι 300dpi. (λέμε και τα χωρίσματα τελείες,υπολογίζουμε 150 σημεία +149 χωρίσματα+1,θεωρώντας την μια πλευρά ως την αρχή της μέτρησης).  Το lpi θα μεγάλωνε αν μπορούσε ένας εκτυπωτής να μεταφέρει με ακρίβεια με μικρότερο βήμα τη σελίδα για να εκτυπωθεί με τεχνολογία inkjet, ή να περιστρέψει με μεγαλύτερη ακρίβεια ένα τύμπανο για να το γράψει ένα laser. Αυτό απαιτεί ακριβό βηματικό κινητήρα (step motor). Συνήθως λοιπόν οι εκτυπωτές έχουν ποιοτική κεφαλή που μπορεί σε μικρό χρόνο να δώσει πολλές εξαγωγές μελανιού, άρα έτσι να έχουμε μεγάλο αριθμό dpi κατά πλάτος και όχι κατά ύψος. Και έτσι προκύπτει η διαφορά.

Με αυτή τη γνώση λοιπόν γνωρίζουμε ότι η χρήση twips είναι αναγκαία για να βγάλουμε σωστά μεγέθη στην εκτύπωση. Δεν μας χαλάει να χρησιμοποιούμε twips για την οθόνη μας. Υπάρχει το πρακτικό όφελος που μας λέει ότι εφόσον ως μονάδα τα twips είναι μικρότερα από την μονάδα "εικονοστοιχείο" pixels, θα θέλουμε έναν αριθμό twips για να μας δώσει το ολόκληρο Pixel. Πράγματι σε μια οθόνη με 96 dpi τα twips για ένα εικονοστοιχείο είναι 15. Άρα 150 twips είναι 10 pixels σε οθόνη 96dpi. Υπάρχουν υπολογισμοί που θα δίνουν έναν αριθμό twips που  θα λέει τόσα Pixels συν ένα υπόλοιπο σε twips. Αυτό το υπόλοιπο μας κάνει για να δούμε αν ο αριθμός δείχνει τα Pixels χωρίς το υπόλοιπο ή τα ίδια συν ένα. Αυτό συμβαίνει επειδή δεν έχουμε αναπαράσταση μισού Pixel στην οθόνη. Ειδικά για τους χαρακτήρες αν δεν οριστεί γωνία εμφάνισης άλλη από την οριζόντια, τα Windows χρησιμοποιούν μια τεχνική SubPixel για τις Οθόνες TFT, μπερδεύοντας χρώματα. Παρόμοια γίνονται και στο Linux. Αυτό το κείμενο το διαβάζεται με τέτοια τεχνική. Δείτε στο Google το ClearType.

Συνοψίζοντας: Ορισμένες φορές μας ενδιαφέρει το σημείο και ορισμένες η απόσταση. Το σημείο προφανώς έχει μια απόσταση από το σημείο αρχής (0,0), και στη Μ2000 είναι σταθερό στην πάνω αριστερή γωνία (ίσως αυτό να μπορεί να αλλάξει σε άλλες εκδόσεις, αλλά προς το  παρόν έχει κρατηθεί σταθερό), αλλά αυτό που μας ενδιαφέρει είναι το πώς επιλέγουμε το κοντινότερο όταν έχουμε μια τιμή με δεκαδικά. Όταν μετράμε απόσταση μπορεί να έχουμε και στα δυο άκρα τιμές με δεκαδικά, άρα αν έχουμε 0.5 pixels και στα δύο σε twips θα είναι + 7.5  και στην διαφορά δεν θα λογαριάζονται π.χ. 97.5 twips - 37.5  έχουμε 60 twips ή 60/15 = 4 pixels. Που είναι όμως το 97.5; Εδώ πρέπει να σκεφτούμε ότι η μισή μονάδα  (εδώ τα 7.5 twips )είναι ένα ένδειξη ότι είμαστε στο επόμενο ολόκληρο...δηλαδή 90+7.5+7.5= 105 twips, ή 7 Pixels.
Το ίδιο πρόγραμμα σε Windows με 120dpi στην οθόνη,  θα έχει 12 twips σε κάθε Pixel, έτσι το 97.5 που υπολογίζει το πρόγραμμα δίνει 8 pixels και ένα υπόλοιπο  1.5 twips. Αν έχουμε ένα bitmap των 7 pixels, στην περίπτωση με τα 15 Twips ανά pixel ταιριάζει άμεσα, ενώ στα 8 pixels πρέπει να γίνει νέα δειγματοληψία  ή resample (τα 7 εικονοστοιχεία να επεκταθούν σε 8) την οποία η Μ2000 την κάνει αυτόματα, όπως θα δούμε σε άλλο τεύχος.

Το θέμα εδώ αναλύεται σε κάποιο βάθος γιατί έχει σημασία σε μια παρουσίαση να πάρουμε αυτό που περιμένουμε σε κάθε περίπτωση που θα τρέξουμε το πρόγραμμά μας, είτε στον υπολογιστή που φτιάχτηκε, είτε σε άλλο.

Προσθήκη της $(4,10) για να κάνει την εμφάνιση των γραμμάτων σε αναλογική γραφή και το μέγεθος της στήλης 10 χαρακτήρες (μη αναλογικούς)

Πένα 14
Οθόνη 5
Περιθώριο {Οθόνη 1}
\\ Η τύπος περιορίζει την οθόνη της Μ2000
\\ για το βασικό επίπεδο τα στοιχεία της Τύπος είναι προτεινόμενα
\\ ενδέχεται να αλλαχτούν
Τύπος 16, Ανάλυση.Χ-3000, Ανάλυση.Υ-3000
Τύπωσε $(4,10),
Πένα 11 {
Τύπωσε Μέρος $(2), "Μέγεθος", "Χ","Υ","Μονάδες"
Τύπωσε
\\ Αυτά ζητάμε:
      Τύπωσε 16, Ανάλυση.Χ-3000, Ανάλυση.Υ-3000
\\ Αυτά είναι τα πραγματικά:
      Τυπωσε Τύπος, Χ.Σημεία, Υ.Σημεία
}
Τύπωσε "Ανάλυση  Οθόνης Υπολογιστή"
Πένα 11 {
      Τύπωσε "", Ανάλυση.Χ, Ανάλυση.Υ, " σε twips"
      Τύπωσε "", Ανάλυση.Χ Δια Πλάτος.σημείου, Ανάλυση.Υ Δια Ύψος.Σημείου, " σε Pixels"
}


Τύπωσε "Αρχικά το Παράθυρο της Μ2000 έχει ίδιο μέγεθος με την Οθόνη Υπολογιστή"
Τύπωσε "Ανάλυση  Οθόνης (φόρμας της Μ2000)"
Πένα 11 {
      Τύπωσε "", Χ.Σημεία, Υ.Σημεία, " σε twips"
      Τύπωσε "", Χ.Σημεία Δια Πλάτος.σημείου, Υ.Σημεία Δια Ύψος.Σημείου, " σε Pixels"
}


Δείτε ότι εκεί που έχουμε ορίσει γράμματα με 16 points μέγεθος, μας εμφανίζει το σύστημα 15.75 (αν έχουμε 96dpi ανάλυση οθόνης, που τόσο είναι τα περισσότερα Window συστήματα. Θα εξηγηθεί παρακάτω γιατί γίνεται αυτό)



Περί σημείων και ακρίβειας (πότε βάζουμε το +1 δηλαδή).

Φόρμα 40,25
Τύπωσε $(4),
ΔεςΕδώ(Ανάλυση.Χ, Ανάλυση.Υ, 0)
Τύπωσε("Ανάλυση Οθόνης Υπολογιστή")
ΔεςΕδώ(Χ.Σημεία, Υ.Σημεία, 1)
Τύπωσε("Διάστημα")
Περιθώριο {
      \\ έχουμε πλήρη κάλυψη στην αρχή!
      \\ αυτό μπορεί να αλλάξει
      ΔεςΕδώ(Χ.Σημεία, Υ.Σημεία, 1)
}
Τύπωσε("Διάστημα")
\\ Θέση του 300, 300
ΔεςΕδώ(300,300,0
Τύπωσε("Θέση"\\ 21ο Pixel θέση 20, ξεκινάνε από 0
\\ Πλάτος του 300, 300
ΔεςΕδώ(300,300,1)
Τύπωσε("Διάστημα"\\ δίνει το 21


\\ Θέση του 0, 0
ΔεςΕδώ(0,0,0)
Τύπωσε("Θέση"\\  το 1ο
\\ Πλάτος του 0,0
ΔεςΕδώ(0,0,1
Τύπωσε("Διάστημα"\\ δίνει 1,1 επειδή τόσo μέγεθος έχει ένα pixel


Τύπωσε "Υπολογισμός κοντινότερου σημείου"
ΔεςΕδώ(Πλάτος.σημείου*10.2, Υψος.σημείου*10.2, .5)
Τύπωσε("Θέση")
ΔεςΕδώ(Πλάτος.σημείου*10, Υψος.σημείου*10, .5)
Τύπωσε("Θέση")
ΔεςΕδώ(Πλάτος.σημείου*9.8, Υψος.σημείου*9.8, .5)
Τύπωσε("Θέση")
Έξοδος
Ρουτίνα Τύπωσε(Τι$)
Πένα 14 { Τύπωσε Αριθμός, Αριθμός, " Σε twips"}
Πένα 13 { Τύπωσε Αριθμός, Αριθμός, " "+Τι$+" Σε pixels"}
Τέλος Ρουτίνας
Ρουτίνα Περιστροφή()
      \\ περιστρέφει τα 4 πρώτα στοιχεία
      \\ του σωρού τιμών
      Φέρε 2 : Φέρε 3 : Φέρε 4
Τέλος Ρουτίνας
Ρουτίνα ΔεςΕδώ(Χ,ΥΔιάστημα)
      Βάλε Χ, Υ
      Βάλε Ακ(Χ/Πλάτος.Σημείου+Διάστημα)
      Βάλε Ακ(Υ/Ύψος.Σημείου+Διάστημα)
\\      Περιστροφή()
\\      από 180 αναθεώρηση
      Φέρε 1,-4
Τέλος Ρουτίνας


16.3 Μετρήσεις στην Οθόνη και στο Περιθώριο


Παράθυρο 16,0
Περιθώριο { Φόντο 2, 5 }
Πένα 14



Αν προσέξει κανείς την οθόνη της Μ2000, δηλαδή αυτό που εμφανίζει ως κονσόλα, θα παρατηρήσει ένα πλαίσιο γύρω από την οθόνη. Προφανώς θα ήθελε κανείς να έχει το μέγιστο δυνατό σε μια φόρμα έστω 40Χ25 χαρακτήρων αλλά δεν είναι δυνατόν να μην υπάρχει "υπόλοιπο". Δηλαδή δεν είναι πάντα δυνατόν να διαιρέσουμε δια του 40 το πλάτος της οθόνης της συσκευής μας και να πάρουμε επακριβώς 40 χαρακτήρες, και αυτό δεν έχει να κάνει με τη διαίρεση αλλά με το μέγεθος του γράμματος: Τα μεγέθη των γραμμάτων αλλάζουν με βήματα, που σχετίζονται με την αναπαράστασή τους σε σχέση με το ύψος του εικονοστοιχείου. Μιλάμε για πλάτος και αυτό το "τροποποιεί" το ύψος! Ας φαίνεται κάπως αδύνατο, οι χαρακτήρες έχουν σταθερό λόγο πλάτος προς ύψος άρα όταν μιλάμε για Χ πλάτος τότε μιλάμε για συγκεκριμένο Υ ύψος χαρακτήρα.  Δεν μπορεί ένας χαρακτήρας να πάρει όποιο ύψος θέλουμε. Το ύψος στην Μ2000 των χαρακτήρων τον λέμε Τύπο. Η εντολή Τύπος φτιάχνει οθόνη βάσει μεγέθους γραμμάτων. Συνήθως χρησιμοποιούμε την εντολή Φόρμα η οποία μας λέει πόσο πλάτος θέλουμε και πόσες γραμμές. Η Τύπος βγάζει τα μέγιστα που μπορεί. Μονάδες μέτρησης του Τύπου  (ύψος γραμμάτων) είναι τα points, ή στιγμές.


16.4 Ύψος Γραμμάτων ή Τύπος (στη Μ2000)


Αν θέλουμε γράμματα με μέγεθος 16 points για την γραμματοσειρά Arial το πραγματικό μέγεθος μπορεί να είναι 15.75. Το 15.75 είναι σε στιγμές, και 72 στιγμές έχει μια ίντσα. Θυμηθείτε ότι πάντα 1440 twips λέμε ότι ισοδυναμούν με μια ίντσα, είτε πραγματική είτε λογική (ψεύτικη). Αν στα ψεύτικα dpi της οθόνης (το γιατί τα λέμε ψεύτικα ή λογικά το έχουμε εξηγήσει παραπάνω), υπολογίσουμε ότι το σύστημα λογαριάζει τις στιγμές (points) που είναι μονάδες ύψους χαρακτήρων με το τύπο 1 point = 1/72 της ίντσας ή 1440/72 twips, τότε η πραγματική αναπαράσταση σε εικονοστοιχεία αναγκάζει το σύστημα (Windows ή οποιοδήποτε ) να αλλάξει το μέγεθος (και έτσι να ταιριάζει σε μια σειρά εκονοστοιχείων)! Μπορούμε να το κατανοήσουμε με το παρακάτω πρόγραμμα:


\\ Στη οθόνη μας (το πιθανότερο 96 dpi)
Τύπωσε Δεκ(16*1440/72/ύψος.σημείου)==0 \\ 0
Τύπωσε Ακ(16*1440/72/ύψος.σημείου)*ύψος.σημείου*72/1440

\\ Σε οθόνη 96dpi το ύψος σημείου είναι 15 twips
ΥΣ=15
Τύπωσε Δεκ(16*1440/72/ΥΣ)==0 \\ 0
Τύπωσε Ακ(16*1440/72/ΥΣ)*ΥΣ*72/1440 \\ 15.75
Τύπωσε 1440/ΥΣ \\ 96 dpi

\\ Σε οθόνη 120dpi το ύψος σημείου είναι 12 twips
ΥΣ=12
Τύπωσε Δεκ(16*1440/72/ΥΣ)==0 \\ 0
Τύπωσε Ακ(16*1440/72/ΥΣ)*ΥΣ*72/1440 \\ 15.6
Τύπωσε 1440/ΥΣ \\ 120 dpi

\\ Σε Mac (72dpi)
ΥΣ=20
Τύπωσε Δεκ(16*1440/72/ΥΣ)==0 \\ -1
Τύπωσε Ακ(16*1440/72/ΥΣ)*ΥΣ*72/1440 \\ 15.6
Τύπωσε 1440/ΥΣ \\ 120 dpi

\\ Σε εκτυπωτή 720 dpi
ΥΣ=2
Τύπωσε Δεκ(16*1440/72/ΥΣ)==0 \\ -1
Τύπωσε Ακ(16*1440/72/ΥΣ)*ΥΣ*72/1440 \\ 15.6
Τύπωσε 1440/ΥΣ \\ 120 dpi

Τώρα έχουμε όλα τα στοιχεία που χρειαζόμαστε για να  ετοιμάσουμε γραφικές παραστάσεις! (θα χρησιμοποιήσουμε την Επιγραφή όπως είδαμε στο κεφ. 13.11) για να εμφανίζουμε κείμενο, επιλέγοντας το μέγεθος χαρακτήρων και την γωνία (έχει και στοίχιση, π.χ. κέντρο, ως προς το σημείο που δίνουμε για εμφάνιση). Αλλά δεν έχουμε δει τις εντολές γραφικών!

16.5 Πολικές και Καρτεσιανές Συντεταγμένες


Η οθόνη της Μ2000 έχει την πάνω αριστερή γωνία ως 0,0 και αυξάνει προς τα δεξιά και προς τα κάτω.  Το 0,0 είναι το σημείο γνωστό ως κέντρο των αξόνων (η Origin). Οι άξονες δηλώνονται ως  οριζόντιος (Χ) και κάθετος (Υ), και είναι νοητοί, δηλαδή λέμε ότι το 0,5 σημείο είναι στον άξονα Υ γιατί με 0 στο Χ (οριζόντιο) πέφτει πάνω στον Υ (κάθετο). Το 5 στο Υ σημαίνει στο έκτο σημείο από το άνω μέρος (αφού τα νούμερα πάνε ανάποδα στο Κάθετο άξονα). Αυτές είναι οι καρτεσιανές συντεταγμένες.

Στη Μ2000 υπάρχει ένας δρομέας γραφικών στην Οθόνη, που είναι νοητός, δηλαδή υπάρχουν στην ουσία δυο μεταβλητές που δείχνουν σε ένα σημείο. Στο παράδειγμα παρακάτω πάμε τη θέση του δρομέα στο 6000,4000 και το ελέγχουμε διαβάζοντας τις μεταβλητές. Τη θέση 6000, 4000 την λέμε απόλυτη διότι μας δίνει επακριβώς αυτήν!

Θέση 6000, 4000 \\ απόλυτη θέση
Τύπωσε Θέση.Χ, Θέση.Υ


Μπορούμε να κινηθούμε πάνω 2000 και δεξιά 2000. Επειδή πάμε πάνω θέλουμε αρνητικό νούμερο, και επειδή πάμε δεξιά θέλουμε θετικό. Το ζεύγος τιμών -2000, 4000 είναι η σχετική θέση. Δεν ξέρουμε ποια θα είναι αν δεν την προσθέσουμε στην απόλυτη, για να γίνει απόλυτη! Η σχετική θέση είναι στην ουσία μεταθέσεις κατά τον οριζόντιο και τον κάθετο άξονα (νοητό πάντα). Πράγματι δεν έχουμε δει ακόμα να ζωγραφίζεται κάτι, μόνο αλλαγές στις μεταβλητές μόνο ανάγνωσης Θέση.Χ και Θέση.Υ. Αυτές οι μεταβλητές υποδηλώνουν ότι χρησιμοποιούμε καρτεσιανές συντεταγμένες. Εδώ θα πάρουμε το 4000, 8000

Βήμα -2000, 4000
Τύπωσε Θέση.Χ, Θέση.Υ


Υπάρχει ένας ωραίος τρόπος να κινηθούμε, χωρίς να δώσουμε μεταθέσεις, αλλά εσωτερικά θα γίνει ο υπολογισμό και θα βγει η νέα θέση (που είναι καρτεσιανή συντεταγμένη). Θα δώσουμε πολικές συντεταγμένες! Η Μ2000 χρησιμοποιεί την απόλυτη γωνία και την απόσταση. Ο δρομέας γραφικών δεν έχει προσανατολισμό, όπως η χελώνα στη Logo. Έτσι δεν έχει νόημα να λέμε στρίψε δεξιά τόσο, αλλά αν έχουμε σε μια μεταβλητή τη "πορεία" τότε μπορούμε σε αυτήν να προσθέσουμε ή να αφαιρέσουμε γωνία. Δηλαδή κρατάμε τον προσανατολισμό χωριστά, προγραμματιστικά.
Η γωνία είναι σε ακτίνια, για να δουλεύουμε με το Πι εύκολα αφού 2*Πι είναι ο κύκλος. Π.χ. Πι/2 είναι 90 μοίρες (ορθή γωνία) και σημαίνει σε απόλυτη γωνία Βορράς (το 0 είναι Ανατολή, αν κοιτάμε την Οθόνη σαν χάρτη). Στο παράδειγμα λέμε να κινηθεί ο δρομέας στην θέση Βορράς 4000, άρα στο 4000,4000. Το σύστημα δέχεται και αρνητικές γωνίες και αρνητικές αποστάσεις, που δηλώνουν αντίθετη διεύθυνση (βάζει δηλαδή ένα Πι στη γωνία που δίνουμε). Το -Πι/2 είναι στην ουσία το Πι*3/2.  Το -Πι βάζει και αυτό ένα Πι άρα Πι*1/2 + Πι*2/2 δίνει Πι/2*(1+2) ή Πι*3/2

Βήμα Γωνία Πι/2, 4000
Τύπωσε Θέση.Χ, Θέση.Υ


16.6 Κατασκευή Κάθετης Κλίμακας

Με όσα έχουμε μάθει εδώ και επιπλέον:

  • Η εντολή Χάραξε τραβάει γραμμή σε σχετική θέση (όπως η Βήμα αλλά εδώ έχουμε εμφάνιση γραμμής). Η εντολή Χάραξε Έως παίρνει απόλυτες τιμές, αλλά δεν την χρησιμοποιούμε εδώ!
  • Στην επιγραφή βάζουμε γωνία σε ακτίνια και το 2 στο τέλος σημαίνει στοίχιση στο κέντρο (του σημείου που θέλουμε, αλλά αυτό στα γράμματα θα είναι στο κέντρο και την πάνω πλευρά των γραμμάτων, όχι στο κέντρο των γραμμάτων), 

θα φτιάξουμε μια κλίμακα από 0 έως 100 όπως της εικόνας:





Θέση 3000,3000
Για Ι=100 έως 0 ανά 10 {
      Επιγραφή μορφή$("{0}",Ι), "Arial", 10, Πι/2, 2
      Βήμα 105, 0
      Χάραξε 345, 0
      Βήμα -450,0
      Βήμα Γωνία Πι/2, -300
      Βήμα 210, 0
      Χάραξε 240, 0
      Βήμα -450, 0
      Βήμα Γωνία Πι/2, -300
}
      Επιγραφή μορφή$("{0}",Ι), "Arial", 10, Πι/2, 2
      Βήμα 105, 0
      Χάραξε 345, 0
      Βήμα -450,0


Το παραπάνω δίνει από -10 έως 100, Οπότε για 0 έως 100 γράφεται και έτσι:
Θέση 3000,3000
Για Ι=100 έως 0 ανά 10
      Επιγραφή μορφή$("{0}",Ι), "Arial", 10, Πι/2, 2
      Βήμα 105, 0
      Χάραξε 345, 0
      Βήμα -450,0
      Αν Ι=0 Τότε Συνέχισε
      Βήμα Γωνία Πι/2, -300
      Βήμα 210, 0
      Χάραξε 240, 0
      Βήμα -450, 0
      Βήμα Γωνία Πι/2, -300
Επόμενο

Η Συνέχισε κάνει την επανάληψη να συνεχίσει χωρίς να εκτελέσει τις εντολές παρακάτω, οπότε επειδή το 0 είναι το τελευταίο Ι, θα τερματίσει η επανάληψη. Εδώ η Για έχει γραφτεί με την μορφή Για Επόμενο. Μια δοαφορά που έχει με την κανονική Για είναι ότι η Έξοδος πρέπει να γραφτεί ως Έξοδος Για (σαν να μιλάμε στη Καβάλα όταν σπούδαζα, θυμάμαι ήταν ένας ωραίος ιδιωματισμός, "ναι για"). Ο λόγος της διαφοράς αυτής είναι ότι στην Για Επόμενο ο διερμηνευτής χρησιμοποιεί τη στοίβα επιστροφής των ρουτινών ενώ η Για με αγκύλες είναι ένα μπλοκ κώδικα { } όπου οι εντολές Κυκλικά, Έξοδος, Συνέχισε, Ξεκίνα και Διέκοψε μπορούν να εκτελεστούν. Η Κυκλικά σηκώνει μια σημαία (επανάληψη) στο μπλοκ, έτσι όταν το μπλοκ "σωθεί", δηλαδή όταν εκτελεστούν όλες οι εντολές, τότε επαναλβάνει την εκτέλεση - ο έλεγχος της σημαίας γίνεται στο τέλος και η σημαία καθαρίζει στην νέα εκκίνηση του μπλοκ. Ο διερμηνευτής κρατάει ένα αντίγραφο του μπλοκ για τις επαναλήψεις. Παρόμοια δουλεύει και η απλή Για, αλλά εδώ πρώτα βρίσκει την Επόμενο και μετά βγάζει ένα αντίγραφο για εκτέλεση. Παλιά έβγαζε αντίγραφο μέχρι το τέλος του τμήματος με συνέπεια το μέγεθος του τμήματος να επιφέρει μεγαλύτερο φόρτο στην εκτέλεση

Η Μ2000 όπως έχει γραφτεί δεν χρησιμοποιεί κάποια ενδιάμεση μορφή κώδικα αλλά εκτελεί απευθείας από το κείμενο, αφαιρόντας ότι έχει εκτελέσει! Αυτό έγινε για να με βοηθάει να ελέγχω τον διερμηνευτή κατά την εκτέλεση μέσα από το περιβάλλον της Visual Basic 6. Ο περισσότερος κώδικας γράφτηκε ενώ έτρεχαι ο διερμηνευτής (έχει αυτήν ιδιότητα η Visual Basic, να μπορείς να αλλάζεις κώδικα και να βλέπεις ότι γίνεται κατά την εκτέλεση). Έχω φτιάξει λεκτικό αναλυτή και έναν συντακτικό αλλά χωρίς να βγάζει σφάλματα, αλλά ακόμα είναι σε δοκιμές, όπου το πρόγραμμα μετατρέπεται σε "άτομα" όπου το καθένα μπορεί να είναι κάτι απ΄όλα αυτά που γράφουμε χωρίς όμως τα σχόλια, και επιπλέον στα μπλοκ έχει σημειωμένα στην αρχή που τελειώνει και στο τέλος που αρχίζει. Επιπλέον οι αριθμοί (τα νούμερα που γράφουμε) είναι σε δυαδική μορφή και τα αλφαριθμητικά επίσης χωριστά, ώστε κατά την εκτέλεση να μην χρειάζεται ανάγνωση από τον κώδικα. Για να εκτελεστεί αυτός ο κώδικας θα πρέπει να γραφτούν όλες οι εντολές (που διάβαζαν απευθείας από το κείμενο) στην νεα μορφή. Οπότε μέχρι να τελειώσω με ότι έχω στο νου μου για τη Μ2000 θα μείνει στην άκρη το σχέδιο...αυτό. Η Visual Basic 6 βγάζει κώδικα εφάμιλλο της C++ σε ταχύτητα, και επειδή έχω ρυθμίσει κατάλληλα τον Compiler, πχ να μην κάνει έλεγχο ορίων σε πίνακες, όπως γίνεται στη C, κερδίζω σε ταχύτητα. Επιπλέον επειδή ο κώδικας εκτελεί κομάτια μνήμης που τραβάει στην μνήμη του επεξεργαστή (την πιο γρήγορη), έχει ταχύτητα. Τα ονόματα των εντολών (πάνω από 1000 επειδή είναι και σε δυο γλώσσες και επειδή υπάρχουν και συνώνυμα εντολών πχ Επανάλαβε και Επανέλαβε) τα βρίσκει σε Ο(1) με πίνακα κατακερματισμού όπου έχω φτιάξει (παρόμοιο χρησιμοποιεί και η Κατάσταση, το αντικείμενο για ζεύγη Κλειδί/Τιμή). Όταν λοιπόν βρίσκει μια εντολή ο Διερμηνευτής παίρνει από την κατάσταση την διεύθυνση εκτέλεσης της εντολής (φορτώθηκε στην εκκίνηση του διερμηνευτή) και εκτελεί άμεσα την εντολή. Οι εντολές (ο κώδικας που καλείται με τη διεύθυνση εκτέλεσης) είναι σε λίγα τμήματα των 64kbytes στην μνήμη, οπότε είναι συνέχεια φορτωμένες στην γρήγορη μνήμη! Σε κάθε τμήμα υπάρχουν short branches, δηλαδή μικρές σε μέγεθος εντολές διακλάδωσης, και λίγες far (κλήση εκτός μπλοκ 64kbytes). Και αυτό ακόμα μετράει για την ταχύτητα εκτέλεσης.

Θέση 3000,3000
Ι=100
{
      Επιγραφή μορφή$("{0}",Ι), "Arial", 10, Πι/2, 2
      Βήμα 105, 0
      Χάραξε 345, 0
      Βήμα -450,0
      Αν Ι<10 Τότε Έξοδος
      Ι-=10
      Κυκλικά
      Βήμα Γωνία Πι/2, -300
      Βήμα 210, 0
      Χάραξε 240, 0
      Βήμα -450, 0
      Βήμα Γωνία Πι/2, -300
}



(συνεχίζεται...)

Αναθεώρηση 181 και C Calls

Σε αυτήν την αναθεώρηση, τελείωσα μια εκκρεμότητα που είχα αφήσει πολύ καιρό. H M2000 μπορεί να κάνει stdCalls δηλαδή κλήσεις σε ρουτίνες του λειτουργικού (αν και προς το παρόν δεν μπορεί να περάσει structs, και εκεί έχω εκκρεμότητα). Τώρα πρόσθεσα τα C Calls δηλαδή κλήσεις σε dll που έχουν γραφεί με C.

Για να το πετύχω τροποποίησα τον ορισμό για σύνδεση με βιβλιοθήκη με κλήση stdCall βάζοντας ένα C που δηλώνει ότι έχουμε κλήση κατά C.

Στο παράδειγμα καλούμε την εντολή (συνάρτηση) της C την swprintf μιας συνάρτησης που επιστρέφει ένα νούμερο (Α) το οποίο δηλώνει πόσοι χαρακτήρες έχουν χρησιμοποιηθεί από το αλφαριθμητικό mybuf$ που περνάμε με αναφορά (by reference).
Στον ορισμό έχω δηλώσει ότι θα πάρει λίστα παραμέτρων (και αυτό σε αυτήν την αναθεώρηση το έφτιαξα).
Υπάρχει θέμα με τις κλήσεις σε C. Αν δεν γίνουν σωστά τότε έχουμε άμεσα λάθος ανεπανόρθωτο, ή fatal error. Δηλαδή δεν διορθώνει η κατάσταση, το πρόγραμμα διακόπτει την λειτουργία του!
Δείτε ότι στο P2 λέμε ότι θα δώσουμε d που σημαίνει Long, Μακρύς,  Αν δώσουμε πραγματικό  (double) τότε θα έχουμε fatal error. Για το σκοπό αυτό έφτιαξα στη Μ2000 να περνάμε στο σωρό ακέραιες τιμές άμεσα και όταν τις διαβάζει η κλήση εξωτερικής ρουτίνας να ξέρει ότι θα βάλει την τιμή σε ένα μακρύ (32 Bit).

Μπορούμε να ορίσουμε Γενικό
Όρισε Γενικό MyPrint Από C "msvcrt.swprintf" { &sBuf$, sFmt$, ... }
Κανονική μορφή όπου το 0 δηλώνει ότι θα επιστρέφει Μακρύ.
Όρισε Γενικό MyPrint Από C "msvcrt.swprintf" { &sBuf$, sFmt$, ... } ως 0



mybuf$=επαν$(χαρ$(0), 1000)
\\ Αν ορίσουμε συνάρτηση με το C πριν, τότε λέμε ότι είναι κλήση τύπου C
\\  το σύμβολο ... δηλώνει λίστα παραμέτρων. Ισχύει μόνο για το τελευταίο στοιχείο.
\\ μόνο Unicode κλήσεις για C.
Όρισε MyPrint Από C "msvcrt.swprintf" { &sBuf$, sFmt$, ... }
\\ το σύμβολο ! πριν από μια αριθμητική έκφραση για παράμετρο...
\\........λέει στον διερμηνευτή ότι θα καταχωρηθεί ως Μακρύς ή Long.
Α=MyPrint(&myBuf$, "Γειά P1=%s, P2=%d, P3=%.4f, P4=%s", "ABC", !123456, 1.23456, "xyz")
Τύπωσε Αρισ$(myBuf$,Α)




Και εδώ είναι κανονική κλήση στο λειτουργικό:

Όρισε μήνυμα Από "user32.MessageBoxW" {Μακρυς Α, κειμενο$, κειμενο2$, Μακρυς τυπος}
Τυπωσε μήνυμα(Παραθυρο, "Γεια χαρά", "Γιώργος", 2)


Η Παράθυρο είναι το hWnd ή ο handler του παραθύρου της Μ2000, και το δίνουμε για να είναι πάντα το μήνυμα μπροστά από το παράθυρο, μπροστά από την φόρμα της Μ2000.

Μπορεί κανείς να φτιάξει με όποια γλώσσα θέλει ένα COM αντικείμενο και μπορεί η Μ2000 να το προσπελάσει:
Έφτιαξα σε VB6 μια κλάση Class1 με μια μόνο συνάρτηση σε ένα Dll με όνομα project Mydll. To αποθήκευσα ως Checkme.dll. Η Vb6 το καταχώρησε στη Registry των Windows.

Function CheckMe(A As Double, B As Double) As Double
CheckMe = (A + B) / 2
End Function


Για να τρέξω τη συνάρτηση πρέπει να ορίσω ένα αντικείμενο, με το όνομα Mydll και από αυτό τη κλάση που με ενδιαφέρει, την Class1. (Το Mydll θα μπορούσε να είχε και άλλες κλάσεις). Από αυτό το αντικείμενο καλώ μια μέθοδο, την CheckMe (είναι η συνάρτηση που βλέπουμε παραπάνω). Αφού την χρησιμοποιήσω τρεις φορές την εξαφανίζω!

Όρισε Γενικό alfa "mydll.class1"
Συνάρτηση CheckMe {
      Διάβασε K, L
      Μέθοδος alfa, "checkme", K, L ως A
      =A
}
Τύπωσε CheckMe(1000,500)
Τύπωσε CheckMe(1500,500)
Τύπωσε CheckMe(2000,500)
Όρισε alfa Τίποτα

Κυριακή 6 Μαρτίου 2016

Αναθεώρηση 180, προσθήκες

Μπήκαν μερικές προσθήκες για τις εντολές ΦΕΡΕ και ΦΕΡΕΠΙΣΩ,  μπήκε μια δεύτερη παράμετρος η οποία λέει πόσα τεμάχια θα φέρει ο διερμηνευτής (στη κορυφή του σωρού)  ή θα φέρει πίσω (από την κορυφή του σωρού), στη θέση που θα υποδείξουμε, και αν δώσουμε αρνητικό αριθμό τότε θα τα μεταφέρει με την ανάποδο σειρά.

(στο σωρό "Τιμών" μπορούμε να έχουμε αλφαριθμητικά, αριθμούς, αντικείμενα, πίνακες, μέχρι και αντικείμενα γεγονότα, αλλά και αναφορές σε τιμές/αντικείμενα)
Είχα φτιάξει την Over ή Πάνω να παίρνει και δεύτερη παράμετρο για να εκτελεί πολλαπλές αντιγραφές, αλλά εδώ η Shift (Φέρε) και η ShiftBack (ΦέρεΠίσω) πήραν από δυο λειτουργίες, ο δεύτερος αριθμός ως απόλυτη τιμή λέει για πόσα "τεμάχια" ενώ αν είναι αρνητικός η μεταφορά γίνεται με την αντίστροφη σειρά, δηλαδή αν ήταν να μεταφερθεί το 4, 5 θα πάει το 5,4

Η Φέρε πάντα φέρνει στην κορυφή ενώ η ΦέρεΠίσω πάντα φέρνει από την κορυφή

Υπάρχει φυσικά και η Πέτα ή Drop όπου αν θέλουμε πετάμε έναν αριθμό στοιχείων από την κορυφή.
Με αυτή την προσθήκη έχει ολοκληρωθεί το σετ εντολών για τον σωρό.

Άδειασε \\ καθαρίζουμε το σωρό
Βάλε 1,2,3,4 \\ η βάλε βάζει πάντα στη κορυφή
Σειρά 5,6,7,8 \\ η σειρά βάζει στο τέλος
Σωρός   \\ εμφανίζουμε το 4 3 2 1 5 6 7 8 - απλά βλέπουμε!
Φέρε 4 \\ φέρνει ένα στοιχείο από τη 4η θέση στη κορυφή
Σωρός   \\ 1 4 3 2 5 6 7 8
ΦέρεΠίσω 4 \\ φέρνει πίσω στη 4η θέση το στοιχείο της κορυφής
Σωρός   \\ 4 3 2 1 5 6 7 8
Φέρε 1,-4 \\ φέρε στην 1  από την 1 θέση 4 στοιχεία σε αντίστροφη σειρά
Σωρός   \\1 2 3 4 5 6 7 8
Φέρε 1,-4 \\
Σωρός  \\ 4 3 2 1 5 6 7 8
Φέρε 5, -4 \\ φέρε στη κορυφή (1) από τη θέση 5 τέσσερα στοιχεία με την αντίστροφη σειρά!
Σωρός  \\ 8 7 6 5 4 3 2 1
Φέρε 1, -8
Σωρός  \\ 1 2 3 4 5 6 7 8
ΦέρεΠίσω 5, -4 \\ θα πάρω τέσσερα στοιχεία από κορυφή και θα τα βάλω αντίστροφα στην 5 θέση
Σωρός  \\ 5 6 7 8 4 3 2 1
ΦέρεΠίσω 5, 4 \\ ομοίως αλλά θα βάλω τέσσερα στοιχεία με την σειρά που έχουν
Σωρός  \\ 4 3 2 1 5 6 7 8
\\ τόμπολα που λέμε! Βγήκε πάλι αυτό που ήταν στην αρχή!