//============================================================================== std::string RPURU::resolveContextObjectPropertyPath(const ObjectHandle& contextObject, const char* propertyPath, IDefinitionManager& definitionManager) { assert(contextObject != nullptr); const auto classDef = contextObject.getDefinition(definitionManager); assert(classDef != nullptr); std::string tmp = propertyPath; std::vector<std::string> paths; paths.push_back(tmp); char* pch; pch = strtok(const_cast<char*>(tmp.c_str()), "."); if (pch != NULL) { pch = strtok(NULL, "."); while (pch != NULL) { paths.push_back(pch); pch = strtok(NULL, "."); } } PropertyAccessor pa; for (auto& path : paths) { resolveProperty(contextObject, *classDef, path.c_str(), pa, definitionManager); if (pa.isValid()) { break; } } return pa.getFullPath(); }
//============================================================================== ObjectHandle SetReflectedPropertyCommand::execute( const ObjectHandle & arguments ) const { ReflectedPropertyCommandArgument * commandArgs = arguments.getBase< ReflectedPropertyCommandArgument >(); auto objManager = definitionManager_.getObjectManager(); assert( objManager != nullptr ); ObjectHandle object = objManager->getObject( commandArgs->getContextId() ); if (!object.isValid()) { return CommandErrorCode::INVALID_ARGUMENTS; } PropertyAccessor property = object.getDefinition( definitionManager_ )->bindProperty( commandArgs->getPropertyPath(), object ); if (property.isValid() == false) { //Can't set return CommandErrorCode::INVALID_ARGUMENTS; } const Variant & data = commandArgs->getPropertyValue(); bool br = property.setValue( data ); if (!br) { return CommandErrorCode::INVALID_VALUE; } // Do not return the object // CommandInstance will hold a reference to the return value // and the CommandInstance is stored in the undo/redo history forever // This is due to a circular reference in CommandManagerImpl::pushFrame return nullptr; }
//============================================================================== void RPURU::resolveProperty(const ObjectHandle& handle, const IClassDefinition& classDef, const char* propertyPath, PropertyAccessor& o_Pa, IDefinitionManager& definitionManager) { o_Pa = handle.getDefinition(definitionManager)->bindProperty(propertyPath, handle); if (o_Pa.isValid()) { return; } const PropertyIteratorRange& props = classDef.allProperties(); for (PropertyIterator pi = props.begin(); pi != props.end(); ++pi) { std::string parentPath = pi->getName(); const PropertyAccessor& prop = classDef.bindProperty(parentPath.c_str(), handle); assert(prop.isValid()); if (prop.getProperty()->isMethod()) { continue; } const Variant& value = prop.getValue(); if (value.typeIs<ObjectHandle>()) { ObjectHandle subHandle; bool isOk = value.tryCast(subHandle); assert(isOk); if ((subHandle == nullptr) || (subHandle.getDefinition(definitionManager) == nullptr)) { continue; } parentPath = parentPath + "." + propertyPath; resolveProperty(subHandle, *subHandle.getDefinition(definitionManager), parentPath.c_str(), o_Pa, definitionManager); if (o_Pa.isValid()) { return; } } } }