QuerySignal generates Notifications instead of Exceptions.
authorStefan Vogel <sv@exept.de>
Fri, 21 Jan 2005 11:33:05 +0100
changeset 8686 708fa53592f6
parent 8685 06c1d82512f5
child 8687 d6e6e2c0c27c
QuerySignal generates Notifications instead of Exceptions. Implement the same set of #raise... methods in GenericException class and Signal. Remove unsed instance variable from signal. Save some message sends when raising signals.
QuerySignal.st
--- a/QuerySignal.st	Fri Jan 21 11:28:35 2005 +0100
+++ b/QuerySignal.st	Fri Jan 21 11:33:05 2005 +0100
@@ -278,6 +278,21 @@
     "Modified: / 25.7.1999 / 23:34:02 / stefan"
 ! !
 
+!QuerySignal methodsFor:'exception creation'!
+
+newException
+    "{ Pragma: +inlineNew }"
+    "answer a new exception object for this signal"
+
+    ^ Notification basicNew setSignal:self.
+
+    "
+      |querySignal|
+      querySignal := QuerySignal new.
+      querySignal handle:[:ex| self halt] do:[querySignal raiseRequest].
+    "
+! !
+
 !QuerySignal methodsFor:'initialization'!
 
 defaultAnswer:someValue
@@ -351,7 +366,7 @@
     self == aSignal ifTrue:[^ true].
     aSignal isQuerySignal ifFalse:[^ false].
 
-    s := aSignal.
+    s := aSignal parent.
     [s notNil] whileTrue:[
         self == s ifTrue:[^ true].
         s := s parent
@@ -368,7 +383,7 @@
 
     |arg|
 
-    theContext selector == #'answer:do:' ifTrue:[
+    theContext selector == #answer:do: ifTrue:[
         (self == signal or:[self accepts:signal]) ifTrue:[
             arg := theContext argAt:1.
             ^ [:ex| ex proceedWith:arg].
@@ -382,13 +397,32 @@
     "Created: / 25.7.1999 / 23:33:05 / stefan"
 !
 
+handles:anException
+    "return true, if the receiver handles the argument, anException.
+     (i.e. the receiver is anExceptions signal or a parent of it)"
+
+    |signal|
+
+    signal := anException signal.
+
+    self == signal ifTrue:[^ true].               "quick check"
+    anException isNotification ifFalse:[^ false]. "speed up non-queries by not traversing the parent chain"
+
+    [(signal := signal parent) notNil] whileTrue:[
+        self == signal ifTrue:[^ true].
+    ].
+    ^ false
+!
+
 isQuerySignal
     "return true, if this is a querySignal - always return true here"
 
     ^ true
 
     "Modified: 22.4.1996 / 13:45:10 / cg"
-!
+! !
+
+!QuerySignal methodsFor:'raising'!
 
 query
     "raise the query - return the handlers value, or the default
@@ -427,20 +461,22 @@
 
     con := Context findFirstSpecialHandle:true raise:false.
     [con notNil] whileTrue:[
-        (sel := con selector) == #'answer:do:' ifTrue:[
-            (sig := con receiver) == self ifTrue:[
+        sel := con selector.
+        sel == #answer:do: ifTrue:[
+            sig := con receiver.
+            sig == self ifTrue:[
                 ^ con argAt:1
             ].
             sig isNil ifTrue:[
-                self halt:'should not happen'.
+                self error:'nil receiver in #answer:do: - send'.
             ].
             (sig accepts:self) ifTrue:[
                 ^ super raiseRequest
             ].
         ] ifFalse:[
-            (sel ~~ #'handle:do:'
-            or:[(sig := con receiver) == self
-            or:[(sig accepts:self)]]) ifTrue:[
+            (sel ~~ #handle:do:
+             or:[(sig := con receiver) == self
+             or:[sig accepts:self]]) ifTrue:[
                 ^ super raiseRequest
             ].
         ].
@@ -463,5 +499,5 @@
 !QuerySignal class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/QuerySignal.st,v 1.38 2002-10-08 17:27:51 penk Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/QuerySignal.st,v 1.39 2005-01-21 10:33:05 stefan Exp $'
 ! !