Zurück   Flashforum > Flash > ActionScript > Softwarearchitektur und Entwurfsmuster

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 30-06-2003, 10:40   #1 (permalink)
[+]
 
Benutzerbild von André Michelle
 
Registriert seit: Dec 2002
Ort: cologne
Beiträge: 2.271
magic switch

hallo zusammen,


'switch' ist nicht das, was man erwartet, oder ?

Warum werden ab einer erfüllten Bedingung die weiteren cases ausgeführt ? Welche Gründe gibt es für dieses Verhalten ?

ActionScript:
  1. var prop = 10;
  2.  
  3. switch ( prop ) {
  4.  
  5.     case 9:
  6.  
  7.         trace ( "9" );
  8.  
  9.     case 10:
  10.  
  11.         trace ( "10" );
  12.  
  13.     case 11:
  14.  
  15.         trace ( "11" ); // 11
  16.  
  17.         break;
  18.  
  19.     case 12:
  20.  
  21.         trace ( "12" ); // nix
  22.  
  23. }

Das es so ist, wie es ist sehe ich :o)
Aber woher kommt so eine seltsame Interpretation...
__________________
aM

blog | laboratory | tonfall | processing

Audiotool.com
André Michelle ist offline   Mit Zitat antworten
Alt 30-06-2003, 10:47   #2 (permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
Dafür gibt es break.

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 30-06-2003, 11:15   #3 (permalink)
[+]
 
Benutzerbild von André Michelle
 
Registriert seit: Dec 2002
Ort: cologne
Beiträge: 2.271
Bokel, du könntest Dir gerne mal die Mühe machen, Beiträge bis zum Ende zu lesen :o)
__________________
aM

blog | laboratory | tonfall | processing

Audiotool.com
André Michelle ist offline   Mit Zitat antworten
Alt 30-06-2003, 11:19   #4 (permalink)
zeitreisender
 
Benutzerbild von emax
 
Registriert seit: Aug 2001
Ort: Hannover
Beiträge: 1.577
den sinn dieses verhaltens habe ich auch noch nie verstanden.

dafür ist es wesentlich schneller als das if/else if konstrukt.
__________________
Website: www.thomas-vogel.de
emax ist offline   Mit Zitat antworten
Alt 30-06-2003, 11:30   #5 (permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
@emax:
Bei mir ist das if schneller. Das wundert mich allerdings auch, denn ich habe im Hinterkopf, dass beide zum gleichen Bytecode übersetzt werden.

ActionScript:
  1. x = 4;
  2. //
  3. t = getTimer();
  4. for (var i = 0; i < 10000; i++) {
  5.     switch (x) {
  6.     case 1 :
  7.         y = 1;
  8.         break;
  9.     case 2 :
  10.         y = 2;
  11.         break;
  12.     case 3 :
  13.         y = 3;
  14.     }
  15. }
  16. trace(getTimer() - t);
  17. //
  18. t = getTimer();
  19. for (var i = 0; i < 10000; i++) {
  20.     if( x == 1) {
  21.         y = 1;
  22.     } else if( x == 2){
  23.         y = 2;
  24.     } else if( x == 3){
  25.         y = 3;
  26.     }
  27. }
  28. trace(getTimer() - t);


@andre:
Ja, wieso ? Der Grund für dieses Verhalten ist das fehlende break. Oder fragst du nach dem Sinn dieses Verhaltens ?
Der Sinn könnte darin liegen, dass man das Verhalten für verschiedene Fälle nicht immer wieder kopieren muss.

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 30-06-2003, 11:42   #6 (permalink)
[+]
 
Benutzerbild von André Michelle
 
Registriert seit: Dec 2002
Ort: cologne
Beiträge: 2.271
@bokel: Genau, es ging mir um den Sinn :o)

Das ist einfach unlogisch und sprachlich nicht nachzuvollziehen.

Für mich muss ein case wahr sein, damit er ausgeführt wird und nicht, wenn ein case vorher wahr war...
__________________
aM

blog | laboratory | tonfall | processing

Audiotool.com
André Michelle ist offline   Mit Zitat antworten
Alt 30-06-2003, 11:47   #7 (permalink)
zeitreisender
 
Benutzerbild von emax
 
Registriert seit: Aug 2001
Ort: Hannover
Beiträge: 1.577
stimmt, es nimmt sich nix. mal ist if schneller, mal switch.

komisch, habe für die 4gewinnt ki auch benchmarks gemacht
und irgendwie rausgelesen, daß switch schneller wäre.
__________________
Website: www.thomas-vogel.de
emax ist offline   Mit Zitat antworten
Alt 30-06-2003, 11:51   #8 (permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
@andre
Genau dieses Verhalten bekommst du ja mit break hin.

Durch das fehlende break kannst du mehrere Blöcke zu einem zusammenfassen.

ActionScript:
  1. switch( x){
  2.     case 1:
  3.     case 8:
  4.     case 13:
  5.           trace("1, 8, 19");
  6.           break;
  7.     case 4:
  8.           trace("4");
  9.           break;
  10. }

Wenn es break nicht gäbe, müsstest du den Code vervielfältigen.

ActionScript:
  1. switch( x){
  2.     case 1:
  3.           trace("1, 8, 19");
  4.           break;
  5.  
  6.     case 8:
  7.           trace("1, 8, 19");
  8.           break;
  9.  
  10.     case 13:
  11.           trace("1, 8, 19");
  12.           break;
  13.  
  14.     case 4:
  15.           trace("4");
  16.           break;
  17. }

Ziemlich unpraktisch.


mfg r.
bokel ist offline   Mit Zitat antworten
Alt 30-06-2003, 12:51   #9 (permalink)
[+]
 
Benutzerbild von André Michelle
 
Registriert seit: Dec 2002
Ort: cologne
Beiträge: 2.271
Ja, genau. Ziemlich unpraktisch.
Wann brauche ich den im normalen Leben eine solche Interpretation von 'case' ?

Dein Beispiel überzeugt mich nicht.
Vieleicht liegt es nur daran, dass du es einfach hinnimmst und es benutzt!
Mir kommt es immer ein wenig hoch bei solchen Ungereimtheiten...
__________________
aM

blog | laboratory | tonfall | processing

Audiotool.com
André Michelle ist offline   Mit Zitat antworten
Alt 30-06-2003, 12:58   #10 (permalink)
LastActionScriptHero
 
Benutzerbild von k7c4
 
Registriert seit: Apr 2002
Beiträge: 572
Diese Skripte machen das gleiche
ActionScript:
  1. // mit if
  2. if(foo==1)
  3. {
  4.  trace(1)
  5. }
  6. else if(foo==2)
  7. {
  8. trace(2)
  9. }
  10. else if(foo==3)
  11. {
  12. trace(3)
  13. }
  14. else
  15. {
  16. trace("nix")
  17. }
  18.  
  19. // mit switch
  20. switch(foo)
  21. {
  22. case 1: trace(1); break;
  23. case 2: trace(2); break;
  24. case 3: trace(3); break;
  25. default: trace("nix");
  26. }
ebenso diese beiden Konstrukte
ActionScript:
  1. // mit if
  2. if(foo==1)
  3. {
  4.  trace(1)
  5.  trace(2)
  6.  trace(3)
  7. }
  8. else if(foo==2)
  9. {
  10. trace(2)
  11. trace(3)
  12. }
  13. else if(foo==3)
  14. {
  15. trace(3)
  16. }
  17. else
  18. {
  19. trace("nix")
  20. }
  21.  
  22. // mit switch
  23. switch(foo)
  24. {
  25. case 1: trace(1);
  26. case 2: trace(2);
  27. case 3: trace(3); break;
  28. default: trace("nix");
  29. }
Es gibt zwar mehrere Verwendungsmöglichkeiten für ein switch mit break als ohne break, aber wenn man die zweite Möglichkeit mal braucht, dann ist man froh, dass man sie hat.
__________________
All your AS are belong to us! haha!
Beweise heute Deine Tierliebe: Schlage nie ein totes Pferd!
k7c4 ist offline   Mit Zitat antworten
Alt 30-06-2003, 13:03   #11 (permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
Dann bedank dich mal bei Kernighan/Ritchie .
Ich schätze switch ist einfach nur ein leicht verkleidetes Assemblerkonstrukt, an dem dann nie mehr jemand was geändert hat (ausser Wirth). Wird eh nur selten benötigt.

Während das Verhalten von break ja noch dokumentiert ist, gibt es noch zwei kleine implemementationsabhängige Fallen, die nicht so offensichtlich sind:

ActionScript:
  1. // switch wertet den Ausdruck jedesmal neu aus
  2. function test(){
  3.       trace("test");
  4.       return ++zaehler;
  5. }
  6.  
  7. switch( test()){
  8.        case 100:
  9.          trace(100);
  10.          break;
  11.        case 200:
  12.            trace(200);
  13.          break;
  14.        case 300
  15.          trace(300);    
  16.          break;
  17. }
  18.  
  19.  
  20. // switch benutzt === anstatt == zum Vergleich
  21. x = 1;
  22.  
  23. switch(x){
  24.     case "1":
  25.         trace("String 1");
  26.         break;
  27.     case 1:
  28.         trace("Number 1");
  29.         break;
  30. }

Jetzt alle: ärgern, ärgern

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 30-06-2003, 13:06   #12 (permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
@k7c4: Genau, mit break ist man einfach flexibler, ohne dass es mehr kostet.

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 30-06-2003, 13:10   #13 (permalink)
[+]
 
Benutzerbild von André Michelle
 
Registriert seit: Dec 2002
Ort: cologne
Beiträge: 2.271
Mag sein. Ich hätte es anders gebraucht, aber das ging eh nicht...

Ich haue es mal hier rein, sollte jemand noch ein paar gute Ideen haben, kann Bokel vieleicht den Thread splitten.

Ich suche einen Ansatz, um in einem 2D Array nach eingeschalteten Bits abzufragen.

Erst das Script dann die Erklärung:

ActionScript:
  1. var map = [
  2.  
  3.     [ 1 , 1 , 4 , 5 , 6 , 7 , 8 ],
  4.     [ 1 , 1 , 4 , 5 , 6 , 7 , 8 ],
  5.     [ 1 , 1 , 4 , 5 , 6 , 7 , 8 ],
  6.     [ 1 , 1 , 4 , 133 , 6 , 7 , 8 ],
  7.     [ 1 , 1 , 4 , 5 , 6 , 7 , 8 ]
  8.  
  9. ];
  10.  
  11. // ------------------------------------------------------------- //
  12.  
  13. MapManager = function () {};
  14.  
  15. MapManager.initialize = function ( map_data , bit_width ) {
  16.  
  17.     this.map_data = map_data;
  18.  
  19.     this.bit_range = [];
  20.  
  21.     while ( bit_width > -1 ) {
  22.  
  23.         this.bit_range.push ( Math.pow ( 2 , bit_width-- ) );
  24.  
  25.     }
  26.  
  27. }
  28.  
  29. MapManager.accessBit = function ( x , y ) {
  30.  
  31.     trace ( "new request" );
  32.  
  33.     var bit , bit_range , proof_bit;
  34.  
  35.     bit = this.map_data[ y ][ x ];
  36.  
  37.     bit_range = this.bit_range.slice( 0 );
  38.  
  39.     while ( proof_bit = bit_range.pop() ) {
  40.  
  41.         if ( ( bit & proof_bit ) == proof_bit ) {
  42.  
  43.             trace ( "> " + proof_bit + " is on" );
  44.  
  45.         }
  46.  
  47.     }
  48.  
  49. }
  50.  
  51.  
  52. MapManager.initialize ( map , 8 );
  53.  
  54. MapManager.installMethod = function ( obj , method , bit ) {/*Event aufnehmen...*/};
  55.  
  56. MapManager.accessBit ( 3 , 3 );
  57. MapManager.accessBit ( 3 , 1 );

Der Witz ist ja bei Tilemap basierten Spielen, dass ich einige Eigenschaften eines Tiles bequem als Bits ein- und ausschalten kann. Dabei können ja auch 2 oder mehr Bits aktiviert sein.
zB. Der Spieler bekommt an einer Stelle Punkte und es weht ein Wind von rechts....

Jetzt suche ich nach einer eleganten Möglichkeit Bits auszulesen.

Bis jetzt mache ich das immer so:

ActionScript:
  1. if ( ( bit & 2 ) == 2 ) {
  2. // tue was Bit2 verlangt
  3. } else if ( ( bit & 4 ) == 4 ) {
  4. // tue was Bit4 verlangt
  5. }
  6. etc.
Das gibt meistens langweilige und schlecht durchschaubare if else Stränge.

Der OOP Ansatz wäre schön, aber auch langsamer.
__________________
aM

blog | laboratory | tonfall | processing

Audiotool.com
André Michelle ist offline   Mit Zitat antworten
Alt 30-06-2003, 13:43   #14 (permalink)
helpQLODhelp
 
Benutzerbild von bokel
 
Registriert seit: Feb 2002
Ort: Köln
Beiträge: 8.505
Wenn du mich fragst, ist das der klassische Fall, in dem OOP schneller als die herkömmliche Programmierung ist. Anstatt einer Menge von Bits würde ich eine Liste von Methoden benutzen, die du dann direkt ausführen kannst. Oder ist die Umwandlung in Funktionen schon so teuer, dass es sich nicht lohnt ?

mfg r.
bokel ist offline   Mit Zitat antworten
Alt 30-06-2003, 13:51   #15 (permalink)
LastActionScriptHero
 
Benutzerbild von k7c4
 
Registriert seit: Apr 2002
Beiträge: 572
Zitat:
Geschrieben von Andre' Michelle
Bis jetzt mache ich das immer so:

ActionScript:
  1. if ( ( bit & 2 ) == 2 ) {
  2. // tue was Bit2 verlangt
  3. } else if ( ( bit & 4 ) == 4 ) {
  4. // tue was Bit4 verlangt
  5. }
  6. etc.,
Mach doch so
ActionScript:
  1. if ( bit & 2 ) {
  2. // tue was Bit2 verlangt
  3. } else if ( bit & 4 ) {
  4. // tue was Bit3verlangt
  5. }
  6. etc.
,
denn (bit & 2) kann sowieso nur 2 oder 0 sein ebenso wie bit & 4 nur 4 oder 0 sein kann, und da 0 zu false wird und alles andere zu true...

Oder so, dann weisst Du immer, welches Bit gemeint ist
ActionScript:
  1. if ( bit & 1<<1 ) {
  2. // tue was Bit1 verlangt
  3. } else if ( bit & 1<<3 ) {
  4. // tue was Bit3verlangt
  5. }
  6. etc.
, da wir ja bei Bit0 anfangen zu zählen.
ActionScript:
  1. trace(1<<0) //   1 Bit 0
  2. trace(1<<1) //   2 Bit 1
  3. trace(1<<2) //   4 Bit 2
  4. trace(1<<3) //   8 Bit 3
  5. trace(1<<4) //  16 Bit 4
  6. trace(1<<5) //  32 Bit 5
  7. trace(1<<6) //  64 Bit 6
  8. trace(1<<7) // 128 Bit 7
  9.  

Edit:
Außerdem denke ich, dass Du, wenn Du diese Abfrage so machen willst, Deine Bit-Belegung etwas undurchsichtig/unlogisch angelegt hast, denn normalerweise müsste es so gehen.
ActionScript:
  1. if(bit & 1<<0)
  2. {
  3. // bit 0 gesetzt
  4. }
  5. else
  6. {
  7. // bit 0 nicht gesetzt
  8. }
  9. if(bit & 1<<1)
  10. {
  11. // bit 1 gesetzt
  12. }
  13. else
  14. {
  15. // bit 1 nicht gesetzt
  16. }
  17. // etc.
  18.  
1<<2 wird ja einfach beim Veröffentlichen durch 4 ersetzt
__________________
All your AS are belong to us! haha!
Beweise heute Deine Tierliebe: Schlage nie ein totes Pferd!

Geändert von k7c4 (30-06-2003 um 14:09 Uhr)
k7c4 ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an



Alle Zeitangaben in WEZ +1. Es ist jetzt 15:33 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele