1 /*
2  *  cEventList.h
3  *  Avida
4  *
5  *  Called "event_list.hh" prior to 12/2/05.
6  *  Copyright 1999-2011 Michigan State University. All rights reserved.
7  *  Copyright 1993-2003 California Institute of Technology.
8  *
9  *
10  *  This file is part of Avida.
11  *
12  *  Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
13  *  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
14  *
15  *  Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public License along with Avida.
19  *  If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #ifndef cEventList_h
24 #define cEventList_h
25 
26 #ifndef cAction_h
27 #include "cAction.h"
28 #endif
29 
30 #include "tList.h"
31 
32 
33 namespace Avida {
34   class Feedback;
35 };
36 
37 class cAvidaContext;
38 class cString;
39 class cWorld;
40 
41 using namespace Avida;
42 
43 
44 // This is the fundamental class for event management. It holds a list of all
45 // events, and provides methods to add new events and to process existing
46 // events.
47 
48 class cEventList
49 {
50 public:
51 
52   // Event Trigger Type ====================================================================
53   //  UPDATE occurs at the end of an update
54   //  GENERATION occurs at the end of an update for particular values of average generation,
55   //             as evaluated at an update boundry
56   //  IMMEDIATE occurs at once
57   //  BIRTHS is triggered by values of tot_creatures (total creatures ever) in the stats object
58   //         as evaluated at an update boundary
59   //  UNDEFINED is undefined
60   //  BIRTH_INTERRUPT is triggered by tot_creatures values outside of update boundaries.
61   //                  Some statistical information gathered at the end of an update is not
62   //                  available or is incomplete with this option.
63   enum eTriggerType { UPDATE, GENERATION, IMMEDIATE, BIRTHS, UNDEFINED, BIRTHS_INTERRUPT };
64 
65   static const double TRIGGER_BEGIN;  //Are these unsafely defined? @MRR
66   static const double TRIGGER_END;
67   static const double TRIGGER_ALL;
68   static const double TRIGGER_ONCE;
69 
70 private:
71   class cEventListEntry;
72 
73 private:
74   cWorld* m_world;
75   cEventListEntry* m_head;
76   cEventListEntry* m_tail;
77   int m_num_events;
78 
79   tList<double> m_birth_interrupt_queue;
80 
81   void QueueBirthInterruptEvent(double t_val);
82   void DequeueBirthInterruptEvent(double t_val);
83 
84   void SyncEvent(cEventListEntry* event);
85   double GetTriggerValue(eTriggerType trigger) const;
86   void Delete(cEventListEntry* entry);
87 
88   cEventList(); // @not_implemented
89   cEventList(const cEventList&); // @not_implemented
90   cEventList& operator=(const cEventList&); // @not_implemented
91 
92 
93 public:
cEventList(cWorld * world)94   cEventList(cWorld* world) : m_world(world), m_head(NULL), m_tail(NULL), m_num_events(0) { ; }
95   ~cEventList();
96 
97 
98   bool AddEvent(eTriggerType trigger, double start, double interval, double stop, const cString &name, const cString& args,
99                 Feedback& feedback);
100 
101   /**
102    * This function adds an event that is given in the event list file format.
103    * In other words, it can be used to parse one line from an event list file,
104    * and construct the appropriate event.
105    **/
106   bool AddEventFileFormat(const cString& line, Feedback& feedback);
107 
108 
109   bool LoadEventFile(const cString& filename, const cString& working_dir, Feedback&  feedback);
110 
111   void Process(cAvidaContext& ctx);
112   void Sync(); // Get all events caught up.
113 
114   void PrintEventList(std::ostream& os = std::cout);
115 
116   /**
117    * Returns true if a particular org_id (or Stats::tot_creature) value is present
118    * in the interrupt queue.
119    *
120    * @param t_value The value being checked.
121    **/
122   bool CheckBirthInterruptQueue(double t_val);
123 
124 
125   /**
126    * This function is called to process an event outside of an update boundary.
127    * Some data may be missing, inaccurate, or incomplete if processing is required
128    * at the end of an update.
129    **/
130   void ProcessInterrupt(cAvidaContext& ctx);
131 
132 	//! Check to see if an event with the given name is upcoming at some point in the future.
133 	bool IsEventUpcoming(const cString& event_name);
134 
135 
136 private:
137   class cEventListEntry
138   {
139   private:
140     cAction* m_action;
141     cString m_name;
142 
143     eTriggerType m_trigger;
144     double m_start;
145     double m_interval;
146     double m_stop;
147     double m_original_start;
148 
149     cEventListEntry* m_prev;
150     cEventListEntry* m_next;
151 
152   public:
153     cEventListEntry(cAction* action, const cString& name, eTriggerType trigger = UPDATE, double start = TRIGGER_BEGIN,
154                     double interval = TRIGGER_ONCE, double stop = TRIGGER_END, cEventListEntry* prev = NULL,
155                     cEventListEntry* next = NULL)
m_action(action)156     : m_action(action), m_name(name), m_trigger(trigger), m_start(start), m_interval(interval), m_stop(stop)
157     , m_original_start(start), m_prev(prev), m_next(next)
158     {
159     }
160 
~cEventListEntry()161     virtual ~cEventListEntry() { delete m_action; }
162 
SetPrev(cEventListEntry * prev)163     void SetPrev(cEventListEntry* prev) { m_prev = prev; }
SetNext(cEventListEntry * next)164     void SetNext(cEventListEntry* next) { m_next = next; }
165 
NextInterval()166     void NextInterval(){ m_start += m_interval; }
Reset()167     void Reset() { m_start = m_original_start; }
168 
169     // accessors
GetAction()170     cAction* GetAction() const { assert(m_action != NULL); return m_action; }
171 
GetName()172     const cString GetName() const { assert(m_action != NULL); return m_name; }
GetArgs()173     const cString& GetArgs() const { assert(m_action != NULL); return m_action->GetArgs(); }
174 
GetTrigger()175     eTriggerType GetTrigger() const { return m_trigger; }
GetStart()176     double GetStart() const { return m_start; }
GetInterval()177     double GetInterval() const { return m_interval; }
GetStop()178     double GetStop() const { return m_stop; }
179 
GetPrev()180     cEventListEntry* GetPrev() const { return m_prev; }
GetNext()181     cEventListEntry* GetNext() const { return m_next; }
182   };
183 
184 };
185 
186 #endif
187