Kevin Rocard | 93250d1 | 2012-07-19 17:48:30 +0200 | [diff] [blame] | 1 | /* |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 2 | * INTEL CONFIDENTIAL |
| 3 | * Copyright © 2011 Intel |
| 4 | * Corporation All Rights Reserved. |
| 5 | * |
| 6 | * The source code contained or described herein and all documents related to |
| 7 | * the source code ("Material") are owned by Intel Corporation or its suppliers |
| 8 | * or licensors. Title to the Material remains with Intel Corporation or its |
| 9 | * suppliers and licensors. The Material contains trade secrets and proprietary |
| 10 | * and confidential information of Intel or its suppliers and licensors. The |
| 11 | * Material is protected by worldwide copyright and trade secret laws and |
| 12 | * treaty provisions. No part of the Material may be used, copied, reproduced, |
| 13 | * modified, published, uploaded, posted, transmitted, distributed, or |
| 14 | * disclosed in any way without Intel’s prior express written permission. |
| 15 | * |
| 16 | * No license under any patent, copyright, trade secret or other intellectual |
| 17 | * property right is granted to or conferred upon you by disclosure or delivery |
| 18 | * of the Materials, either expressly, by implication, inducement, estoppel or |
| 19 | * otherwise. Any license under such intellectual property rights must be |
| 20 | * express and approved by Intel in writing. |
| 21 | * |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 22 | * CREATED: 2011-06-01 |
| 23 | * UPDATED: 2011-07-27 |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 24 | */ |
| 25 | #include "Subsystem.h" |
| 26 | #include "ComponentLibrary.h" |
| 27 | #include "InstanceDefinition.h" |
| 28 | #include "XmlParameterSerializingContext.h" |
| 29 | #include "ParameterAccessContext.h" |
| 30 | #include "ConfigurationAccessContext.h" |
| 31 | #include "SubsystemObjectCreator.h" |
| 32 | #include <assert.h> |
| 33 | |
| 34 | #define base CConfigurableElement |
| 35 | |
| 36 | CSubsystem::CSubsystem(const string& strName) : base(strName), _pComponentLibrary(new CComponentLibrary), _pInstanceDefinition(new CInstanceDefinition), _bBigEndian(false) |
| 37 | { |
| 38 | // Note: A subsystem contains instance components |
| 39 | // InstanceDefintion and ComponentLibrary objects are then not chosen to be children |
| 40 | // They'll be delt with locally |
| 41 | } |
| 42 | |
| 43 | CSubsystem::~CSubsystem() |
| 44 | { |
| 45 | // Remove subsystem objects |
| 46 | SubsystemObjectListIterator subsystemObjectIt; |
| 47 | |
| 48 | for (subsystemObjectIt = _subsystemObjectList.begin(); subsystemObjectIt != _subsystemObjectList.end(); ++subsystemObjectIt) { |
| 49 | |
| 50 | delete *subsystemObjectIt; |
| 51 | } |
| 52 | |
| 53 | // Remove susbsystem creators |
| 54 | uint32_t uiIndex; |
| 55 | |
| 56 | for (uiIndex = 0; uiIndex < _subsystemObjectCreatorArray.size(); uiIndex++) { |
| 57 | |
| 58 | delete _subsystemObjectCreatorArray[uiIndex]; |
| 59 | } |
| 60 | |
| 61 | // Order matters! |
| 62 | delete _pInstanceDefinition; |
| 63 | delete _pComponentLibrary; |
| 64 | } |
| 65 | |
| 66 | string CSubsystem::getKind() const |
| 67 | { |
| 68 | return "Subsystem"; |
| 69 | } |
| 70 | |
| 71 | // Susbsystem Endianness |
| 72 | bool CSubsystem::isBigEndian() const |
| 73 | { |
| 74 | return _bBigEndian; |
| 75 | } |
| 76 | |
Guillaume Denneulin | f2fd15a | 2012-12-20 17:53:29 +0100 | [diff] [blame] | 77 | // Susbsystem sanity |
| 78 | bool CSubsystem::isAlive() const |
| 79 | { |
| 80 | return true; |
| 81 | } |
| 82 | |
| 83 | // Resynchronization after subsystem restart needed |
| 84 | bool CSubsystem::needResync(bool bClear) |
| 85 | { |
| 86 | (void)bClear; |
| 87 | |
| 88 | return false; |
| 89 | } |
| 90 | |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 91 | // From IXmlSink |
| 92 | bool CSubsystem::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext) |
| 93 | { |
| 94 | // Context |
| 95 | CXmlParameterSerializingContext& parameterBuildContext = static_cast<CXmlParameterSerializingContext&>(serializingContext); |
| 96 | |
| 97 | // Install temporary component library for further component creation |
| 98 | parameterBuildContext.setComponentLibrary(_pComponentLibrary); |
| 99 | |
| 100 | CXmlElement childElement; |
| 101 | |
| 102 | // XML populate ComponentLibrary |
| 103 | xmlElement.getChildElement("ComponentLibrary", childElement); |
| 104 | |
| 105 | if (!_pComponentLibrary->fromXml(childElement, serializingContext)) { |
| 106 | |
| 107 | return false; |
| 108 | } |
| 109 | |
| 110 | // XML populate InstanceDefintion |
| 111 | xmlElement.getChildElement("InstanceDefintion", childElement); |
| 112 | if (!_pInstanceDefinition->fromXml(childElement, serializingContext)) { |
| 113 | |
| 114 | return false; |
| 115 | } |
| 116 | |
| 117 | // Create components |
| 118 | _pInstanceDefinition->createInstances(this); |
| 119 | |
| 120 | // Execute mapping to create subsystem mapping entities |
| 121 | string strError; |
| 122 | if (!mapSubsystemElements(strError)) { |
| 123 | |
| 124 | serializingContext.setError(strError); |
| 125 | |
| 126 | return false; |
| 127 | } |
| 128 | |
| 129 | // Endianness |
| 130 | _bBigEndian = xmlElement.getAttributeBoolean("Endianness", "Big"); |
| 131 | |
| 132 | return true; |
| 133 | } |
| 134 | |
| 135 | // XML configuration settings parsing |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 136 | bool CSubsystem::serializeXmlSettings(CXmlElement& xmlConfigurationSettingsElementContent, CConfigurationAccessContext& configurationAccessContext) const |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 137 | { |
| 138 | // Fix Endianness |
| 139 | configurationAccessContext.setBigEndianSubsystem(_bBigEndian); |
| 140 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 141 | return base::serializeXmlSettings(xmlConfigurationSettingsElementContent, configurationAccessContext); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 142 | } |
| 143 | |
| 144 | |
| 145 | bool CSubsystem::mapSubsystemElements(string& strError) |
| 146 | { |
| 147 | // Default mapping context |
| 148 | _contextStack.push(CMappingContext(_contextMappingKeyArray.size())); |
| 149 | |
| 150 | // Map all instantiated subelements in subsystem |
| 151 | uint32_t uiNbChildren = getNbChildren(); |
| 152 | uint32_t uiChild; |
| 153 | |
| 154 | for (uiChild = 0; uiChild < uiNbChildren; uiChild++) { |
| 155 | |
| 156 | CInstanceConfigurableElement* pInstanceConfigurableChildElement = static_cast<CInstanceConfigurableElement*>(getChild(uiChild)); |
| 157 | |
| 158 | if (!pInstanceConfigurableChildElement->map(*this, strError)) { |
| 159 | |
| 160 | return false; |
| 161 | } |
| 162 | } |
| 163 | return true; |
| 164 | } |
| 165 | |
| 166 | // Parameter access |
Patrick Benavoli | 065264a | 2011-11-20 15:46:41 +0100 | [diff] [blame] | 167 | bool CSubsystem::accessValue(CPathNavigator& pathNavigator, string& strValue, bool bSet, CParameterAccessContext& parameterAccessContext) const |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 168 | { |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 169 | // Deal with Endianness |
Patrick Benavoli | 065264a | 2011-11-20 15:46:41 +0100 | [diff] [blame] | 170 | parameterAccessContext.setBigEndianSubsystem(_bBigEndian); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 171 | |
Patrick Benavoli | 065264a | 2011-11-20 15:46:41 +0100 | [diff] [blame] | 172 | return base::accessValue(pathNavigator, strValue, bSet, parameterAccessContext); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 173 | } |
| 174 | |
| 175 | void CSubsystem::logValue(string& strValue, CErrorContext& errorContext) const |
| 176 | { |
Patrick Benavoli | 065264a | 2011-11-20 15:46:41 +0100 | [diff] [blame] | 177 | CParameterAccessContext& parameterAccessContext = static_cast<CParameterAccessContext&>(errorContext); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 178 | |
| 179 | // Deal with Endianness |
Patrick Benavoli | 065264a | 2011-11-20 15:46:41 +0100 | [diff] [blame] | 180 | parameterAccessContext.setBigEndianSubsystem(_bBigEndian); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 181 | |
| 182 | return base::logValue(strValue, errorContext); |
| 183 | } |
| 184 | |
Patrick Benavoli | 6ccab9d | 2011-11-10 23:21:01 +0100 | [diff] [blame] | 185 | // Used for simulation and virtual subsystems |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 186 | void CSubsystem::setDefaultValues(CParameterAccessContext& parameterAccessContext) const |
| 187 | { |
| 188 | // Deal with Endianness |
| 189 | parameterAccessContext.setBigEndianSubsystem(_bBigEndian); |
| 190 | |
| 191 | base::setDefaultValues(parameterAccessContext); |
| 192 | } |
| 193 | |
| 194 | // Belonging subsystem |
| 195 | const CSubsystem* CSubsystem::getBelongingSubsystem() const |
| 196 | { |
| 197 | return this; |
| 198 | } |
| 199 | |
| 200 | // Subsystem context mapping keys publication |
| 201 | void CSubsystem::addContextMappingKey(const string& strMappingKey) |
| 202 | { |
| 203 | _contextMappingKeyArray.push_back(strMappingKey); |
| 204 | } |
| 205 | |
| 206 | // Subsystem object creator publication (strong reference) |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 207 | void CSubsystem::addSubsystemObjectFactory(CSubsystemObjectCreator* pSubsystemObjectCreator) |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 208 | { |
| 209 | _subsystemObjectCreatorArray.push_back(pSubsystemObjectCreator); |
| 210 | } |
| 211 | |
| 212 | // Mapping generic context handling |
| 213 | bool CSubsystem::handleMappingContext(const CInstanceConfigurableElement* pInstanceConfigurableElement, CMappingContext& context, string& strError) |
| 214 | { |
| 215 | // Feed context with found mapping data |
| 216 | uint32_t uiItem; |
| 217 | |
| 218 | for (uiItem = 0; uiItem < _contextMappingKeyArray.size(); uiItem++) { |
| 219 | |
| 220 | string strKey = _contextMappingKeyArray[uiItem]; |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 221 | const string* pStrValue; |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 222 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 223 | if (pInstanceConfigurableElement->getMappingData(strKey, pStrValue)) { |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 224 | // Assign item to context |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 225 | if (!context.setItem(uiItem, pStrValue)) { |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 226 | |
| 227 | getMappingError(strError, strKey, "Already set", pInstanceConfigurableElement); |
| 228 | |
| 229 | return false; |
| 230 | } |
| 231 | } |
| 232 | } |
| 233 | return true; |
| 234 | } |
| 235 | |
Kevin Rocard | 084cafb | 2013-01-28 17:02:08 +0100 | [diff] [blame] | 236 | // Subsystem object creation handling |
| 237 | bool CSubsystem::handleSubsystemObjectCreation( |
| 238 | CInstanceConfigurableElement* pInstanceConfigurableElement, |
| 239 | CMappingContext& context, bool& bHasCreatedSubsystemObject, string& strError) |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 240 | { |
| 241 | uint32_t uiItem; |
Kevin Rocard | 084cafb | 2013-01-28 17:02:08 +0100 | [diff] [blame] | 242 | bHasCreatedSubsystemObject = false; |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 243 | |
| 244 | for (uiItem = 0; uiItem < _subsystemObjectCreatorArray.size(); uiItem++) { |
| 245 | |
Kevin Rocard | 3414f99 | 2013-04-02 19:49:40 +0200 | [diff] [blame] | 246 | const CSubsystemObjectCreator* pSubsystemObjectCreator = |
| 247 | _subsystemObjectCreatorArray[uiItem]; |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 248 | |
| 249 | // Mapping key |
| 250 | string strKey = pSubsystemObjectCreator->getMappingKey(); |
| 251 | // Object id |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 252 | const string* pStrValue; |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 253 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 254 | if (pInstanceConfigurableElement->getMappingData(strKey, pStrValue)) { |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 255 | |
Kevin Rocard | 3414f99 | 2013-04-02 19:49:40 +0200 | [diff] [blame] | 256 | // First check context consistency |
| 257 | // (required ancestors must have been set prior to object creation) |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 258 | uint32_t uiAncestorKey; |
| 259 | uint32_t uiAncestorMask = pSubsystemObjectCreator->getAncestorMask(); |
| 260 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 261 | for (uiAncestorKey = 0; uiAncestorKey < _contextMappingKeyArray.size(); uiAncestorKey++) { |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 262 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 263 | if (!((1 << uiAncestorKey) & uiAncestorMask)) { |
| 264 | // Ancestor not required |
| 265 | continue; |
| 266 | } |
| 267 | // Check ancestor was provided |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 268 | if (!context.iSet(uiAncestorKey)) { |
| 269 | |
Kevin Rocard | 3414f99 | 2013-04-02 19:49:40 +0200 | [diff] [blame] | 270 | getMappingError(strError, strKey, _contextMappingKeyArray[uiAncestorKey] + |
| 271 | " not set", pInstanceConfigurableElement); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 272 | |
| 273 | return false; |
| 274 | } |
| 275 | } |
| 276 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 277 | // Then check configurable element size is correct |
Kevin Rocard | 3414f99 | 2013-04-02 19:49:40 +0200 | [diff] [blame] | 278 | if (pInstanceConfigurableElement->getFootPrint() > |
| 279 | pSubsystemObjectCreator->getMaxConfigurableElementSize()) { |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 280 | |
Kevin Rocard | 3414f99 | 2013-04-02 19:49:40 +0200 | [diff] [blame] | 281 | string strSizeError = "Size should not exceed " + |
| 282 | pSubsystemObjectCreator->getMaxConfigurableElementSize(); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 283 | |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 284 | getMappingError(strError, strKey, strSizeError, pInstanceConfigurableElement); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 285 | |
| 286 | return false; |
| 287 | } |
Patrick Benavoli | 6ba361d | 2011-08-31 11:23:24 +0200 | [diff] [blame] | 288 | |
| 289 | // Do create object and keep its track |
Kevin Rocard | 3414f99 | 2013-04-02 19:49:40 +0200 | [diff] [blame] | 290 | _subsystemObjectList.push_back(pSubsystemObjectCreator->objectCreate( |
| 291 | *pStrValue, pInstanceConfigurableElement, context)); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 292 | |
Kevin Rocard | 084cafb | 2013-01-28 17:02:08 +0100 | [diff] [blame] | 293 | // Indicate subsytem creation to caller |
| 294 | bHasCreatedSubsystemObject = true; |
| 295 | |
| 296 | // The subsystem Object has been instantiated, no need to continue looking for an |
| 297 | // instantiation mapping |
| 298 | break; |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 299 | } |
| 300 | } |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 301 | |
Kevin Rocard | 084cafb | 2013-01-28 17:02:08 +0100 | [diff] [blame] | 302 | return true; |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 303 | } |
| 304 | |
| 305 | // Generic error handling from derived subsystem classes |
Kevin Rocard | 3414f99 | 2013-04-02 19:49:40 +0200 | [diff] [blame] | 306 | void CSubsystem::getMappingError(string& strError, const string& strKey, const string& strMessage, |
| 307 | const CInstanceConfigurableElement* pInstanceConfigurableElement) |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 308 | { |
Kevin Rocard | 3414f99 | 2013-04-02 19:49:40 +0200 | [diff] [blame] | 309 | strError = getName() + " " + getKind() + " " |
| 310 | "mapping:\n" + strKey + " " |
| 311 | "error: \"" + strMessage + "\" " |
| 312 | "for element " + pInstanceConfigurableElement->getPath(); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 313 | } |
| 314 | |
| 315 | // From IMapper |
Kevin Rocard | 084cafb | 2013-01-28 17:02:08 +0100 | [diff] [blame] | 316 | // Handle a configurable element mapping |
| 317 | bool CSubsystem::mapBegin(CInstanceConfigurableElement* pInstanceConfigurableElement, |
| 318 | bool& bKeepDiving, string& strError) |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 319 | { |
| 320 | // Get current context |
| 321 | CMappingContext context = _contextStack.top(); |
| 322 | |
Kevin Rocard | 084cafb | 2013-01-28 17:02:08 +0100 | [diff] [blame] | 323 | // Add mapping in context |
| 324 | if (!handleMappingContext(pInstanceConfigurableElement, context, strError)) { |
| 325 | |
| 326 | return false; |
| 327 | } |
| 328 | |
| 329 | // Push context |
| 330 | _contextStack.push(context); |
| 331 | |
| 332 | // Assume diving by default |
| 333 | bKeepDiving = true; |
| 334 | |
| 335 | // Deal with ambiguous usage of parameter blocks |
| 336 | bool bShouldCreateSubsystemObject = true; |
| 337 | |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 338 | switch(pInstanceConfigurableElement->getType()) { |
| 339 | |
Kevin Rocard | 084cafb | 2013-01-28 17:02:08 +0100 | [diff] [blame] | 340 | case CInstanceConfigurableElement::EComponent: |
| 341 | return true; |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 342 | |
Kevin Rocard | 084cafb | 2013-01-28 17:02:08 +0100 | [diff] [blame] | 343 | case CInstanceConfigurableElement::EParameterBlock: |
| 344 | // Subsystem object creation is optional in parameter blocks |
| 345 | bShouldCreateSubsystemObject = false; |
| 346 | // No break |
| 347 | case CInstanceConfigurableElement::EBitParameterBlock: |
| 348 | case CInstanceConfigurableElement::EParameter: |
| 349 | case CInstanceConfigurableElement::EStringParameter: |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 350 | |
Kevin Rocard | 084cafb | 2013-01-28 17:02:08 +0100 | [diff] [blame] | 351 | bool bHasCreatedSubsystemObject; |
| 352 | |
| 353 | if (!handleSubsystemObjectCreation(pInstanceConfigurableElement, context, |
| 354 | bHasCreatedSubsystemObject, strError)) { |
| 355 | |
| 356 | return false; |
| 357 | } |
| 358 | // Check for creation error |
| 359 | if (bShouldCreateSubsystemObject && !bHasCreatedSubsystemObject) { |
| 360 | |
| 361 | getMappingError(strError, "Not found", |
| 362 | "Subsystem object mapping key is missing", |
| 363 | pInstanceConfigurableElement); |
| 364 | return false; |
| 365 | } |
| 366 | // Not created and no error, keep diving |
| 367 | bKeepDiving = !bHasCreatedSubsystemObject; |
| 368 | |
| 369 | return true; |
| 370 | |
| 371 | default: |
| 372 | assert(0); |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 373 | return false; |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 374 | } |
Patrick Benavoli | 68a9128 | 2011-08-31 11:23:23 +0200 | [diff] [blame] | 375 | } |
| 376 | |
| 377 | void CSubsystem::mapEnd() |
| 378 | { |
| 379 | // Unstack context |
| 380 | _contextStack.pop(); |
| 381 | } |