summaryrefslogtreecommitdiff
path: root/dnn
diff options
context:
space:
mode:
authorchatty2000-11-28 14:52:15 +0000
committerchatty2000-11-28 14:52:15 +0000
commit343e64cc2c838496ccb07ab7bd58e618cc75036c (patch)
tree5b9eb3fadd0083f7f9bedffd33e9fbae059999b5 /dnn
parenta38e6d7cf946ce15e4a67bcbd1ffbeaec532763a (diff)
downloadivy-league-343e64cc2c838496ccb07ab7bd58e618cc75036c.zip
ivy-league-343e64cc2c838496ccb07ab7bd58e618cc75036c.tar.gz
ivy-league-343e64cc2c838496ccb07ab7bd58e618cc75036c.tar.bz2
ivy-league-343e64cc2c838496ccb07ab7bd58e618cc75036c.tar.xz
Added Johnny's criteria
Safer destructor
Diffstat (limited to 'dnn')
-rw-r--r--dnn/Trigger.cc121
1 files changed, 112 insertions, 9 deletions
diff --git a/dnn/Trigger.cc b/dnn/Trigger.cc
index 9b6db60..3effd6d 100644
--- a/dnn/Trigger.cc
+++ b/dnn/Trigger.cc
@@ -3,7 +3,7 @@
*
* by Stephane Chatty
*
- * Copyright 1993-1994
+ * Copyright 1993-1995
* Centre d'Etudes de la Navigation Aerienne (CENA)
*
* Event triggers.
@@ -14,6 +14,7 @@
#include "Trigger.h"
#include "Reaction.h"
+#include "Criterion.h"
/*?class DnnTrigger
\typ{DnnTrigger}s are the core of event detection and emission. The presence of a trigger
@@ -28,21 +29,50 @@ the trigger.
Create a trigger with an empty list of associated reaction.
?*/
DnnTrigger :: DnnTrigger ()
-: Subscribers (),
- Grabs ()
+: FirstSubscribers (),
+ LastSubscribers (),
+ Subscribers (),
+ Grabs (),
+ Criteria ()
{
}
/*?nodoc?*/
DnnTrigger :: ~DnnTrigger ()
{
+ /* Force reactions to unsubscribe.
+ We should take care of conditions when destructor is called
+ during iteration */
+
+ CcuListIterOf <DnnBaseReaction> ri = FirstSubscribers;
+ while (++ri)
+ (*ri)->Forget (*this);
+ ri = Subscribers;
+ while (++ri)
+ (*ri)->Forget (*this);
+ ri = LastSubscribers;
+ while (++ri)
+ (*ri)->Forget (*this);
+ ri = Grabs;
+ while (++ri)
+ (*ri)->Forget (*this);
}
/*?nextdoc?*/
void
-DnnTrigger :: Subscribe (DnnBaseReaction& a)
+DnnTrigger :: Subscribe (DnnBaseReaction& a, REL_PRIORITY p)
{
- Subscribers.Append (&a);
+ switch (p) {
+ case isFirstPriority:
+ FirstSubscribers.Append (&a);
+ break;
+ case isNormalPriority:
+ Subscribers.Append (&a);
+ break;
+ case isLastPriority:
+ LastSubscribers.Prepend (&a);
+ break;
+ }
}
/*?
@@ -52,7 +82,9 @@ events caused by this trigger.
void
DnnTrigger :: Unsubscribe (DnnBaseReaction& a)
{
+ FirstSubscribers.Remove (&a);
Subscribers.Remove (&a);
+ LastSubscribers.Remove (&a);
Grabs.Remove (&a);
}
@@ -70,8 +102,28 @@ events caused by this trigger.
void
DnnTrigger :: Release (DnnBaseReaction& a)
{
- Subscribers.Remove (&a);
+ Grabs.Remove (&a);
+}
+
+#if 0
+void
+DnnTrigger :: Circulate (DnnBaseReaction& r, REL_POS pos, DnnBaseReaction* ref)
+{
+
+ if (Subscribers.Remove (&r)) {
+ /* find the predecessor of ref */
+ CcuListIterOf <DnnBaseReaction> lc = Subscribers;
+ while (++lc && (*lc != ref))
+ ;
+ /* NOW, lc is on ref, or at the end if ref == 0 */
+ if (pos == isBefore)
+ Subscribers.InsertBefore (lc, &r);
+ else
+ Subscribers.InsertAfter (lc, &r);
+ }
+
}
+#endif
/*?
Have a trigger dispatch the event \var{ev} to its associated reactions.
@@ -83,9 +135,60 @@ DnnTrigger :: Dispatch (DnnEvent& ev)
if (r) {
r->Manage (ev);
} else {
+ /* calls to Manage may result in changes in Subscribers; let's make a safe copy */
+ CcuListOf <DnnBaseReaction> first_subscribers = FirstSubscribers;
CcuListOf <DnnBaseReaction> subscribers = Subscribers;
- CcuListIterOf <DnnBaseReaction> ai = subscribers;
- while (++ai)
- (*ai)->Manage (ev);
+ CcuListOf <DnnBaseReaction> last_subscribers = LastSubscribers;
+
+ CcuListIterOf <DnnBaseReaction> s = first_subscribers;
+ while (++s)
+#ifdef CRITERIA_IN_REACTIONS
+ if ((*s)->Check (ev))
+#endif
+ (*s)->Manage (ev);
+
+ s = subscribers;
+ while (++s)
+#ifdef CRITERIA_IN_REACTIONS
+ if ((*s)->Check (ev))
+#endif
+ (*s)->Manage (ev);
+
+ s = last_subscribers;
+ while (++s)
+#ifdef CRITERIA_IN_REACTIONS
+ if ((*s)->Check (ev))
+#endif
+ (*s)->Manage (ev);
}
}
+
+
+bool
+DnnTrigger :: Check (DnnEvent& ev)
+{
+ CcuListIterOf <DnnBaseCriterion> c = Criteria;
+ while (++c)
+ if (!(*c)->Test (ev))
+ return false;
+
+
+#ifdef CRITERIA_IN_REACTIONS
+ CcuListIterOf <DnnBaseReaction> ri = FirstSubscribers;
+ while (++ri)
+ if ((*ri)->Check (ev))
+ return true;
+ ri = Subscribers;
+ while (++ri)
+ if ((*ri)->Check (ev))
+ return true;
+ ri = LastSubscribers;
+ while (++ri)
+ if ((*ri)->Check (ev))
+ return true;
+ return false;
+#else
+ return true;
+#endif
+}
+