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 AbstractSink* sink = *itr;
166 auto isFiltered = filteredSourceSinkMap.find(sink);
168 if(isFiltered != filteredSourceSinkMap.end() )
171 std::string u = filteredSourceSinkMap[sink][property];
172 DebugOut()<<"Property ("<<property<<") for sink is filtered for source: "<<u<<endl;
175 if( (isFiltered != filteredSourceSinkMap.end() && filteredSourceSinkMap[sink][property] == uuid) || isFiltered == filteredSourceSinkMap.end())
177 /// FIXME: Set this here just in case a source neglects to:
178 value->sourceUuid = uuid;
180 sink->propertyChanged(property, value, uuid);
185 std::list<std::string> Core::sourcesForProperty(VehicleProperty::Property property)
187 std::list<std::string> l;
189 for(auto itr = mSources.begin(); itr != mSources.end(); itr++)
191 AbstractSource* src = *itr;
193 PropertyList s = src->supported();
195 if(ListPlusPlus<VehicleProperty::Property>(&s).contains(property))
197 l.push_back(src->uuid());
204 void Core::registerSink(AbstractSink *self)
206 if(!ListPlusPlus<AbstractSink*>(&mSinks).contains(self))
208 mSinks.push_back(self);
212 void Core::unregisterSink(AbstractSink *self)
214 if(ListPlusPlus<AbstractSink*>(&mSinks).contains(self))
216 ListPlusPlus<AbstractSink*>(&mSinks).removeOne(self);
221 AsyncPropertyReply *Core::getPropertyAsync(AsyncPropertyRequest request)
223 AsyncPropertyReply * reply = new AsyncPropertyReply(request);
225 for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
227 AbstractSource* src = (*itr);
228 PropertyList properties = src->supported();
229 int supportedOps = src->supportedOperations();
231 bool supportsGet = supportedOps & AbstractSource::Get;
233 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(request.property) && supportsGet && (request.sourceUuidFilter == "" || request.sourceUuidFilter == src->uuid()))
236 src->getPropertyAsync(reply);
238 /** right now the owner of the reply becomes the requestor that called this method.
239 * reply will become invalid after the first reply. */
247 AsyncRangePropertyReply *Core::getRangePropertyAsync(AsyncRangePropertyRequest request)
249 AsyncRangePropertyReply * reply = new AsyncRangePropertyReply(request);
251 for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
253 AbstractSource* src = (*itr);
254 PropertyList properties = src->supported();
255 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(request.property)
256 && (src->supportedOperations() & AbstractSource::GetRanged)
257 && (request.sourceUuid == "" || request.sourceUuid == src->uuid()))
259 src->getRangePropertyAsync(reply);
266 AsyncPropertyReply * Core::setProperty(AsyncSetPropertyRequest request)
268 for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
270 AbstractSource* src = (*itr);
271 PropertyList properties = src->supported();
272 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(request.property) && src->supportedOperations() & AbstractSource::Set)
274 return src->setProperty(request);
278 DebugOut(0)<<"Error: setProperty opration failed"<<endl;
282 void Core::subscribeToProperty(VehicleProperty::Property property, AbstractSink* self)
284 DebugOut(1)<<"Subscribing to: "<<property<<endl;
286 if(propertySinkMap.find(property) == propertySinkMap.end())
288 propertySinkMap[property] = SinkList();
291 SinkList list = propertySinkMap[property];
293 if(!ListPlusPlus<AbstractSink*>(&list).contains(self))
295 propertySinkMap[property].push_back(self);
298 for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
300 AbstractSource* src = (*itr);
301 PropertyList properties = src->supported();
302 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(property))
304 src->subscribeToPropertyChanges(property);
310 void Core::subscribeToProperty(VehicleProperty::Property property, string sourceUuidFilter, AbstractSink *sink)
312 if(filteredSourceSinkMap.find(sink) == filteredSourceSinkMap.end() && sourceUuidFilter != "")
314 std::map<VehicleProperty::Property, std::string> propertyFilter;
315 propertyFilter[property] = sourceUuidFilter;
316 filteredSourceSinkMap[sink] = propertyFilter;
319 subscribeToProperty(property,sink);
322 void Core::subscribeToProperty(VehicleProperty::Property, string sourceUuidFilter, Zone::Type zoneFilter, AbstractSink *self)
327 void Core::unsubscribeToProperty(VehicleProperty::Property property, AbstractSink* self)
329 if(propertySinkMap.find(property) == propertySinkMap.end())
331 DebugOut(1)<<__FUNCTION__<<" property not subscribed to: "<<property<<endl;
335 ListPlusPlus<AbstractSink*>(&propertySinkMap[property]).removeOne(self);
337 if( filteredSourceSinkMap.find(self) != filteredSourceSinkMap.end())
339 filteredSourceSinkMap.erase(self);
342 /// Now we check to see if this is the last subscriber
343 if(propertySinkMap.find(property) == propertySinkMap.end())
345 for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
347 AbstractSource* src = (*itr);
348 PropertyList properties = src->supported();
350 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(property))
352 src->unsubscribeToPropertyChanges(property);
358 PropertyInfo Core::getPropertyInfo(VehicleProperty::Property property, string sourceUuid)
360 for(auto itr = mSources.begin(); itr != mSources.end(); itr++)
362 AbstractSource* src = *itr;
364 if(src->uuid() == sourceUuid)
366 return src->getPropertyInfo(property);
370 return PropertyInfo::invalid();
373 std::list<string> Core::getSourcesForProperty(VehicleProperty::Property property)
375 std::list<std::string> list;
377 for(auto itr = mSources.begin(); itr != mSources.end(); itr++)
379 AbstractSource* src = *itr;
381 PropertyList supportedProperties = src->supported();
383 if(ListPlusPlus<VehicleProperty::Property>(&supportedProperties).contains(property))
385 list.push_back(src->uuid());