2 Copyright (C) 2012 Intel Corporation
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "listplusplus.h"
26 using namespace std::placeholders;
30 static int PPSUpdate(void* data)
32 int* pps = (int*)data;
36 if(temp > 0 && temp != lastpps)
39 DebugOut(1)<<"Property updates per second: "<<temp<<endl;
46 :propertiesPerSecond(0)
48 g_timeout_add(1000,PPSUpdate,&propertiesPerSecond);
53 std::vector<AbstractSink*> toDelete;
54 for(auto itr = mSinks.begin(); itr != mSinks.end(); itr++)
56 AbstractSink* sink = *itr;
57 toDelete.push_back(sink);
60 for(int i=0; i<toDelete.size(); i++)
67 void Core::setSupported(PropertyList supported, AbstractSource* source)
70 if(!ListPlusPlus<AbstractSource*>(&mSources).contains(source))
71 mSources.push_back(source);
73 for(PropertyList::iterator itr = supported.begin(); itr != supported.end(); itr++)
75 if(!ListPlusPlus<VehicleProperty::Property>(&mMasterPropertyList).contains((*itr)))
77 DebugOut()<<__FUNCTION__<<"() adding support for property "<<(*itr)<<endl;
78 mMasterPropertyList.push_back((*itr));
82 /// tell all new sinks about the newly supported properties.
84 for(SinkList::iterator itr = mSinks.begin(); itr != mSinks.end(); itr++)
86 (*itr)->supportedChanged(mMasterPropertyList);
89 /// iterate through subscribed properties and resubscribe. This catches newly supported properties in the process.
91 for(map<VehicleProperty::Property, SinkList>::iterator itr = propertySinkMap.begin(); itr != propertySinkMap.end(); itr++)
93 VehicleProperty::Property property = (*itr).first;
95 for(SourceList::iterator source = mSources.begin(); source != mSources.end(); source++)
97 PropertyList properties = (*source)->supported();
99 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(property))
101 (*source)->subscribeToPropertyChanges(property);
108 void Core::updateSupported(PropertyList added, PropertyList removed)
111 /// add the newly supported to master list
113 for(PropertyList::iterator itr = added.begin(); itr != added.end(); itr++)
115 if(ListPlusPlus<VehicleProperty::Property>(&added).contains(*itr))
117 mMasterPropertyList.push_back(*itr);
121 /// removed no longer supported properties from master list.
123 for(PropertyList::iterator itr = removed.begin(); itr != removed.end(); itr++)
125 ListPlusPlus<VehicleProperty::Property>(&mMasterPropertyList).removeOne(*itr);
128 /// tell all new sinks about the newly supported properties.
130 for(SinkList::iterator itr = mSinks.begin(); itr != mSinks.end(); itr++)
132 (*itr)->supportedChanged(mMasterPropertyList);
135 /// iterate through subscribed properties and resubscribe. This catches newly supported properties in the process.
137 for(map<VehicleProperty::Property, SinkList>::iterator itr = propertySinkMap.begin(); itr != propertySinkMap.end(); itr++)
139 VehicleProperty::Property property = (*itr).first;
141 for(SourceList::iterator source = mSources.begin(); source != mSources.end(); source++)
143 PropertyList properties = (*source)->supported();
145 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(property))
147 (*source)->subscribeToPropertyChanges(property);
153 void Core::updateProperty(VehicleProperty::Property property, AbstractPropertyType *value, std::string uuid)
155 SinkList list = propertySinkMap[property];
157 DebugOut()<<__FUNCTION__<<"() there are "<<list.size()<<" sinks connected to property: "<<property<<endl;
159 propertiesPerSecond++;
162 for(SinkList::iterator itr = list.begin(); itr != list.end(); itr++)
164 (*itr)->propertyChanged(property, value, uuid);
168 std::list<std::string> Core::sourcesForProperty(VehicleProperty::Property property)
170 std::list<std::string> l;
172 for(auto itr = mSources.begin(); itr != mSources.end(); itr++)
174 AbstractSource* src = *itr;
176 PropertyList s = src->supported();
178 if(ListPlusPlus<VehicleProperty::Property>(&s).contains(property))
180 l.push_back(src->uuid());
187 void Core::registerSink(AbstractSink *self)
189 if(!ListPlusPlus<AbstractSink*>(&mSinks).contains(self))
191 mSinks.push_back(self);
195 void Core::unregisterSink(AbstractSink *self)
197 if(ListPlusPlus<AbstractSink*>(&mSinks).contains(self))
199 ListPlusPlus<AbstractSink*>(&mSinks).removeOne(self);
204 AsyncPropertyReply *Core::getPropertyAsync(AsyncPropertyRequest request)
206 AsyncPropertyReply * reply = new AsyncPropertyReply(request);
208 for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
210 AbstractSource* src = (*itr);
211 PropertyList properties = src->supported();
212 int supportedOps = src->supportedOperations();
214 bool supportsGet = supportedOps & AbstractSource::Get;
216 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(request.property) && supportsGet && (request.sourceUuid == "" || request.sourceUuid == src->uuid()))
218 src->getPropertyAsync(reply);
220 /** right now the owner of the reply becomes the requestor that called this method.
221 * reply will become invalid after the first reply. */
229 AsyncRangePropertyReply *Core::getRangePropertyAsync(AsyncRangePropertyRequest request)
231 AsyncRangePropertyReply * reply = new AsyncRangePropertyReply(request);
233 for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
235 AbstractSource* src = (*itr);
236 PropertyList properties = src->supported();
237 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(request.property)
238 && (src->supportedOperations() & AbstractSource::GetRanged)
239 && (request.sourceUuid == "" || request.sourceUuid == src->uuid()))
241 src->getRangePropertyAsync(reply);
248 AsyncPropertyReply * Core::setProperty(AsyncSetPropertyRequest request)
250 for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
252 AbstractSource* src = (*itr);
253 PropertyList properties = src->supported();
254 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(request.property) && src->supportedOperations() & AbstractSource::Set)
256 return src->setProperty(request);
260 DebugOut(0)<<"Error: setProperty opration failed"<<endl;
264 void Core::subscribeToProperty(VehicleProperty::Property property, AbstractSink* self)
266 DebugOut(1)<<"Subscribing to: "<<property<<endl;
268 /** TODO: Change behavior of subscribe to subscribe even if no sources provide a
269 * given property. When subscribers come online with support, core should tell
270 * the sources what properties have already been subscribed to.
273 /*if(!ListPlusPlus<VehicleProperty::Property>(&mMasterPropertyList).contains((property)))
275 DebugOut(1)<<__FUNCTION__<<"(): property not supported: "<<property<<endl;
279 if(propertySinkMap.find(property) == propertySinkMap.end())
281 propertySinkMap[property] = SinkList();
284 SinkList list = propertySinkMap[property];
286 if(!ListPlusPlus<AbstractSink*>(&list).contains(self))
288 propertySinkMap[property].push_back(self);
291 for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
293 AbstractSource* src = (*itr);
294 PropertyList properties = src->supported();
295 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(property))
297 src->subscribeToPropertyChanges(property);
302 void Core::unsubscribeToProperty(VehicleProperty::Property property, AbstractSink* self)
304 if(propertySinkMap.find(property) == propertySinkMap.end())
306 DebugOut(1)<<__FUNCTION__<<"property not supported: "<<property<<endl;
310 ListPlusPlus<AbstractSink*>(&propertySinkMap[property]).removeOne(self);
312 /// Now we check to see if this is the last subscriber
313 if(propertySinkMap.find(property) == propertySinkMap.end())
315 for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
317 AbstractSource* src = (*itr);
318 PropertyList properties = src->supported();
320 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(property))
322 src->unsubscribeToPropertyChanges(property);