OpenTTD
linkgraphschedule.cpp
Go to the documentation of this file.
1 /* $Id: linkgraphschedule.cpp 26482 2014-04-23 20:13:33Z rubidium $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8  */
9 
12 #include "../stdafx.h"
13 #include "linkgraphschedule.h"
14 #include "init.h"
15 #include "demands.h"
16 #include "mcf.h"
17 #include "flowmapper.h"
18 
19 #include "../safeguards.h"
20 
25 {
26  if (this->schedule.empty()) return;
27  LinkGraph *next = this->schedule.front();
28  LinkGraph *first = next;
29  while (next->Size() < 2) {
30  this->schedule.splice(this->schedule.end(), this->schedule, this->schedule.begin());
31  next = this->schedule.front();
32  if (next == first) return;
33  }
34  assert(next == LinkGraph::Get(next->index));
35  this->schedule.pop_front();
37  LinkGraphJob *job = new LinkGraphJob(*next);
38  job->SpawnThread();
39  this->running.push_back(job);
40  } else {
41  NOT_REACHED();
42  }
43 }
44 
49 {
50  if (this->running.empty()) return;
51  LinkGraphJob *next = this->running.front();
52  if (!next->IsFinished()) return;
53  this->running.pop_front();
54  LinkGraphID id = next->LinkGraphIndex();
55  delete next; // implicitly joins the thread
56  if (LinkGraph::IsValidID(id)) {
57  LinkGraph *lg = LinkGraph::Get(id);
58  this->Unqueue(lg); // Unqueue to avoid double-queueing recycled IDs.
59  this->Queue(lg);
60  }
61 }
62 
68 /* static */ void LinkGraphSchedule::Run(void *j)
69 {
70  LinkGraphJob *job = (LinkGraphJob *)j;
72  for (uint i = 0; i < lengthof(schedule->handlers); ++i) {
73  schedule->handlers[i]->Run(*job);
74  }
75 }
76 
82 {
83  for (JobList::iterator i = this->running.begin(); i != this->running.end(); ++i) {
84  (*i)->SpawnThread();
85  }
86 }
87 
91 /* static */ void LinkGraphSchedule::Clear()
92 {
94  for (JobList::iterator i(inst->running.begin()); i != inst->running.end(); ++i) {
95  (*i)->JoinThread();
96  }
97  inst->running.clear();
98  inst->schedule.clear();
99 }
100 
107 {
108  LinkGraph *lg;
109  FOR_ALL_LINK_GRAPHS(lg) lg->ShiftDates(interval);
110  LinkGraphJob *lgj;
111  FOR_ALL_LINK_GRAPH_JOBS(lgj) lgj->ShiftJoinDate(interval);
112 }
113 
118 {
119  this->handlers[0] = new InitHandler;
120  this->handlers[1] = new DemandHandler;
121  this->handlers[2] = new MCFHandler<MCF1stPass>;
122  this->handlers[3] = new FlowMapper(false);
123  this->handlers[4] = new MCFHandler<MCF2ndPass>;
124  this->handlers[5] = new FlowMapper(true);
125 }
126 
131 {
132  this->Clear();
133  for (uint i = 0; i < lengthof(this->handlers); ++i) {
134  delete this->handlers[i];
135  }
136 }
137 
142 {
143  static LinkGraphSchedule inst;
144  return &inst;
145 }
146 
152 {
155  if (offset == 0) {
157  } else if (offset == _settings_game.linkgraph.recalc_interval / 2) {
159  }
160 }
161 
162