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