blob: a746025a6c09d2a0ac3fd486b6d519deef03a274 [file] [log] [blame]
Ernesto Posse8a4f2962015-05-12 13:28:46 -04001// umlrtcapsuletocontrollermap.cc
2
3/*******************************************************************************
4* Copyright (c) 2014-2015 Zeligsoft (2009) Limited and others.
5* All rights reserved. This program and the accompanying materials
6* are made available under the terms of the Eclipse Public License v1.0
7* which accompanies this distribution, and is available at
8* http://www.eclipse.org/legal/epl-v10.html
9*******************************************************************************/
10
11#include "umlrtcapsule.hh"
12#include "umlrtcapsuletocontrollermap.hh"
13#include "umlrtcontroller.hh"
14#include "umlrthashmap.hh"
15#include "basefatal.hh"
16#include "basedebug.hh"
17#include "basedebugtype.hh"
18#include <string.h>
19#include <stdlib.h>
20#include <stdio.h>
21
22UMLRTHashMap * UMLRTCapsuleToControllerMap::capsuleToControllerListMap = NULL;
23UMLRTHashMap * UMLRTCapsuleToControllerMap::controllerNameMap = NULL;
24UMLRTHashMap * UMLRTCapsuleToControllerMap::capsuleNameMap = NULL;
25
26/*static*/ UMLRTHashMap * UMLRTCapsuleToControllerMap::getControllerNameMap()
27{
28 if (controllerNameMap == NULL)
29 {
30 controllerNameMap = new UMLRTHashMap("controllerNameMap", UMLRTHashMap::compareString);
31 }
32 return controllerNameMap;
33}
34
35/*static*/ UMLRTHashMap * UMLRTCapsuleToControllerMap::getCapsuleToControllerListMap()
36{
37 if (capsuleToControllerListMap == NULL)
38 {
39 capsuleToControllerListMap = new UMLRTHashMap("capsuleToControllerMap", UMLRTHashMap::compareString);
40 }
41 return capsuleToControllerListMap;
42}
43
44/*static*/ UMLRTHashMap * UMLRTCapsuleToControllerMap::getCapsuleNameMap()
45{
46 if (capsuleNameMap == NULL)
47 {
48 capsuleNameMap = new UMLRTHashMap("capsuleNameMap", UMLRTHashMap::compareString);
49 }
50 return capsuleNameMap;
51}
52
53// Add a controller by name.
54/*static*/ bool UMLRTCapsuleToControllerMap::addController( const char * controllername, UMLRTController * controller )
55{
56 if (getControllerFromName(controllername) != NULL)
57 {
58 FATAL("ERROR: Controller %s has already registered.", controllername);
59 }
60 BDEBUG(BD_CONTROLLER, "add controller(%s) p(%p)\n", controllername, controller );
61
62 getControllerNameMap()->insert( controllername, (void *)controller);
63
64 return true;
65}
66
67// Add a capsule by name.
68/*static*/ void UMLRTCapsuleToControllerMap::addCapsule( const char * capsulename, UMLRTCapsule * capsule )
69{
70 getCapsuleNameMap()->insert( capsulename, (void *)capsule);
71}
72
73/*static*/ const UMLRTCapsule * UMLRTCapsuleToControllerMap::getCapsuleFromName ( const char * capsulename )
74{
75 return (const UMLRTCapsule *)getCapsuleNameMap()->getObject(capsulename);
76}
77
78// Remove a capsule instance from the list.
79/*static*/ void UMLRTCapsuleToControllerMap::removeCapsule ( const char * capsuleName, UMLRTCapsule * capsule )
80{
81 getCapsuleNameMap()->remove(capsuleName);
82}
83
84/*static*/ UMLRTController * UMLRTCapsuleToControllerMap::getControllerFromName( const char * controllerName )
85{
86 return (UMLRTController *)getControllerNameMap()->getObject(controllerName);
87}
88
89/*static*/ UMLRTController * UMLRTCapsuleToControllerMap::getFirstController()
90{
91 return (UMLRTController *)getControllerNameMap()->getFirstObject();
92}
93
94/*static*/ const char * UMLRTCapsuleToControllerMap::getControllerNameForCapsule ( const char * capsuleName, const UMLRTCapsuleClass * capsuleClass )
95{
96 const char * controllerName = NULL;
97 UMLRTHashMap * controllerList = (UMLRTHashMap *)getCapsuleToControllerListMap()->getObject(capsuleName);
98 if (controllerList)
99 {
100 // Attempt to find the class-specific controller.
101 controllerName = (const char *) controllerList->getObject(capsuleClass->name);
102 if (controllerName == NULL)
103 {
104 // Class-specific controller not assigned - look for the default.
105 controllerName = (const char *)controllerList->getObject((void*)NULL);
106 }
107 }
108 return controllerName;
109}
110
111// Return the controller assigned to this capsule. Returns NULL if no controller is assigned or doesn't exist.
112/*static*/ UMLRTController * UMLRTCapsuleToControllerMap::getControllerForCapsule ( const char * capsuleName, const UMLRTCapsuleClass * capsuleClass )
113{
114 const char * controllerName = getControllerNameForCapsule( capsuleName, capsuleClass );
115
116 return (UMLRTController *)getControllerFromName(controllerName);
117}
118
119/*static*/ void UMLRTCapsuleToControllerMap::addCapsuleToControllerSpec ( char * capsuleName, char * controllerName, char * className )
120{
121 // className can be NULL, indicating the default controller for all capsule classes incarnated into the slot.
122
123 UMLRTHashMap * controllerList = (UMLRTHashMap *)getCapsuleToControllerListMap()->getObject(capsuleName);
124
125 if (controllerList == NULL)
126 {
127 // This capsule has no previous controller assignments - no controller list - add one.
128 const char * capsuleKey = strdup(capsuleName);
129 controllerList = new UMLRTHashMap(capsuleKey, UMLRTHashMap::compareString);
130 getCapsuleToControllerListMap()->insert(capsuleKey, (void *)controllerList);
131 }
132 if ((controllerList->getObject(className)) != NULL)
133 {
134 FATAL("-C option: capsule-to-controller-map already had an entry for capsule '%s' class '%s'",
135 capsuleName, (className == NULL) ? "(default)" : className);
136 }
137 // Assign this controller to the capsule/class combination.
138 const char *classKey = className;
139 if (classKey != NULL)
140 {
141 classKey = strdup(className);
142 }
143 controllerList->insert(classKey, (void *)strdup(controllerName));
144}
145
146// Create a map of capsule to controller
147/*static*/ bool UMLRTCapsuleToControllerMap::parseCapsuleControllerLine ( char * line )
148{
149 bool ok = false;
150 char * capsuleName;
151 char * saveptr;
152 capsuleName = strtok_r( line, " =\n\r\t", &saveptr);
153 if (capsuleName != NULL)
154 {
155 char * controllerName = strtok_r(NULL, " =\n\r\t", &saveptr);
156 if (controllerName != NULL)
157 {
158 char * className = strtok_r(NULL, " = \n\r\t", &saveptr);
159 // If className is NULL, then this is the default controller assignment for this capsule - no capsule class specified.
160 addCapsuleToControllerSpec( capsuleName, controllerName, className );
161 ok = true;
162 }
163 }
164 return ok;
165}
166
167// Create a map of capsule to controller
168/*static*/ bool UMLRTCapsuleToControllerMap::readCapsuleControllerMap( const char * controllerfile )
169{
170 bool ok = true;
171 FILE *fd;
172
173 if ((fd = fopen(controllerfile, "r")) == NULL)
174 {
175 printf("ERROR: failed to open controllers file %s\n", controllerfile);
176 ok = false;
177 }
178 else
179 {
180 char * line;
181 char buf[1024];
182
183 while (((line = fgets(buf, sizeof(buf), fd)) != NULL) && ok)
184 {
185 ok = UMLRTCapsuleToControllerMap::parseCapsuleControllerLine(buf);
186 }
187 }
188 return ok;
189}
190
191// Assign static capsule controllers based on the run-time map.
192/*static*/ void UMLRTCapsuleToControllerMap::setStaticCapsuleControllers( UMLRTSlot * slots, size_t size )
193{
194 for (size_t i = 0; i < size; ++i)
195 {
196 UMLRTController * controller = getControllerForCapsule(slots[i].name, slots[i].capsuleClass);
197
198 // Only reassign static capsules (i.e. controller already assigned) whose controllers were specified in the run-time map.
199 if ((slots[i].controller != NULL) && (controller != NULL))
200 {
201 // Reassign the capsule according to the run-time map collected.
202 slots[i].controller = controller;
203 }
204 }
205}
206
207
208// Debug output the the capsule, controller and capsule-to-controller maps.
209/*static*/ void UMLRTCapsuleToControllerMap::debugOutputControllerList()
210{
211 BDEBUG(BD_MODEL, "Controller list: { <controller name>, <instance address> }\n");
212
213 UMLRTHashMap::Iterator iter = getControllerNameMap()->getIterator();
214
215 if (iter == iter.end())
216 {
217 BDEBUG(BD_MODEL, " No controllers.\n");
218 }
219 else
220 {
221 while (iter != iter.end())
222 {
223 BDEBUG(BD_MODEL, " { %s, %p }\n", ((UMLRTController *)((char *)iter.getObject()))->getName(), (UMLRTController *)((char *)iter.getObject()));
224 iter = iter.next();
225 }
226 }
227}
228
229/*static*/ void UMLRTCapsuleToControllerMap::debugOutputCapsuleList()
230{
231 BDEBUG(BD_MODEL, "Capsule list: { <capsule name>, <instance address>, <capsule class>, <assigned controller> }\n");
232
233 UMLRTHashMap::Iterator iter = getCapsuleNameMap()->getIterator();
234
235 if (iter == iter.end())
236 {
237 BDEBUG(BD_MODEL, " No capsules.\n");
238 }
239 else
240 {
241 while (iter != iter.end())
242 {
243 UMLRTCapsule * capsule = (UMLRTCapsule *)iter.getObject();
244 BDEBUG(BD_MODEL, " { %s, %p, %s, %s }\n",
245 capsule->getName(), capsule, capsule->getClass()->name, capsule->getSlot()->controller->getName());
246 iter = iter.next();
247 }
248 }
249}
250
251// Debug output of capsule-to-controller map.
252/*static*/ void UMLRTCapsuleToControllerMap::debugOutputCaspuleToControllerMap()
253{
254 BDEBUG(BD_MODEL, "Capsule to controller map: { <slot>, <controller>, <capsule class> }\n");
255
256 UMLRTHashMap::Iterator ctclIter = getCapsuleToControllerListMap()->getIterator();
257
258 if (ctclIter == ctclIter.end())
259 {
260 BDEBUG(BD_MODEL, " No capsule to controller assignments.\n");
261 }
262 else
263 {
264 while (ctclIter != ctclIter.end())
265 {
266 const char * capsuleName = (const char *)ctclIter.getKey();
267 UMLRTHashMap * controllerList = (UMLRTHashMap *)ctclIter.getObject();
268 if (controllerList)
269 {
270 UMLRTHashMap::Iterator clIter = controllerList->getIterator();
271 while (clIter != clIter.end())
272 {
273 BDEBUG(BD_MODEL, " { %s, %s, %s }\n",
274 capsuleName,
275 (clIter.getObject() == NULL) ? "?no controller?" : clIter.getObject(),
276 (clIter.getKey() == NULL) ? "(default)" : clIter.getKey());
277 clIter = clIter.next();
278 }
279 }
280 ctclIter = ctclIter.next();
281 }
282 }
283}
284
285