113 | | === Wie werden plattformunabhängige Datei-Zugriffe realisiert? === |
114 | | |
115 | | Unabhängige Trennzeichen bekommt ihr mit den Methoden: #separator, #pathSeparator, #separatorString. |
116 | | Ebenso kapselt die Klasse URI alle notwendigen Plattform-Mappings. |
117 | | |
118 | | |
119 | | === Wo finden die Konsultationen statt? === |
120 | | |
121 | | In der Kommunikationszone C.E. |
| 55 | |
| 56 | === Wie kann man einem !SystemWindow ein Icon geben? === |
| 57 | |
| 58 | Schau dir mal die "initialization" Kategorie bei den !SystemWindow Methoden an: Dort wirst du die labelArea finden, die u.a. auch für die Buttons und den Titel verantwortlich ist. Der labelArea kannst du auch Morphs hinzufügen. Einfach mal im Explorer (Alt+Shift+I) auf |
| 59 | {{{ |
| 60 | SystemWindow new openInWorld |
| 61 | }}} |
| 62 | |
| 63 | |
| 64 | === In welcher Auflösung soll das fertige Spiel laufen? === |
| 65 | |
| 66 | Das ist euch generell freigestellt. |
| 67 | |
| 68 | Wenn ihr das Spiel auf dem XO in Vollbild laufen lassen wollt, dann solltet ihr eine etwas höhere Auflösung einplanen. Der XO-1 hat eine Auflösung von 1200x900 [http://laptop.org/en/laptop/hardware/specs.shtml XO Specs] |
| 69 | |
| 70 | |
| 71 | === Wir wollen einen Morph (inklusive Submorphs) als .png Datei abspeichern. === |
| 72 | |
| 73 | Verwendet dazu Morph>>exportAsPng. |
| 74 | |
| 75 | |
| 76 | === Wie kann man einige Farben in einem Array speichern, und diese einer Variablen zuweisen, die für die Hintergrundfarbe eines Morphs zuständig ist? === |
| 77 | |
| 78 | Das !ColorArray scheint seiner Implementierung zu Folge etwas speicherfreundlicher zu sein als ein normales Array mit Color Objekten. Diese besondere Art kodiert Farben in ihre 32 Bit Repräsentation und speichert diese ab also genau 4 Byte. Beim näheren betrachten der Color Class fällt allerdings auf, dass Farben durchaus mehr Speicher in Anspruch nehmen können (durch cache Mechanismen usw.). Daher kann es in bestimmten Situation sinnvoll sein (wenn viele Farben benötigt werden z.B. in einem Bitmap oder einer Colorform) diese in nur 4 Byte abzulegen. Vermutlich kann hier auch die VM etwas optimieren, wenn grundsätzlich 4 Byte pro Element festgelegt sind. |
| 79 | |
| 80 | === Gibt es eine gute Möglichkeit in !Squeak/Morphic mit Vektorgraphikenzu arbeiten? Am besten wäre natürlich SVG. === |
| 81 | |
| 82 | Squeak hat von Haus aus keinen SVG Support. Es gibt aber das [http://map1.squeakfoundation.org/package/7318c055-ce88-4a98-8d4d-2b8cf92e1920/autoversion/4 SVGMorph Package] von Gary Chambers, das ihr euch per Installation der entsprechenden .mcz in des Image holen könnt. |
| 83 | |
| 84 | |
| 85 | === Gibt es in Squeak eine Möglichkeite Bilder in eine Package einzubetten als Ressource? Oder kann man Bilder nur aus Dateien laden? === |
| 86 | |
| 87 | Die Klasse !SystemWindow besitzt eine Reihe von Class-methods, die allesamt auf *Image enden. (z.B. SystemWindow>>menuBoxImage) |
| 88 | Diese Methoden geben Arrays zurück, die die Bildinformationen enthalten aus denen dann Form-Objekte erzeugt werden. |
| 89 | Form ist die "Squeak's Canvas". Eine Bitmap, die Bilder enthalten kann oder auf der gezeichnet |
| 90 | werden kann. Diese Objekte können dann in !ImageMorphs verwendet werden (Der dazu ähnliche !SketchMorph ist veraltet). |
| 91 | |
| 92 | |
| 93 | Bei größeren oder vielen Bildern lohnt ein Blick auf die Klassenseite von Form. |
| 94 | Da gibt es eine Methode, die aus einer Datei direkt ein Form-Objekt lädt. |
| 95 | Ähnliches findet sich auch auf den Klassenseiten von den Klassen PNGReadWriter, JPEGReadWriter, GIFReadWriter und weitere für spezielle Bildformate. |
| 96 | |
| 97 | |
| 98 | Mit Klassen wie !FileDirectory oder !FileUrl kann im Dateisystem navigiert werden. |
| 99 | Hierbei gilt es auch zu bedenken, dass die "Pathdelimiter" der Betriebssysteme unterschiedlich |
| 100 | sein können (/ oder \, ). Für Plattformunabnhängigkeit könnt ihr GRPlatform>>pathSeparator. |
| 101 | |
| 102 | |
| 103 | Wenn Bilder in Methoden (Was nicht unbedingt zu empfehlen ist) |
| 104 | und damit im Image gespeichert werden sollen, können Array-Repräsentationen |
| 105 | gewonnen werden, indem das Bild, wie oben beschrieben, in eine Form geladen wird |
| 106 | und aus dieser dann das Array (s. z.B. Form>>storeOn). |
| 107 | |
| 108 | |
| 109 | Das Speichern von Bildern im "Quellcode"/Image hat den einfachen Vorteil, dass ihr sie mit allen Teammitgliedern mit Hilfe des Monticello Source Code Repository teilen könnt. Bei externen Dateien muss leider ein anderer Weg (z.B. SVN) genutzt werden. Dennoch würden wir externe Dateien immer bevorzugen (welche nur bei Bedarf geladen und im Image gecached werden), da sie das Image klein halten. Unser Plan gegen Ende des Semester ist es alle Projekte in ein Image zu laden, daher ist es auch hier sinnvoll eure Resourcen extern im Dateisystem zu halten. Denkt bitte auch daran einen Unterordner für euer Projekt innerhalb des Squeak Verzeichnisses zu nutzen. |
| 110 | |
| 111 | |
| 112 | === Wie formatiert man Text in Squeak? === |
| 113 | |
| 114 | In Squeak gibt es auch für Text einen bestimmten Morph. |
| 115 | Den !TextMorph. Der hat auch weitere Halos, die einem |
| 116 | erlauben mögliche Kombinationen aus Schriftarten und Schriftgrößen |
| 117 | zu betrachten.. |
| 118 | |
| 119 | Ein Beispiel für sehr großen Text: |
| 120 | {{{ |
| 121 | TextMorph new |
| 122 | contents: (Text string: 'very important text' attribute: TextEmphasis italic); |
| 123 | beAllFont: (StrikeFont familyName: #BitstreamVeraSans pointSize: 120); |
| 124 | openInWorld. |
| 125 | }}} |
| 126 | |
| 127 | Anzumerken ist, dass der von Textmorphs enthaltene Text direkt auf diesem verändert werden kann. |
| 128 | Dabei ist die Eingabe in !TextMorphs durchaus gewollt. Wenn ihr dies verhindern wollt, müsst ihr sie locken. Weiterhin brechen diese Morphs automatisch den Text um, wenn der Platz (definiert durch die Bounds) nicht ausreichend ist. Das so genannte Word Wrapping kann aber auch deaktiviert werden (siehe TextMorph>>wrapOnOff). Wenn in einer Zeile mehr als nur 3-4 Zeichen geschrieben werden sollen, so muss man ihm eben mehr Platz geben also vergrößern. Beide Eigenschaften lassen sich auch mit dem vorgefertigten !TextMorph über Halos und Menüs implementieren. |
| 129 | |
| 130 | |
| 131 | === Wie kann ich das mouseDown-Event an den Owner weiterleiten? === |
| 132 | |
| 133 | Falls der Owner alle Mouse-Down-Events seiner Kinder abfangen soll, ist #mouseDownPriority die bessere Lösung. Bei #rejectsEvent: müsste jeder mögliche Submorph-Typ modifiziert werden. Dies würde Code-Duplikation bedeuten. |
| 134 | |
| 135 | |
| 136 | === Wir haben mehrere Prozesse in unserem Spiel und beim Rendern treten Artefakte in den Morphs auf. Was passiert und wie können wir das lösen? === |
| 137 | |
| 138 | Das könnte mit der Synchronisierung zu tun haben. |
| 139 | Wenn du Eigenschaften von Morphic-Objekten aus einem anderen Thread heraus veränderst, riskierst du, dass das Drawing der Objekte nur die Hälfte deiner Veränderungen mitbekommt (falls es zufällig "im selben Moment" ausgeführt wird). - Und das kann lustige Effekte haben. |
| 140 | Es gibt aber die Möglichkeit, diese Veränderungen synchron im UI-Prozess von Squeak auszuführen. Dafür fügt man eine "Deferred Message" zu einer Liste hinzu, die im UI-Thread dann später abgearbeitet wird und eure Veränderungen in einem Block kapselt. |
| 141 | Siehe dazu das folgende [http://osdir.com/ml/lang.smalltalk.squeak.general/2004-12/msg01057.html Beispiel]. |
| 142 | |
| 143 | Einfacher ist es für euch aber eventuell, wenn ihr eure Game-Logic nicht mithilfe eines neuen Threads schedulen lasst, sondern z.B. das Stepping eines einzigen Morph-Objektes für eure Game-Loop verwendet (d.h. die step-Methode dieses Objekts führt den Rumpf eurer Schleife aus und ihr setzt die stepTime entsprechend). |
| 144 | |
| 145 | |
| 146 | |
| 147 | |
| 148 | |
| 149 | == Sound == |
| 150 | |
| 151 | === Wie kann man Soundeffekte im Image abspielen? === |
| 152 | |
| 153 | Beispiel: |
| 154 | {{{ |
| 155 | (SampledSound fromWaveFileNamed: 'daffyduck1.wav') play. |
| 156 | }}} |
| 157 | |
| 158 | Allgemein lohnt sich ein Blick auf die !SoundSystem Klassen, z.B. !BaseSoundSystem und die ganze Sound-Synthesis Kathegorie. |
| 159 | |
| 160 | |
| 161 | === Gibt es eine Möglichkeit Soundeffekte aus Dateien zu laden und abzuspielen? === |
| 162 | |
| 163 | Die gibt es: |
| 164 | {{{ |
| 165 | (SampledSound fromWaveFileNamed: 'daffyduck1.wav') play |
| 166 | }}} |
| 167 | Interessante Klassen sind hier !SoundSystem default (bzw !BaseSoundSystem und die ganze Sound-Synthesis Kathegorie) |
| 168 | |
| 169 | |
| 170 | |
| 171 | |
| 172 | |
| 173 | == Image == |
| 174 | |
| 175 | === Wie kann ich ein selbst gespeichertes Image mit der VM öffnen? === |
| 176 | |
| 177 | Ändere je nach Betriebssystem die .ini oder die .sh Datei. Falls du beim starten der VM einen Dialog haben möchtest, in dem du die Imagedatei auswählen kannst, musst du nur den Pfad zum Image setzen. |
| 178 | |
| 179 | |
| 180 | === Hilfe, ich habe hunderte Morphs die alle eine falsche Methode steppen. Was kann ich sie stoppen? === |
| 181 | |
| 182 | 1.) Wenn es sich um eine einzige Methode handelt, könntest du versuchen diese mit einem "User Interrupt" zu unterbrechen: strg/alt und . (!Windows/Linux) bzw. cmd und . (Mac) |
| 183 | |
| 184 | |
| 185 | 2.) Du kannst in Squeak jeder Klasse #allInstances senden und bekommst dann eine Liste, die alle Objekte der Klasse enthält. An diese Liste können dann mit dem Collection Protocol (z.B. #do:) Nachrichten an alle Objekte geschickt werden. Somit kannst du die Objekte bearbeiten oder mittels stopStepping zum Stillstand bringen. |
177 | | === Wie kann man einem !SystemWindow ein Icon geben? === |
178 | | |
179 | | Schau dir mal die "initialization" Kategorie bei den !SystemWindow Methoden an: Dort wirst du die labelArea finden, die u.a. auch für die Buttons und den Titel verantwortlich ist. Der labelArea kannst du auch Morphs hinzufügen. Einfach mal im Explorer (Alt+Shift+I) auf |
180 | | {{{ |
181 | | !SystemWindow new openInWorld |
182 | | }}} |
183 | | |
184 | | |
185 | | === In welcher Auflösung soll das fertige Spiel laufen? === |
186 | | |
187 | | Das ist euch generell freigestellt. |
188 | | |
189 | | Wenn ihr das Spiel auf dem XO in Vollbild laufen lassen wollt, dann solltet ihr eine etwas höhere Auflösung einplanen. Der XO-1 hat eine Auflösung von 1200x900 [http://laptop.org/en/laptop/hardware/specs.shtml XO Specs] |
190 | | |
191 | | |
192 | | === Hat Squeak einen integrierten Eventhandler für Netzwerkevents? Wie kann man eine Methode aufrufen, sobald Daten angekommen sind? === |
193 | | |
194 | | Das kommt sehr auf eure Netzwerkimplementierung an. Nutz ihr ein Standardprotokoll, so sollte die verwendete Bibliothek im Allgemeinen auch entsprechende Methoden bereitstellen. Häufig sind diese transparent, so dass die Methoden automatisch gerufen werden, sobald ein neuer Request eintrifft. Um Beispiele dafür zu sehen, schaut euch einmal im Image den WAListener an, welcher den Webserver für Seaside implementiert. Dort wird auch gezeigt wie man Prozesse "forked" um mehrere Requests gleichzeitig zu behandeln. |
195 | | |
196 | | Von dem Ansatz die ganze Sache in Morphic und dessen #step Methode abzubilden, raten wir schlichtweg ab. Der Grund: die #step Methode ist nur scheinbar parallelisiert und sollte eine Methode auf SocketStream>>#isDataAvailable warten, steht das ganze System. Ihr müsste also auf jeden Fall mit mehreren Prozessen arbeiten. Dafür verwendet ihr wie gesagt die ``fork``-methode. |
197 | | |
198 | | Um das Warten zu realisieren, schaut euch die Klasse Delay an. |
199 | | Es gibt aber noch weiter Synchronisationsprimitiven, insbesondere wenn ihr Sockets benutzt: |
200 | | Je nachdem ob ihr Socket oder !SocketStream verwendet, gibt es entsprechende Methoden die sich schlafen legen bis Daten verfügbar sind, z.B. Socket>>#waitForData (siehe Kommentar). |
201 | | |
202 | | Die Netzwerkfähigkeit wäre zwar sicher ein schönes Feature ist aber ohne entsprechende Vorkenntnisse in dem Bereich nicht ganz einfach. Überlegt es euch daher vielleicht, ob ihr dies wirklich implementieren möchtet. |
| 252 | === Wie werden plattformunabhängige Datei-Zugriffe realisiert? === |
| 253 | |
| 254 | Unabhängige Trennzeichen bekommt ihr mit den Methoden: #separator, #pathSeparator, #separatorString. |
| 255 | Ebenso kapselt die Klasse URI alle notwendigen Plattform-Mappings. |
| 256 | |
| 257 | |
| 258 | |
| 259 | === Wie können mehrere Schritte rückgängig gemacht werden? === |
| 260 | |
| 261 | In den Einstellungen findet sich die Option "multipleTextUndo". Aktiviert diese und ihr könnt mehrere Schritte rückgängig machen. Mittels Strg + Z bzw cmd + Z könnt ihr die letzte Änderung rückgängig machen. Mehrmals zurück geht lediglich über Squeaks changes. Klickt dazu im Browser auf versions und wählt eure letzte Änderung aus. |
253 | | === State und Strategy Pattern – Was ist der Unterschied? === |
254 | | |
255 | | Die Strukturen der beiden Muster sind schon sehr ähnlich aber was sie wesentlich unterscheidet ist ihre Intention. Beim State Pattern geht es darum einen Zustand abzubilden und mit diesem verschiedenes Verhalten zu erzeugen. Die Verhaltensvariation unterliegt also der Zustandsklasse und der Client setzt hauptsächlich seinen Zustand und nutzt diesen. Beim Strategy Muster entscheidet der Client aber bewusst ein anderes Verhalten zu benutzen und kennt daher dessen Umsetzung, Vor- und Nachteile. Im GoF Buch gibt es für State das Beispiel der TCP Connection, welche je nach Zustand zwar die selben Nachrichten versteht aber unterschiedlich reagiert.Hingegen beim Strategy |
256 | | Muster wurde ein Compositor zur Ausgabe von Text gewählt, hier entscheidet der Client ganz bewusst die Ausgabe in TeX oder normalen Text zu rendern |
257 | | . |
258 | | über die Häufigkeit des Austauschens würde ich jedoch keine Aussage treffen wollen, da dies sehr vom Anwendungsfall abhängt. |
259 | | Der Zustand der Strategy Algorithmen sollte keinen direkten Einfluss auf den Zustand des Clients haben. Beim State kann das jedoch der Fall sein, z.B. ist die TCPConnection abgebrochen und der Client zeigt eine Fehlermeldung |
260 | | durch diesen neuen Zustand. |
261 | | |
262 | | |
263 | | === Ist Late Binding das Mittel, um Polymorphie zu erreichen und hat ohne diesen keine Funktion? === |
264 | | |
265 | | Polymorhpie kann auch ohne späte Bindung erreicht werden. Zum Beispiel in C++ stehen polymorphe Methoden schon zur Übersetzungszeit fest, wenn sie nicht mit dem Schlüsselwort "virtual" markiert sind [http://en.wikipedia.org/wiki/Late_binding#Late_binding_in_C.2B.2B Dynamic Dispatch in C++]. Late binding ermöglicht polymorphe Methoden auf Objekten, deren Klasse erst zur Laufzeit bestimmt werden kann. |
266 | | |
267 | | Vererbung und Polymorphie sind nicht notwendig, um objektorientierte Abstraktion zu ermöglichen; Sie werden jedoch aus praktischen Gründen in OO-Sprachen sehr gerne eingesetzt. Die Darstellung von OOP zieht oft fälschlicherweise diese beiden Konzepte als zentral und unabdingbar heran. Sprachen wie z. B. !JavaScript und Self nutzen Delegation an Stelle von Vererbung. Sie sind objektorientiert, kommen aber auch ohne Klassen aus. |
268 | | |
269 | | |
270 | | === Ist in Squeak eine Implementierung der MD5-Verschlüsselung vorhanden? === |
271 | | |
272 | | Das Cryptography package sollte alle notwendigen Funktionen liefern. |
273 | | Dort habt ihr eine MD5 Klasse. Folgt dem Beispiel in der Methode |
274 | | #hashStream:. Aber Achtung, [http://de.wikipedia.org/wiki/MD5 MD5] ist sehr unsicher, da sehr leicht Kollisionen gefunden werden können. |
275 | | Seaside nutzt deswegen üblicherweise den SHA Algorithmus. Diesen könnt ihr bereits in eurem Image finden unter der Klasse ``SecureHashAlgorithm`. Dort schaut euch einfach die Methoden unter dem 'public' Protokoll an. |
276 | | |
277 | | |
278 | | === In Seaside "clean" URLs (ohne _s und _k) === |
| 294 | === Kann man aus dem Debugfenster den Callstack rauskopieren? === |
| 295 | |
| 296 | Wenn der Debugger geöffnet ist, kann man z.B. im Menü (Rechtsklick o.ä. auf die Titelleiste) |
| 297 | "copy text" wählen. Dann ist der dargestellte Callstack in die Zwischenablage kopiert und kann gewohnt in allen Anwendungen eingefügt werden. |
| 298 | |
| 299 | |
| 300 | |
| 301 | |
| 302 | |
| 303 | == Seaside == |
| 304 | |
| 305 | === In Seaside: "clean" URLs (ohne _s und _k) === |
355 | | |
356 | | |
357 | | === Gibt es eine gute Möglichkeit in !Squeak/Morphic mit Vektorgraphikenzu arbeiten? Am besten wäre natürlich SVG. === |
358 | | |
359 | | Squeak hat von Haus aus keinen SVG Support. Es gibt aber das [http://map1.squeakfoundation.org/package/7318c055-ce88-4a98-8d4d-2b8cf92e1920/autoversion/4 SVGMorph Package] von Gary Chambers, das ihr euch per Installation der entsprechenden .mcz in des Image holen könnt. |
360 | | |
361 | | |
362 | | === Gibt es in Squeak eine Möglichkeite Bilder in eine Package einzubetten als Ressource? Oder kann man Bilder nur aus Dateien laden? === |
363 | | |
364 | | Die Klasse !SystemWindow besitzt eine Reihe von Class-methods, die allesamt auf *Image enden. (z.B. SystemWindow>>menuBoxImage) |
365 | | Diese Methoden geben Arrays zurück, die die Bildinformationen enthalten aus denen dann Form-Objekte erzeugt werden. |
366 | | Form ist die "Squeak's Canvas". Eine Bitmap, die Bilder enthalten kann oder auf der gezeichnet |
367 | | werden kann. Diese Objekte können dann in !ImageMorphs verwendet werden (Der dazu ähnliche !SketchMorph ist veraltet). |
368 | | |
369 | | |
370 | | Bei größeren oder vielen Bildern lohnt ein Blick auf die Klassenseite von Form. |
371 | | Da gibt es eine Methode, die aus einer Datei direkt ein Form-Objekt lädt. |
372 | | Ähnliches findet sich auch auf den Klassenseiten von den Klassen !PNGReadWriter, !JPEGReadWriter, !GIFReadWriter und weitere für spezielle Bildformate. |
373 | | |
374 | | |
375 | | Mit Klassen wie !FileDirectory oder !FileUrl kann im Dateisystem navigiert werden. |
376 | | Hierbei gilt es auch zu bedenken, dass die "Pathdelimiter" der Betriebssysteme unterschiedlich |
377 | | sein können (/ oder \, ). Für Plattformunabnhängigkeit könnt ihr GRPlatform>>pathSeparator. |
378 | | |
379 | | |
380 | | Wenn Bilder in Methoden (Was nicht unbedingt zu empfehlen ist) |
381 | | und damit im Image gespeichert werden sollen, können Array-Repräsentationen |
382 | | gewonnen werden, indem das Bild, wie oben beschrieben, in eine Form geladen wird |
383 | | und aus dieser dann das Array (s. z.B. Form>>storeOn). |
384 | | |
385 | | |
386 | | Das Speichern von Bildern im "Quellcode"/Image hat den einfachen Vorteil, dass ihr sie mit allen Teammitgliedern mit Hilfe des Monticello Source Code Repository teilen könnt. Bei externen Dateien muss leider ein anderer Weg (z.B. SVN) genutzt werden. Dennoch würden wir externe Dateien immer bevorzugen (welche nur bei Bedarf geladen und im Image gecached werden), da sie das Image klein halten. Unser Plan gegen Ende des Semester ist es alle Projekte in ein Image zu laden, daher ist es auch hier sinnvoll eure Resourcen extern im Dateisystem zu halten. Denkt bitte auch daran einen Unterordner für euer Projekt innerhalb des Squeak Verzeichnisses zu nutzen. |
387 | | |
388 | | |
389 | | === Woher ist gute Einführungsliteratur für Squeak zu finden? === |
390 | | |
391 | | Das Buch [http://www.squeakbyexample.org/ Squeak by Example] ist besonders geeignet, da es explizit auf |
392 | | alle wichtigen Tools in Squeak und auch auf das Morphic-Framework |
393 | | eingeht. Außerdem wird an vielen Beispielen die minimale Syntax und |
394 | | wichtige Konzepte wie die Nachrichtenbasierung erklärt. |
395 | | |
396 | | Weiterhin gibt es noch einige praktische Tutorials zu Morphic |
397 | | im Squeak-Wiki, die auch Hinweise zur Arbeit mit Squeak geben. |
398 | | [http://wiki.squeak.org/squeak/792#Morphic Morphic-Wiki] |
399 | | |
400 | | Zum Einstieg in !Squeak/Smalltalk sind viele gute Bücher kostenlos |
401 | | verfügbar. Eine gute Übersicht bietet: |
402 | | [href="http://stephane.ducasse.free.fr/FreeBooks.html Free Books] |
403 | | |
404 | | |
405 | | === Wie stellt man am Besten Text in Squeak dar? === |
406 | | |
407 | | In Squeak gibt es auch für Text einen bestimmten Morph. |
408 | | Den !TextMorph. Der hat auch weitere Halos, die einem |
409 | | erlauben mögliche Kombinationen aus Schriftarten und Schriftgrößen |
410 | | zu betrachten.. |
411 | | |
412 | | Ein Beispiel für sehr großen Text: |
413 | | {{{ |
414 | | TextMorph new |
415 | | contents: (Text string: 'very important text' attribute: TextEmphasis italic); |
416 | | beAllFont: (StrikeFont familyName: #BitstreamVeraSans pointSize: 120); |
417 | | openInWorld. |
418 | | }}} |
419 | | |
420 | | Anzumerken ist, dass der von Textmorphs enthaltene Text direkt auf diesem verändert werden kann. |
421 | | Dabei ist die Eingabe in !TextMorphs durchaus gewollt. Wenn ihr dies verhindern wollt, müsst ihr sie locken. Weiterhin brechen diese Morphs automatisch den Text um, wenn der Platz (definiert durch die Bounds) nicht ausreichend ist. Das so genannte Word Wrapping kann aber auch deaktiviert werden (siehe TextMorph>>wrapOnOff). Wenn in einer Zeile mehr als nur 3-4 Zeichen geschrieben werden sollen, so muss man ihm eben mehr Platz geben also vergrößern. Beide Eigenschaften lassen sich auch mit dem vorgefertigten !TextMorph über Halos und Menüs implementieren. |
422 | | |
423 | | |
424 | | === Wie konkateniert man Strings? === |
425 | | |
426 | | Das geht mit dem Komma-Operator. |
427 | | Die Konkatenation von Tabs an Strings geht beispielsweise so: |
428 | | {{{ |
429 | | 'abc' , String tab , 'abc' |
430 | | }}} |
431 | | oder auch |
432 | | {{{ |
433 | | 'abc' , Character tab , 'abc' |
434 | | }}} |
435 | | da String>>#, die Nachricht #asString an seinen Parameter sendet. Unterschiedlich sieht das nur aus wenn man es per print it (cmd/strg + p) ausgibt, da tab halt je nach Position in unterschiedlicher Länge gerendert wird. Die Strings sind aber gleich (im Sinne von #=). |
436 | | |
437 | | Bedenkt bitte, dass ihr bei sehr komplexen String Konkatenationen besser auf Streams zurückgreifen solltet: |
438 | | {{{ |
439 | | String streamContents: [:stream | |
440 | | stream |
441 | | nextPutAll: 'abc'; |
442 | | tab; |
443 | | nextPutAll: 'abc']. |
444 | | }}} |
445 | | |
446 | | === Kann man aus dem Debugfenster den Callstack rauskopieren? === |
447 | | |
448 | | Wenn der Debugger geöffnet ist, kann man z.B. im Menü (Rechtsklick o.ä. auf die Titelleiste) |
449 | | "copy text" wählen. Dann ist der dargestellte Callstack in die Zwischenablage kopiert und kann gewohnt in allen Anwendungen eingefügt werden. |
450 | | |
451 | | |
452 | | === Setzt man in Smalltalk nach dem return einen Punkt oder nicht? === |
453 | | |
454 | | Der Punk separiert Ausdrücke und ist deswegen nach dem letzten Ausdruck nicht mehr notwendig. Im Allgemeinen ist es nur wichtig, dass ihr es konsequent überall gleich macht. Wir bevorzugen zwar die Variante ohne Punkt aber dies sollte auf eure Wahl keine Auswirkung haben. |
| 383 | |
| 384 | |
| 385 | |
| 386 | |
| 387 | == Lehrveranstaltung == |
| 388 | |
| 389 | |
| 390 | === Wie sind meine Zugangsdaten zu Squeaksource? === |
| 391 | |
| 392 | Benutzername ist der HPI Benutzername und das Password wurde dir per Mail geschickt. Bitte ändere dein initiales Passwort. |
| 393 | |
| 394 | |
| 395 | === Wo finden die Konsultationen statt? === |
| 396 | |
| 397 | In der Kommunikationszone C.E. |
| 398 | |
| 399 | |
| 400 | === Wie erstelle ich das SAR-Archiv für die Abgabe? === |
| 401 | |
| 402 | Bei SARs handelt es sich nur um ZIPs mit etwas Smalltalk Quellcode (preamble, postscript Dateien). Ihr könnt sie einfach von Hand erstellen. Daher wäre es schön, wenn ihr einfach alles in ein ZIP packt, die 1-2 Zeilen Code zum Laden des MCZ Packages schreibt und dann gebündelt in einem SAR abgebt. Denkt daran, dass ihr auch Ressourcen wie Bilder und Audiodateien mit reinpackt und beim Installieren des SARs extrahiert. |
| 403 | |
| 404 | Hier findet ihr grundlegende Informationen und Tools, die euch bei der Erstellung helfen: |
| 405 | |
| 406 | [http://www.visoracle.com/squeak/faq/sar-installer.html SAR-Installer HowTo] |
| 407 | |
| 408 | [http://wiki.squeak.org/squeak/3324 SAR-Installer Dokumentation] |
| 409 | |
| 410 | |
| 411 | === Welchen Umfang sollten die Projekte haben? === |
| 412 | |
| 413 | Die Anforderungen, welche durch die Spiele umgesetzt werden sollen, reflektieren auch den Umfang des Projektes. Alle Projekte wurden so gewählt (oder von uns freigegeben), sodass sie einerseits mit 4 Studenten in der vorhandenen Zeit sehr gut realisierbar sind und andererseits auch ausreichend Raum lassen, um eine sehr gute Architektur zu entwickeln. |
| 414 | |
| 415 | Eine Zahl entsprechend der Menge an Quelltext lässt sich nur schwer bestimmen, da es von zu vielen Faktoren abhängt (Verwendung von Mustern, Kenntnis der Smalltalk Bibliothek, Benutzte Abstraktionen etc.). Falls es euch hilft: Wir hatten schon sehr gute Projekte, welche nur knapp 1.000 Zeilen geschrieben haben aber auch sehr gute mit mehr als 4.000 Zeilen. Versucht euch am Besten dazwischen einzupendeln und setzt euren Fokus lieber auf Qualität statt Quantität. Uns geht es in dieser Lehrveranstaltung vor allem darum, dass ihr lernt und versteht, was es heißt "schönen" Code zuschreiben. |
| 416 | |
| 417 | |
| 418 | |
| 419 | |
| 420 | == Ohne Kategorie == |
| 421 | |
| 422 | === Hat Squeak einen Eventhandler für Netzwerkevents? Wie kann man eine Methode aufrufen, sobald Daten angekommen sind? === |
| 423 | |
| 424 | Das kommt sehr auf eure Netzwerkimplementierung an. Nutz ihr ein Standardprotokoll, so sollte die verwendete Bibliothek im Allgemeinen auch entsprechende Methoden bereitstellen. Häufig sind diese transparent, so dass die Methoden automatisch gerufen werden, sobald ein neuer Request eintrifft. Um Beispiele dafür zu sehen, schaut euch einmal im Image den WAListener an, welcher den Webserver für Seaside implementiert. Dort wird auch gezeigt wie man Prozesse "forked" um mehrere Requests gleichzeitig zu behandeln. |
| 425 | |
| 426 | Von dem Ansatz die ganze Sache in Morphic und dessen #step Methode abzubilden, raten wir schlichtweg ab. Der Grund: die #step Methode ist nur scheinbar parallelisiert und sollte eine Methode auf SocketStream>>#isDataAvailable warten, steht das ganze System. Ihr müsste also auf jeden Fall mit mehreren Prozessen arbeiten. Dafür verwendet ihr wie gesagt die ``fork``-methode. |
| 427 | |
| 428 | Um das Warten zu realisieren, schaut euch die Klasse Delay an. |
| 429 | Es gibt aber noch weiter Synchronisationsprimitiven, insbesondere wenn ihr Sockets benutzt: |
| 430 | Je nachdem ob ihr Socket oder !SocketStream verwendet, gibt es entsprechende Methoden die sich schlafen legen bis Daten verfügbar sind, z.B. Socket>>#waitForData (siehe Kommentar). |
| 431 | |
| 432 | Die Netzwerkfähigkeit wäre zwar sicher ein schönes Feature ist aber ohne entsprechende Vorkenntnisse in dem Bereich nicht ganz einfach. Überlegt es euch daher vielleicht, ob ihr dies wirklich implementieren möchtet. |
| 433 | |
| 434 | |
| 435 | === Wie viel Kommentare sind nötig/erwünscht? === |
| 436 | |
| 437 | Eine einfache Regel besagt: "So viel wie nötig, so wenig wie möglich". |
| 438 | Schaut euch einfach noch einmal die Idiome zum Kommentieren an (findet ihr |
| 439 | in den Vorlesungsfolien, sowohl von Kent Beck als auch Dave Thomas). |
| 440 | |
| 441 | |
| 442 | |
| 443 | === State und Strategy Pattern – Was ist der Unterschied? === |
| 444 | |
| 445 | Die Strukturen der beiden Muster sind schon sehr ähnlich aber was sie wesentlich unterscheidet ist ihre Intention. Beim State Pattern geht es darum einen Zustand abzubilden und mit diesem verschiedenes Verhalten zu erzeugen. Die Verhaltensvariation unterliegt also der Zustandsklasse und der Client setzt hauptsächlich seinen Zustand und nutzt diesen. Beim Strategy Muster entscheidet der Client aber bewusst ein anderes Verhalten zu benutzen und kennt daher dessen Umsetzung, Vor- und Nachteile. Im GoF Buch gibt es für State das Beispiel der TCP Connection, welche je nach Zustand zwar die selben Nachrichten versteht aber unterschiedlich reagiert.Hingegen beim Strategy |
| 446 | Muster wurde ein Compositor zur Ausgabe von Text gewählt, hier entscheidet der Client ganz bewusst die Ausgabe in TeX oder normalen Text zu rendern |
| 447 | . |
| 448 | über die Häufigkeit des Austauschens würde ich jedoch keine Aussage treffen wollen, da dies sehr vom Anwendungsfall abhängt. |
| 449 | Der Zustand der Strategy Algorithmen sollte keinen direkten Einfluss auf den Zustand des Clients haben. Beim State kann das jedoch der Fall sein, z.B. ist die TCPConnection abgebrochen und der Client zeigt eine Fehlermeldung |
| 450 | durch diesen neuen Zustand. |
| 451 | |
| 452 | |
| 453 | === Ist Late Binding das Mittel, um Polymorphie zu erreichen und hat ohne diesen keine Funktion? === |
| 454 | |
| 455 | Polymorhpie kann auch ohne späte Bindung erreicht werden. Zum Beispiel in C++ stehen polymorphe Methoden schon zur Übersetzungszeit fest, wenn sie nicht mit dem Schlüsselwort "virtual" markiert sind [http://en.wikipedia.org/wiki/Late_binding#Late_binding_in_C.2B.2B Dynamic Dispatch in C++]. Late binding ermöglicht polymorphe Methoden auf Objekten, deren Klasse erst zur Laufzeit bestimmt werden kann. |
| 456 | |
| 457 | Vererbung und Polymorphie sind nicht notwendig, um objektorientierte Abstraktion zu ermöglichen; Sie werden jedoch aus praktischen Gründen in OO-Sprachen sehr gerne eingesetzt. Die Darstellung von OOP zieht oft fälschlicherweise diese beiden Konzepte als zentral und unabdingbar heran. Sprachen wie z. B. !JavaScript und Self nutzen Delegation an Stelle von Vererbung. Sie sind objektorientiert, kommen aber auch ohne Klassen aus. |
| 458 | |
| 459 | |
| 460 | === Ist in Squeak eine Implementierung der MD5-Verschlüsselung vorhanden? === |
| 461 | |
| 462 | Das Cryptography package sollte alle notwendigen Funktionen liefern. |
| 463 | Dort habt ihr eine MD5 Klasse. Folgt dem Beispiel in der Methode |
| 464 | #hashStream:. Aber Achtung, [http://de.wikipedia.org/wiki/MD5 MD5] ist sehr unsicher, da sehr leicht Kollisionen gefunden werden können. |
| 465 | Seaside nutzt deswegen üblicherweise den SHA Algorithmus. Diesen könnt ihr bereits in eurem Image finden unter der Klasse ``SecureHashAlgorithm`. Dort schaut euch einfach die Methoden unter dem 'public' Protokoll an. |
| 466 | |
| 467 | |
| 468 | === Gibt es in Squeak so etwas wie eine !FileDialog Klasse? === |
| 469 | |
| 470 | Helfen kann euch hier die Klasse !FileList. |
| 471 | |
| 472 | |
| 473 | === Was ist die richtige Art, Klassenvariablen anzulegen? Auf Instanzseite in ``classVariableNames:`` oder auf Klassenseite in ``instanceVariableNames:``? === |
| 474 | |
| 475 | Dafür ist die instanzseitige Klassenvariable die richtige Wahl. Die klassenseitige Instanzvariable existiert nur auf Grund der Tatsache, dass Squeak ein Metaobjectprotocol besitzt und somit Klassen selbst wieder Instanz einer anderen Klasse sind. Daher besitzen sie auch Instanzvariablen. Allerdings sind die Instanzvariablen auch nur für die Klasse und nicht für Ihre Instanzen einsehbar. |
| 476 | Um Klassenvariablen (sowohl Klasse als auch Instanzen der Klasse können in Methoden darauf zugreifen) zu erhalten, sind somit die instanzseitigen Klassenvariablen die richtige Wahl. |
| 477 | Uns hatte man damals für den Singletonfall auch geraten, die Instanzseite zu nehmen, um die Singletoninstanz zu speichern. |
| 478 | |
| 479 | Erklärung nach http://www.faqs.org/faqs/smalltalk-faq/: |
| 480 | |
| 481 | Q6. What are class instance variables? |
| 482 | Ans. Class instance variables are similar to class variables, except that they are created for eachsubclass of the defining class. When a class declares a class instance variable, a new variable is created for each subclass of that class. Each subclass then has its own instance of the variable and retains its own value for the variable, but each subclass has a variable with the same name. Only class methods of a class and its subclasses can refer to class instance variables; instance methods cannot. |
| 483 | |
| 484 | |
| 485 | === Woher ist gute Einführungsliteratur für Squeak zu finden? === |
| 486 | |
| 487 | Das Buch [http://www.squeakbyexample.org/ Squeak by Example] ist besonders geeignet, da es explizit auf |
| 488 | alle wichtigen Tools in Squeak und auch auf das Morphic-Framework |
| 489 | eingeht. Außerdem wird an vielen Beispielen die minimale Syntax und |
| 490 | wichtige Konzepte wie die Nachrichtenbasierung erklärt. |
| 491 | |
| 492 | Weiterhin gibt es noch einige praktische Tutorials zu Morphic |
| 493 | im Squeak-Wiki, die auch Hinweise zur Arbeit mit Squeak geben. |
| 494 | [http://wiki.squeak.org/squeak/792#Morphic Morphic-Wiki] |
| 495 | |
| 496 | Zum Einstieg in !Squeak/Smalltalk sind viele gute Bücher kostenlos |
| 497 | verfügbar. Eine gute Übersicht bietet: |
| 498 | [href="http://stephane.ducasse.free.fr/FreeBooks.html Free Books] |
| 499 | |
| 500 | |
| 501 | === Wie konkateniert man Strings? === |
| 502 | |
| 503 | Das geht mit dem Komma-Operator. |
| 504 | Die Konkatenation von Tabs an Strings geht beispielsweise so: |
| 505 | {{{ |
| 506 | 'abc' , String tab , 'abc' |
| 507 | }}} |
| 508 | oder auch |
| 509 | {{{ |
| 510 | 'abc' , Character tab , 'abc' |
| 511 | }}} |
| 512 | da String>>#, die Nachricht #asString an seinen Parameter sendet. Unterschiedlich sieht das nur aus wenn man es per print it (cmd/strg + p) ausgibt, da tab halt je nach Position in unterschiedlicher Länge gerendert wird. Die Strings sind aber gleich (im Sinne von #=). |
| 513 | |
| 514 | Bedenkt bitte, dass ihr bei sehr komplexen String Konkatenationen besser auf Streams zurückgreifen solltet: |
| 515 | {{{ |
| 516 | String streamContents: [:stream | |
| 517 | stream |
| 518 | nextPutAll: 'abc'; |
| 519 | tab; |
| 520 | nextPutAll: 'abc']. |
| 521 | }}} |
| 522 | |
| 523 | |
| 524 | === Setzt man in Smalltalk nach dem return einen Punkt oder nicht? === |
| 525 | |
| 526 | Der Punk separiert Ausdrücke und ist deswegen nach dem letzten Ausdruck nicht mehr notwendig. Im Allgemeinen ist es nur wichtig, dass ihr es konsequent überall gleich macht. Wir bevorzugen zwar die Variante ohne Punkt aber dies sollte auf eure Wahl keine Auswirkung haben. |
| 527 | |
| 528 | |
510 | | === Welchen Umfang sollten die Projekte haben? === |
511 | | |
512 | | Die Anforderungen, welche durch die Spiele umgesetzt werden sollen, reflektieren auch den Umfang des Projektes. Alle Projekte wurden so gewählt (oder von uns freigegeben), sodass sie einerseits mit 4 Studenten in der vorhandenen Zeit sehr gut realisierbar sind und andererseits auch ausreichend Raum lassen, um eine sehr gute Architektur zu entwickeln. |
513 | | |
514 | | Eine Zahl entsprechend der Menge an Quelltext lässt sich nur schwer bestimmen, da es von zu vielen Faktoren abhängt (Verwendung von Mustern, Kenntnis der Smalltalk Bibliothek, Benutzte Abstraktionen etc.). Falls es euch hilft: Wir hatten schon sehr gute Projekte, welche nur knapp 1.000 Zeilen geschrieben haben aber auch sehr gute mit mehr als 4.000 Zeilen. Versucht euch am Besten dazwischen einzupendeln und setzt euren Fokus lieber auf Qualität statt Quantität. Uns geht es in dieser Lehrveranstaltung vor allem darum, dass ihr lernt und versteht, was es heißt "schönen" Code zuschreiben. |
515 | | |
516 | | |
517 | | === Wie kann ich das mouseDown-Event an den Owner weiterleiten? === |
518 | | |
519 | | Falls der Owner alle Mouse-Down-Events seiner Kinder abfangen soll, ist #mouseDownPriority die bessere Lösung. Bei #rejectsEvent: müsste jeder mögliche Submorph-Typ modifiziert werden. Dies würde Code-Duplikation bedeuten. |
520 | | |
521 | | |
522 | | === Wir haben mehrere Prozesse in unserem Spiel und beim Rendern treten Artefakte in den Morphs auf. Was passiert und wie können wir das lösen? === |
523 | | |
524 | | Das könnte mit der Synchronisierung zu tun haben. |
525 | | Wenn du Eigenschaften von Morphic-Objekten aus einem anderen Thread heraus veränderst, riskierst du, dass das Drawing der Objekte nur die Hälfte deiner Veränderungen mitbekommt (falls es zufällig "im selben Moment" ausgeführt wird). - Und das kann lustige Effekte haben. |
526 | | Es gibt aber die Möglichkeit, diese Veränderungen synchron im UI-Prozess von Squeak auszuführen. Dafür fügt man eine "Deferred Message" zu einer Liste hinzu, die im UI-Thread dann später abgearbeitet wird und eure Veränderungen in einem Block kapselt. |
527 | | Siehe dazu das folgende [http://osdir.com/ml/lang.smalltalk.squeak.general/2004-12/msg01057.html Beispiel]. |
528 | | |
529 | | Einfacher ist es für euch aber eventuell, wenn ihr eure Game-Logic nicht mithilfe eines neuen Threads schedulen lasst, sondern z.B. das Stepping eines einzigen Morph-Objektes für eure Game-Loop verwendet (d.h. die step-Methode dieses Objekts führt den Rumpf eurer Schleife aus und ihr setzt die stepTime entsprechend). |
530 | | |
531 | | |
532 | | === Ich habe eine nebenläufige Anwendung programmiert, bei der mir ein Prozess abhanden gekommen ist und der jetzt weiter im Hintergrund läuft. Wie kann ich diesen beenden? === |
533 | | |
534 | | Du kannst im Process-Browser mit Rechtsklick->Explore auf den betreffenden Prozess den Object Explorer öffnen, und in diesem dann "self terminate." ausführen. |
535 | | |
536 | | |