Action List (C++)
A C++ implementation of an action list data structure for games.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
//------------------------------------------------------------------------------ // Header File //------------------------------------------------------------------------------ #include "action.h" #include #include namespace crusher { /* list of concurrently or sequentially running actions */ class action_list : public action { public: // typedefs typedef int lane_id; // ctor / dtor action_list(void); ~action_list(void); // public methods void update(float dt); void push_back(action* back, lane_id id = 0); void push_front(action* front, lane_id id = 0); void clear(void); void clear_lane(lane_id clear_id); bool empty(void) const; bool lane_empty(lane_id id) const; private: // private types typedef std::list typedef std::map typedef std::pair // private members lane_map _lanes; int _size; }; // class action_list } // namespace crusher //------------------------------------------------------------------------------ // Implementation File //------------------------------------------------------------------------------ #include "action_list.h" using namespace crusher; action_list::action_list(void) : _size(0) { } action_list::~action_list(void) { clear(); } void action_list::update(float dt) { if (is_paused()) return; // update all action lanes for (auto& lane_pair : _lanes) { // update actions until blocking action action_container& lane = lane_pair.second; for (auto it = lane.begin(); it != lane.end();) { action* cur_action = *it; // don't update if paused if (!cur_action->is_paused()) { // start if hasn't started if (!cur_action->is_started()) { cur_action->_started = true; cur_action->startup(); } cur_action->update(dt); // remove if finished if (cur_action->is_finished()) { cur_action->shutdown(); delete cur_action; it = lane.erase(it); --_size; continue; } } // remaining actions blocked if (cur_action->is_blocking()) break; ++it; } } // finish if empty if (empty()) set_finished(); } void action_list::push_back(action* back, lane_id id) { _lanes[id].push_back(back); ++_size; } void action_list::push_front(action* front, lane_id id) { _lanes[id].push_front(front); ++_size; } void action_list::clear(void) { // delete all actions for (auto& lane : _lanes) { // delete all actions in lane for (action* action : lane.second) delete action; } _lanes.clear(); _size = 0; } void action_list::clear_lane(lane_id clear_id) { auto lane = _lanes.find(clear_id); if (lane != _lanes.end()) { // delete all actions in lane action_container& clear_lane = lane->second; for (action* action : clear_lane) delete action; clear_lane.clear(); } } bool action_list::empty(void) const { return (_size == 0); } bool action_list::lane_empty(lane_id id) const { auto lane = _lanes.find(id); if (lane == _lanes.end()) return true; return lane->second.empty(); } |