Cytopia  0.3
A city building simulation game
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PowerManager.cxx
Go to the documentation of this file.
1 #include "PowerManager.hxx"
2 #include "../services/GameClock.hxx"
3 #include <MapFunctions.hxx>
4 #include "GameStates.hxx"
5 #include <SignalMediator.hxx>
6 
8 {
11 
13  [this]()
14  {
15  update();
16  return false;
17  },
18  1s, 1s);
19 }
20 
22 {
23  bool updated = false;
24  // Remove nodes (Demolish on power tiles)
25  if (!m_nodesToRemove.empty())
26  {
27  for (auto m_nodeToRemove : m_nodesToRemove)
28  {
29  removePowerNode(m_nodeToRemove);
30  }
31 
32  m_nodesToRemove.clear();
33  updated = true;
34  }
35 
36  if (!m_nodesToAdd.empty())
37  {
38  for (auto nodeToAdd : m_nodesToAdd)
39  {
40  addPowerNodeToGrid(nodeToAdd, m_powerGrids);
41  }
42  m_nodesToAdd.clear();
43 
44  updated = true;
45  }
46 
47  if (updated)
48  {
51  }
52 }
53 
54 std::vector<int> PowerManager::getAdjacentPowerGrids(const PowerNode &powerNode, std::vector<PowerGrid> &powerGrids)
55 {
56  std::vector<int> neighborGrids;
57  int i = 0;
58 
59  for (auto &powerGrid : powerGrids)
60  {
61  if (powerGrid.isNeighbor(powerNode.coordinate))
62  {
63  neighborGrids.push_back(i);
64  }
65  ++i;
66  }
67 
68  return neighborGrids;
69 }
70 
71 void PowerManager::addPowerNodeToGrid(PowerNode &powerNode, std::vector<PowerGrid> &powerGrids)
72 {
73  auto gridNeighbour = getAdjacentPowerGrids(powerNode, powerGrids);
74 
75  if (gridNeighbour.empty())
76  { // new powergrid
77  powerGrids.emplace_back(powerNode);
78  }
79  else if (gridNeighbour.size() == 1)
80  { // add to this grid
81  powerGrids[gridNeighbour[0]].addNode(powerNode);
82  }
83  else
84  { // merge zone areas
85  PowerGrid &mergedGrid = powerGrids[gridNeighbour[0]];
86  mergedGrid.addNode(powerNode);
87 
88  for (int idx = 1; idx < gridNeighbour.size(); ++idx)
89  {
90  mergePowerGrids(mergedGrid, powerGrids[gridNeighbour[idx]]);
91  }
92 
93  for (int idx = gridNeighbour.size() - 1; idx > 0; --idx)
94  {
95  powerGrids.erase(powerGrids.begin() + gridNeighbour[idx]);
96  }
97  }
98 }
99 
101 {
102  for (auto gridIt = m_powerGrids.begin(); gridIt != m_powerGrids.end(); gridIt++)
103  {
104  if (gridIt->isMemberOf(coordinate))
105  {
106  gridIt->removeNode(coordinate);
107 
108  if (gridIt->size() == 0)
109  {
110  m_powerGrids.erase(gridIt);
111  }
112  else
113  {
114  auto powerGrids = rebuildZoneArea(*gridIt);
115  assert(powerGrids.size() > 0);
116  // If powerGrids size is 1, means powerGrid is still compact, nothing to be done
117 
118  if (powerGrids.size() > 1)
119  {
120  m_powerGrids.erase(gridIt);
121  m_powerGrids.insert(m_powerGrids.end(), powerGrids.begin(), powerGrids.end());
122  }
123  }
124 
125  break;
126  }
127  }
128 }
129 
130 std::vector<PowerGrid> PowerManager::rebuildZoneArea(PowerGrid &powerGrid)
131 {
132  std::vector<PowerGrid> newPowerGrids;
133 
134  for (PowerNode powerNode : powerGrid)
135  {
136  addPowerNodeToGrid(powerNode, newPowerGrids);
137  }
138 
139  return newPowerGrids;
140 }
142 {
143  if (!mapNode.isConductive())
144  {
145  return;
146  }
147 
148  int powerLevelOfTile = 0;
149  if (mapNode.getTileData(Layer::BUILDINGS))
150  { // it's safe to assume only nodes on BUILDINGS layer produce power
151  powerLevelOfTile = mapNode.getTileData(Layer::BUILDINGS)->power;
152  }
153 
154  PowerNode nodeToAdd = {mapNode.getCoordinates(), powerLevelOfTile};
155  m_nodesToAdd.push_back(nodeToAdd);
156 }
157 
159 {
161  {
163  {
164  if (!mapNode->isConductive())
165  { // if there's no power conductor on this node, remove it from the grid
166  m_nodesToRemove.push_back(mapNode->getCoordinates());
167  }
168  break;
169  }
170  default:
171  break;
172  }
173 }
174 
176 {
177  for (auto &powerGrid : m_powerGrids)
178  {
179  powerGrid.updatePowerLevel();
180  }
181 }
182 
184 {
185  m_powerGrids.clear();
186  for (const auto &mapNode : MapFunctions::instance().getMapNodes())
187  {
188  if (mapNode.isConductive())
189  {
190  int power = 0;
191  if (mapNode.getTileData(Layer::BUILDINGS))
192  {
193  power = mapNode.getTileData(Layer::BUILDINGS)->power;
194  }
195  PowerNode powerNode = {mapNode.getCoordinates(), power};
196  m_nodesToAdd.push_back(powerNode);
197  }
198  }
199 }
demolishMode
bool demolishMode
Definition: mapEdit.cxx:5
PowerManager::getAdjacentPowerGrids
std::vector< int > getAdjacentPowerGrids(const PowerNode &powerNode, std::vector< PowerGrid > &powerGrids)
Definition: PowerManager.cxx:54
PowerManager::update
void update()
Definition: PowerManager.cxx:21
MapGrid::addNode
virtual void addNode(T node)
Add a T node to this gridnode.
Definition: MapGrid.inl.hxx:7
PowerManager::rebuildZoneArea
std::vector< PowerGrid > rebuildZoneArea(PowerGrid &powerGrid)
Definition: PowerManager.cxx:130
PowerGrid
Definition: PowerGrid.hxx:17
MapNode::getCoordinates
const Point & getCoordinates() const
get iso coordinates of this node
Definition: MapNode.hxx:59
PowerManager::updatePowerLevels
void updatePowerLevels()
Updates all PowerGrid's power levels.
Definition: PowerManager.cxx:175
MapFunctions.hxx
MapNode::isConductive
const bool isConductive() const
check the conductivity of the node
Definition: MapNode.cxx:502
PowerManager::addPowerNodeToGrid
void addPowerNodeToGrid(PowerNode &powerNode, std::vector< PowerGrid > &powerGrids)
Definition: PowerManager.cxx:71
MapNode::getTileData
const TileData * getTileData(Layer layer) const
Definition: MapNode.hxx:84
PowerNode::coordinate
Point coordinate
Definition: PowerGrid.hxx:10
PowerManager::updatePlacedNodes
void updatePlacedNodes(const MapNode &mapNode)
Definition: PowerManager.cxx:141
SignalMediator::registerCbDemolish
void registerCbDemolish(std::function< void(MapNode *)> const &cb)
Definition: SignalMediator.hxx:41
MapNode
Class that holds map nodes.
Definition: MapNode.hxx:30
GameStates.hxx
BUILDINGS
@ BUILDINGS
8- Buildings, Streets and everything that goes on the terrain
Definition: enums.hxx:19
TileData::power
int power
power production / consumption if negative
Definition: tileData.hxx:156
SignalMediator::signalUpdatePower
Signal::Signal< void(const std::vector< PowerGrid > &)> signalUpdatePower
Definition: SignalMediator.hxx:31
PowerManager::m_nodesToRemove
std::vector< Point > m_nodesToRemove
Definition: PowerManager.hxx:34
PowerManager::PowerManager
PowerManager()
Definition: PowerManager.cxx:7
DemolishMode::DEFAULT
@ DEFAULT
Demolish everything, but not.
PowerManager::m_nodesToAdd
std::vector< PowerNode > m_nodesToAdd
Definition: PowerManager.hxx:33
mergePowerGrids
void mergePowerGrids(PowerGrid &mainGrid, PowerGrid &toBeMerged)
Definition: PowerGrid.cxx:7
PowerNode
Definition: PowerGrid.hxx:8
Signal::slot
std::function< R(Args...)> slot(instance &object, R(Class::*method)(Args...))
This function creates a std::function by binding object to the member function pointer method.
Definition: Signal.hxx:167
PowerManager::reset
void reset()
Definition: PowerManager.cxx:183
PowerManager::updateRemovedNodes
void updateRemovedNodes(const MapNode *mapNode)
Definition: PowerManager.cxx:158
SignalMediator.hxx
Point
Definition: Point.hxx:7
Singleton< SignalMediator >::instance
static SignalMediator & instance(void)
Get an instance of the singleton.
Definition: Singleton.hxx:15
PowerManager.hxx
SignalMediator::registerCbSetTileID
void registerCbSetTileID(std::function< void(const MapNode &)> const &cb)
Definition: SignalMediator.hxx:40
GameClock::addRealTimeClockTask
GameClock::ClockTaskHndl addRealTimeClockTask(ClockCbk cbk, DelayType delay, PeriodType period=TimePointZero)
Add new real time clock task.
Definition: GameClock.inl.hxx:5
PowerManager::m_powerGrids
std::vector< PowerGrid > m_powerGrids
Definition: PowerManager.hxx:35
PowerManager::removePowerNode
void removePowerNode(Point coordinate)
Definition: PowerManager.cxx:100