Angel 3.2
A 2D Game Prototyping Engine
Switchboard.cpp
1 
2 // Copyright (C) 2008-2013, Shane Liesegang
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of the copyright holder nor the names of any
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "stdafx.h"
31 #include "../Messaging/Switchboard.h"
32 
33 #include "../Infrastructure/World.h"
34 
35 Switchboard* Switchboard::s_Switchboard = NULL;
36 
37 Switchboard::Switchboard()
38 {
39  _messagesLocked = false;
40 }
41 
43 {
44  if (s_Switchboard == NULL)
45  {
46  s_Switchboard = new Switchboard();
47  }
48  return *s_Switchboard;
49 }
50 
52 {
53  _messages.push(message);
54 }
55 
56 void Switchboard::DeferredBroadcast(Message* message, float delay)
57 {
58  MessageTimer mt(message, delay);
59  _delayedMessages.push_back(mt);
60 }
61 
62 void Switchboard::Update(float dt)
63 {
64  std::vector<MessageTimer>::iterator it = _delayedMessages.begin();
65  while (it != _delayedMessages.end())
66  {
67  (*it)._timeRemaining -= dt;
68  if ((*it)._timeRemaining <= 0.0f)
69  {
70  Broadcast((*it)._message);
71  it = _delayedMessages.erase(it);
72  }
73  else
74  {
75  it++;
76  }
77  }
78 }
79 
80 const bool Switchboard::SubscribeTo(MessageListener* subscriber, const String& messageType)
81 {
82  if (_messagesLocked)
83  {
84  _deferredAdds.push_back(SubscriptionInfo(subscriber, messageType));
85  return false;
86  }
87 
88  _subscriptions[subscriber].insert(messageType);
89  std::pair<std::set<MessageListener*>::iterator, bool> insertResult = _subscribers[messageType].insert(subscriber);
90  return insertResult.second;
91 }
92 
93 const bool Switchboard::UnsubscribeFrom(MessageListener* subscriber, const String& messageType)
94 {
95  if (_messagesLocked)
96  {
97  _deferredRemoves.push_back(SubscriptionInfo(subscriber, messageType));
98  return false;
99  }
100 
101  if (_subscribers.find(messageType) == _subscribers.end())
102  {
103  return false;
104  }
105  std::set<MessageListener*>::iterator it = _subscribers[messageType].find(subscriber);
106  if (it == _subscribers[messageType].end())
107  {
108  return false;
109  }
110  else
111  {
112  _subscribers[messageType].erase(it);
113  StringSet::iterator sIt = _subscriptions[subscriber].find(messageType);
114  if (sIt != _subscriptions[subscriber].end())
115  _subscriptions[subscriber].erase(sIt);
116  return true;
117  }
118 }
119 
120 const std::set<MessageListener*> Switchboard::GetSubscribersTo(const String& messageType)
121 {
122  if (_subscribers.find(messageType) == _subscribers.end())
123  {
124  return std::set<MessageListener*>();
125  }
126  else
127  {
128  return _subscribers[messageType];
129  }
130 }
131 
133 {
134  if (_subscriptions.find(subscriber) == _subscriptions.end())
135  {
136  return StringSet();
137  }
138  else
139  {
140  return _subscriptions[subscriber];
141  }
142 }
143 
145 {
146  _messagesLocked = true;
147  while (!_messages.empty())
148  {
149  String frontMessageName = _messages.front()->GetMessageName();
150  if (_subscribers.find(frontMessageName) != _subscribers.end())
151  {
152  std::set<MessageListener*>::iterator listenIt = _subscribers[frontMessageName].begin();
153  while (listenIt != _subscribers[frontMessageName].end())
154  {
155  (*listenIt)->ReceiveMessage(_messages.front());
156  listenIt++;
157  }
158  }
159  delete _messages.front();
160  _messages.pop();
161  }
162  _messagesLocked = false;
163 
164  for(unsigned int i = 0; i < _deferredRemoves.size(); i++)
165  {
166  UnsubscribeFrom(_deferredRemoves[i]._subscriber, _deferredRemoves[i]._messageType);
167  }
168  _deferredRemoves.clear();
169 
170  for(unsigned int i = 0; i < _deferredAdds.size(); i++)
171  {
172  SubscribeTo(_deferredAdds[i]._subscriber, _deferredAdds[i]._messageType);
173  }
174  _deferredAdds.clear();
175 }