refactored setProperty: made it async with callback
[profile/ivi/automotive-message-broker.git] / ambd / core.cpp
1 /*
2     Copyright (C) 2012  Intel Corporation
3
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.
8
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.
13
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
17 */
18
19
20 #include "core.h"
21 #include <functional>
22 #include <glib.h>
23 #include "listplusplus.h"
24 #include "debugout.h"
25
26 using namespace std::placeholders;
27
28 int lastpps=0;
29
30 static int PPSUpdate(void* data)
31 {
32         int* pps = (int*)data;
33
34         int temp = *pps;
35
36         if(temp > 0 && temp != lastpps)
37         {
38                 lastpps = temp;
39                 DebugOut(1)<<"Property updates per second: "<<temp<<endl;
40         }
41
42         *pps = 0;
43 }
44
45 Core::Core()
46         :propertiesPerSecond(0)
47 {
48         g_timeout_add(1000,PPSUpdate,&propertiesPerSecond);
49 }
50
51 Core::~Core()
52 {
53
54 }
55
56
57 void Core::setSupported(PropertyList supported, AbstractSource* source)
58 {
59
60         if(!ListPlusPlus<AbstractSource*>(&mSources).contains(source))
61                 mSources.push_back(source);
62                 
63         for(PropertyList::iterator itr = supported.begin(); itr != supported.end(); itr++)
64         {
65                 if(!ListPlusPlus<VehicleProperty::Property>(&mMasterPropertyList).contains((*itr)))
66                 {
67                         DebugOut()<<__FUNCTION__<<"() adding suport for property "<<(*itr)<<endl;
68                         mMasterPropertyList.push_back((*itr));
69                 }
70         }
71
72         /// tell all new sinks about the newly supported properties.
73
74         for(SinkList::iterator itr = mSinks.begin(); itr != mSinks.end(); itr++)
75         {
76                 (*itr)->supportedChanged(mMasterPropertyList);
77         }
78
79         /// iterate through subscribed properties and resubscribe.  This catches newly supported properties in the process.
80
81         for(map<VehicleProperty::Property, SinkList>::iterator itr = propertySinkMap.begin(); itr != propertySinkMap.end(); itr++)
82         {
83                 VehicleProperty::Property  property = (*itr).first;
84
85                 for(SourceList::iterator source = mSources.begin(); source != mSources.end(); source++)
86                 {
87                         PropertyList properties = (*source)->supported();
88
89                         if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(property))
90                         {
91                                 (*source)->subscribeToPropertyChanges(property);
92                         }
93                 }
94         }
95 }
96
97
98 void Core::updateSupported(PropertyList added, PropertyList removed)
99 {
100         
101         /// add the newly supported to master list
102         
103         for(PropertyList::iterator itr = added.begin(); itr != added.end(); itr++)
104         {
105                 if(ListPlusPlus<VehicleProperty::Property>(&added).contains(*itr))
106                 {
107                         mMasterPropertyList.push_back(*itr);
108                 }
109         }
110         
111         /// removed no longer supported properties from master list.
112         
113         for(PropertyList::iterator itr = removed.begin(); itr != removed.end(); itr++)
114         {
115                 ListPlusPlus<VehicleProperty::Property>(&mMasterPropertyList).removeOne(*itr);
116         }
117         
118         /// tell all new sinks about the newly supported properties.
119         
120         for(SinkList::iterator itr = mSinks.begin(); itr != mSinks.end(); itr++)
121         {
122                 (*itr)->supportedChanged(mMasterPropertyList);
123         }
124         
125         /// iterate through subscribed properties and resubscribe.  This catches newly supported properties in the process.
126         
127         for(map<VehicleProperty::Property, SinkList>::iterator itr = propertySinkMap.begin(); itr != propertySinkMap.end(); itr++)
128         {
129                 VehicleProperty::Property  property = (*itr).first;
130                 
131                 for(SourceList::iterator source = mSources.begin(); source != mSources.end(); source++)
132                 {
133                         PropertyList properties = (*source)->supported();
134                         
135                         if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(property))
136                         {
137                                 (*source)->subscribeToPropertyChanges(property);
138                         }
139                 }
140         }
141 }
142
143 void Core::updateProperty(VehicleProperty::Property property, AbstractPropertyType *value)
144 {
145         SinkList list = propertySinkMap[property];
146         
147         DebugOut()<<__FUNCTION__<<"() there are "<<list.size()<<" sinks connected to property: "<<property<<endl;
148
149         propertiesPerSecond++;
150
151         for(SinkList::iterator itr = list.begin(); itr != list.end(); itr++)
152         {
153                 (*itr)->propertyChanged(property, value,(*itr)->uuid());
154         }
155 }
156
157 void Core::registerSink(AbstractSink *self)
158 {
159         if(!ListPlusPlus<AbstractSink*>(&mSinks).contains(self))
160         {
161                 mSinks.push_back(self);
162         }
163 }
164
165 void Core::unregisterSink(AbstractSink *self)
166 {
167         if(ListPlusPlus<AbstractSink*>(&mSinks).contains(self))
168         {
169                 ListPlusPlus<AbstractSink*>(&mSinks).removeOne(self);
170         }
171 }
172
173
174 AsyncPropertyReply *Core::getPropertyAsync(AsyncPropertyRequest request)
175 {
176         AsyncPropertyReply * reply = new AsyncPropertyReply(request);
177
178         for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
179         {
180                 AbstractSource* src = (*itr);
181                 PropertyList properties = src->supported();
182                 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(request.property))
183                 {
184                         src->getPropertyAsync(reply);
185                 }
186         }
187
188         return reply;
189 }
190
191 AsyncRangePropertyReply *Core::getRangePropertyAsync(AsyncRangePropertyRequest request)
192 {
193         AsyncRangePropertyReply * reply = new AsyncRangePropertyReply(request);
194
195         for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
196         {
197                 AbstractSource* src = (*itr);
198                 PropertyList properties = src->supported();
199                 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(request.property))
200                 {
201                         src->getRangePropertyAsync(reply);
202                 }
203         }
204
205         return reply;
206 }
207
208 AsyncPropertyReply * Core::setProperty(AsyncSetPropertyRequest request)
209 {
210         for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
211         {
212                 AbstractSource* src = (*itr);
213                 PropertyList properties = src->supported();
214                 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(request.property))
215                 {
216                         return src->setProperty(request);
217                 }
218         }
219 }
220
221 void Core::subscribeToProperty(VehicleProperty::Property property, AbstractSink* self)
222 {
223         printf("Subscribing\n");
224         if(!ListPlusPlus<VehicleProperty::Property>(&mMasterPropertyList).contains((property)))
225         {
226                 DebugOut()<<__FUNCTION__<<"(): property not supported: "<<property<<endl;
227                 return; 
228         }
229         
230         if(propertySinkMap.find(property) == propertySinkMap.end())
231         {
232                 propertySinkMap[property] = SinkList();
233         }
234         
235         SinkList list = propertySinkMap[property];
236         
237         if(!ListPlusPlus<AbstractSink*>(&list).contains(self))
238         {
239                 propertySinkMap[property].push_back(self);
240         }
241         
242         for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
243         {
244                 AbstractSource* src = (*itr);
245                 PropertyList properties = src->supported();
246                 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(property))
247                 {
248                         src->subscribeToPropertyChanges(property);
249                 }
250         }
251 }
252
253 void Core::unsubscribeToProperty(VehicleProperty::Property property, AbstractSink* self)
254 {
255         if(propertySinkMap.find(property) == propertySinkMap.end())
256         {
257                 DebugOut()<<__FUNCTION__<<"property not supported: "<<property;
258                 return; 
259         }
260                 
261         ListPlusPlus<AbstractSink*>(&propertySinkMap[property]).removeOne(self);
262         
263         for(SourceList::iterator itr = mSources.begin(); itr != mSources.end(); itr++)
264         {
265                 AbstractSource* src = (*itr);
266                 PropertyList properties = src->supported();
267                 
268                 if(ListPlusPlus<VehicleProperty::Property>(&properties).contains(property))
269                 {
270                         src->unsubscribeToPropertyChanges(property);
271                 }
272         }
273 }
274