void SwapFieldElementCommand::undo(void)
{
    Inherited::undo();

    EditFieldHandlePtr TheFieldHandle = _FC->editField(_FieldId);
    if(TheFieldHandle->isPointerField())
    {
        EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));
        FieldContainer* ToFC = TheHandle->get(_ToIndex);
        FieldContainer* FromFC = TheHandle->get(_FromIndex);

        TheHandle->replace(_FromIndex, ToFC);
        TheHandle->replace(_ToIndex, FromFC);
    }
    else
    {
        //Get the to index value
        std::ostringstream StrStream;
        OutStream TheOutStream(StrStream);

        TheFieldHandle->pushIndexedValueToStream(TheOutStream, _ToIndex);
        std::string ToValue = StrStream.str();

        //Get the from index value
        StrStream.clear();
        StrStream.str("");
        TheFieldHandle->pushIndexedValueToStream(TheOutStream, _FromIndex);
        std::string FromValue = StrStream.str();

        //Set the value
        TheFieldHandle->pushIndexedValueFromCString(ToValue.c_str(), _FromIndex);
        TheFieldHandle->pushIndexedValueFromCString(FromValue.c_str(), _ToIndex);
    }

}
void InsertFieldElementCommand::execute(void)
{
    //Check for a valid Field Container
    if(_FC == NULL)
    {
        SWARNING << "FieldContainer is NULL." << std::endl;
        return;
    }

    //Check for valid Field
    EditFieldHandlePtr TheFieldHandle = _FC->editField(_FieldId);
    if(!TheFieldHandle->isValid())
    {
        SWARNING << "No Field with Id: " << _FieldId << " in FieldContainers of type " << _FC->getType().getName() << std::endl;
        return;
    }

    //Check for valid Field cardinality
    if(TheFieldHandle->getCardinality() != FieldType::MultiField)
    {
        SWARNING << "Field: " << _FC->getType().getName() << " is not a MultiField" << std::endl;
        return;
    }

    //Check for valid indexing
    if(TheFieldHandle->getCardinality() == FieldType::MultiField && _Index > TheFieldHandle->size())
    {
        SWARNING << "Cannot insert the value " << _Value << " at index " << _Index << ", on field " << TheFieldHandle->getDescription()->getName() 
                 << ", on FieldContianer of type " << _FC->getType().getName()
                 << " because that field has size " << TheFieldHandle->size() << std::endl;
        return;
    }
        
    if(TheFieldHandle->isPointerField())
    {
        EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));
        FieldContainer* FC = FieldContainerFactory::the()->getContainer(boost::lexical_cast<UInt32>(_Value));
        //Check the pointer types match
        if(!isFieldContentDerivedFrom(TheFieldHandle->getType(),&FC->getType()))
        {
            SWARNING << "Cannot insert the value of field " << TheFieldHandle->getDescription()->getName() 
                     << ", on FieldContianer of type " << _FC->getType().getName()
                     << " because the value attemting to be set is not derived from the type the field stores." << std::endl;
            return;
        }

        TheHandle->insert(_Index, FC);
    }
    else
    {
        TheFieldHandle->insertIndexedValueFromCString(_Value.c_str(), _Index);
    }

    Inherited::execute();
	_HasBeenDone = true;
}
FieldContainerTransitPtr deepClone(
          OSG::FieldContainer const                        *src,
    const std::vector<const OSG::ReflexiveContainerType *> &shareTypes,
    const std::vector<const OSG::ReflexiveContainerType *> &ignoreTypes,
    const std::vector<OSG::UInt16>                         &shareGroupIds,
    const std::vector<OSG::UInt16>                         &ignoreGroupIds)
{
    if(src == NULL)
        return FieldContainerTransitPtr(NULL);

    const FieldContainerType &fcType  = src->getType();
    FieldContainerTransitPtr  fcClone = fcType.createContainer();

    UInt32 fCount = osgMin(fcType            .getNumFieldDescs(),
                           fcClone->getType().getNumFieldDescs() );

    for(UInt32 i = 1; i <= fCount; ++i)
    {
        const FieldDescriptionBase *fDesc = fcType.getFieldDesc(i);

        if(fDesc->isInternal())
            continue;

        GetFieldHandlePtr  srcField = src    ->getField (i);
        EditFieldHandlePtr dstField = fcClone->editField(i);

        if(dstField == NULL || dstField->isValid() == false || 
           srcField == NULL || srcField->isValid() == false)
        {
            continue;
        }

        if(srcField->isPointerField() == false)
        {
            dstField->copyValues(srcField);
        }
        else
        {
            dstField->cloneValues(srcField, 
                                  shareTypes,    
                                  ignoreTypes,
                                  shareGroupIds, 
                                  ignoreGroupIds);
        }
    }

    return fcClone;
}
void InsertFieldElementCommand::undo(void)
{
    Inherited::undo();

    //Remove the element that was inserted
    EditFieldHandlePtr TheFieldHandle = _FC->editField(_FieldId); 
    if(TheFieldHandle->isPointerField())
    {
        EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));

        TheHandle->remove(_Index);
    }
    else
    {
        TheFieldHandle->removeIndex(_Index);
    }
}
void MoveFieldElementCommand::undo(void)
{
    Inherited::undo();

    EditFieldHandlePtr TheFieldHandle = _FC->editField(_FieldId);
    if(TheFieldHandle->isPointerField())
    {
        EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));
        FieldContainerUnrecPtr ToFC = TheHandle->get(_ToIndex);
        TheHandle->remove(_ToIndex);
        TheHandle->insert(_FromIndex, ToFC);
    }
    else
    {
        //Get the to index value
        std::ostringstream StrStream;
        OutStream TheOutStream(StrStream);

        //Set the value
        if(_ToIndex < _FromIndex)
        {
            TheFieldHandle->pushIndexedValueToStream(TheOutStream, _ToIndex);
            TheFieldHandle->insertIndexedValueFromCString(StrStream.str().c_str(), _FromIndex+1);
        }
        else
        {
            TheFieldHandle->pushIndexedValueToStream(TheOutStream, _ToIndex-1);
            TheFieldHandle->insertIndexedValueFromCString(StrStream.str().c_str(), _FromIndex);
        }
        TheFieldHandle->removeIndex(_ToIndex);
    }

}
void InsertFieldElementCommand::redo(void)
{
    Inherited::redo();

    //Set the value
    EditFieldHandlePtr TheFieldHandle = _FC->editField(_FieldId);
    if(TheFieldHandle->isPointerField())
    {
        EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));
        FieldContainer* FC = FieldContainerFactory::the()->getContainer(boost::lexical_cast<UInt32>(_Value));

        TheHandle->insert(_Index, FC);
    }
    else
    {
        TheFieldHandle->insertIndexedValueFromCString(_Value.c_str(), _Index);
    }
}
void GenericMultiFieldEditor::insertAtIndex(FieldContainer* const fc,
                                            UInt32 fieldID,
                                            UInt32 index,
                                            const FieldContainerType* type,
                                            CommandManager* cmdMgr)
{
    const FieldContainerType* ThePtrType(getFieldContainerTypeFromPtrType(fc->getFieldDescription(fieldID)->getFieldType().getContentType()));

    //Create the Container
    CreateFieldContainerCommandPtr CreateCommand;
    
    //If the type is a node, then create a NodeCore instead
    //and then insert it as the core of a newly created node
    if(*ThePtrType == Node::getClassType())
    {
        CreateFieldContainerCommandPtr CreateCoreCommand = CreateFieldContainerCommand::create(type);
        cmdMgr->executeCommand(CreateCoreCommand);
        
        CreateCommand = CreateFieldContainerCommand::create(&Node::getClassType());
        cmdMgr->executeCommand(CreateCommand);

        dynamic_cast<Node*>(CreateCommand->getContainer())->setCore(dynamic_cast<NodeCore*>(CreateCoreCommand->getContainer()));
    }
    else
    {
        CreateCommand = CreateFieldContainerCommand::create(type);
        cmdMgr->executeCommand(CreateCommand);
    }
        
    EditFieldHandlePtr TheFieldHandle = fc->editField(fieldID);
    EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));

    if(index >= fc->getField(fieldID)->size() ||
       !TheHandle->supportsInsert())
    {
        //Set the value of the field
        AddFieldElementCommandPtr AddCommand = AddFieldElementCommand::create(fc,
                                                                            fieldID,
                                                                            boost::lexical_cast<std::string>(CreateCommand->getContainer()->getId()));

        cmdMgr->executeCommand(AddCommand);
    }
    else
    {
        //Set the value of the field
        InsertFieldElementCommandPtr InsertIndexCommand = InsertFieldElementCommand::create(fc,
                                                                                            fieldID,
                                                                                            boost::lexical_cast<std::string>(CreateCommand->getContainer()->getId()),
                                                                                            index);

        cmdMgr->executeCommand(InsertIndexCommand);
    }
}
bool replacement<SFBoxVolume>(RawInterpFuncion& InterpFunc,
                              const Real32& time,
                              const Real32& prevtime,
                              const UInt32& ReplacePolicy,
                              bool isCyclic,
                              EditFieldHandlePtr Result,
                              UInt32 Index, 
                              Real32 Blend)
{
    SFBoxVolume Value(static_cast<SFBoxVolume&>(*Result->getField()).getValue());
    bool ReturnValue = InterpFunc(time, Value,isCyclic);

    if(Result->getCardinality() == FieldType::SingleField)
    {
        switch(ReplacePolicy)
        {
        case Animator::OVERWRITE:
            static_cast<SFBoxVolume&>(*Result->getField()).setValue(Value.getValue());
            break;
        default:
            SWARNING << "No policy defined for Animation value replacement policy: " << ReplacePolicy << "." << std::endl;
            break;
        }
    }
    else
    {
        switch(ReplacePolicy)
        {
        case Animator::OVERWRITE:
            static_cast<MFBoxVolume&>(*Result->getField())[Index] = Value.getValue();
            break;
        default:
            SWARNING << "No policy defined for Animation value replacement policy: " << ReplacePolicy << "." << std::endl;
            break;
        }
    }
   return ReturnValue;
}
void SwapFieldElementCommand::execute(void)
{
    //Check for a valid Field Container
    if(_FC == NULL)
    {
        SWARNING << "FieldContainer is NULL." << std::endl;
        return;
    }

    //Check for valid Field
    EditFieldHandlePtr TheFieldHandle = _FC->editField(_FieldId);
    if(!TheFieldHandle->isValid())
    {
        SWARNING << "No Field with Id: " << _FieldId << " in FieldContainers of type " << _FC->getType().getName() << std::endl;
        return;
    }

    //Check for valid Field cardinality
    if(TheFieldHandle->getCardinality() != FieldType::MultiField)
    {
        SWARNING << "Field: " << _FC->getType().getName() << " is not a MultiField" << std::endl;
        return;
    }

    //Check for valid indexing
    if(TheFieldHandle->getCardinality() == FieldType::MultiField && _FromIndex >= TheFieldHandle->size())
    {
        SWARNING << "Cannot move the value of from index " << _FromIndex << ", on field " << TheFieldHandle->getDescription()->getName() 
                 << ", on FieldContianer of type " << _FC->getType().getName()
                 << " because that field has size " << TheFieldHandle->size() << std::endl;
        return;
    }
    if(TheFieldHandle->getCardinality() == FieldType::MultiField && _ToIndex >= TheFieldHandle->size())
    {
        SWARNING << "Cannot move the value of to index " << _ToIndex << ", on field " << TheFieldHandle->getDescription()->getName() 
                 << ", on FieldContianer of type " << _FC->getType().getName()
                 << " because that field has size " << TheFieldHandle->size() << std::endl;
        return;
    }

    if(TheFieldHandle->isPointerField())
    {
        EditMFieldHandle<FieldContainerPtrMFieldBase>* TheHandle(dynamic_cast<EditMFieldHandle<FieldContainerPtrMFieldBase>*>(TheFieldHandle.get()));
        FieldContainer* ToFC = TheHandle->get(_ToIndex);
        FieldContainer* FromFC = TheHandle->get(_FromIndex);

        TheHandle->replace(_FromIndex, ToFC);
        TheHandle->replace(_ToIndex, FromFC);
    }
    else
    {
        //Get the to index value
        std::ostringstream StrStream;
        OutStream TheOutStream(StrStream);

        TheFieldHandle->pushIndexedValueToStream(TheOutStream, _ToIndex);
        std::string ToValue = StrStream.str();

        //Get the from index value
        StrStream.clear();
        StrStream.str("");
        TheFieldHandle->pushIndexedValueToStream(TheOutStream, _FromIndex);
        std::string FromValue = StrStream.str();

        //Set the value
        TheFieldHandle->pushIndexedValueFromCString(ToValue.c_str(), _FromIndex);
        TheFieldHandle->pushIndexedValueFromCString(FromValue.c_str(), _ToIndex);
    }

    Inherited::execute();
	_HasBeenDone = true;
}
FieldContainer *SharePtrGraphOp::shareFC(FieldContainer *fc)
{
    if(fc == NULL)
        return fc;

    bool   singleParent = false;
    UInt32 fcTypeId     = fc->getType().getId           ();
    UInt32 fCount       = fc->getType().getNumFieldDescs();


    FCTypeMapIt tmIt = _typeMap.find(fcTypeId);

    if(tmIt == _typeMap.end())
    {
        tmIt =
            _typeMap.insert(FCTypeMap::value_type(fcTypeId, FCSet())).first;
    }

    if(tmIt->second.count(fc) > 0)
        return fc;


    for(UInt32 i = 1; i <= fCount; ++i)
    {
        const FieldDescriptionBase *fDesc = fc->getFieldDescription(i);

        // skip parent fields
        if(fDesc->getFieldType().getClass() == FieldType::ParentPtrField)
        {
            if(fDesc->getFieldType().getCardinality() == FieldType::SingleField)
                singleParent = true;

            continue;
        }

        EditFieldHandlePtr fHandle = fc->editField(i);

        // skip non-pointer fields
#if 1
        if(fDesc->getFieldType().isPtrField() == false)
            continue;
#else
        if(fHandle != NULL)
        {
            if(fHandle->isPointerField() == false)
                continue;
        }
        else
        {
             if(fDesc->getFieldType().isPtrField() == false)
                 continue;
        }
#endif

        // skip internal fields
        if(fDesc->isInternal() == true)
            continue;

        FieldContainerPtrSFieldBase::EditHandlePtr sfPtrHandle =
            boost::dynamic_pointer_cast<
                FieldContainerPtrSFieldBase::EditHandle>(fHandle);

        FieldContainerPtrMFieldBase::EditHandlePtr mfPtrHandle =
            boost::dynamic_pointer_cast<
                FieldContainerPtrMFieldBase::EditHandle>(fHandle);

        if(sfPtrHandle != NULL && sfPtrHandle->isValid() == true)
        {
            FieldContainer *childFC    = sfPtrHandle->get();
            FieldContainer *childEquiv = shareFC(childFC);

            if(childEquiv != childFC)
            {
                sfPtrHandle->set(childEquiv);
            }
        }
        else if(mfPtrHandle != NULL && mfPtrHandle->isValid() == true)
        {
            for(UInt32 j = 0; j < mfPtrHandle->size(); ++j)
            {
                FieldContainer *childFC    = mfPtrHandle->get(j);
                FieldContainer *childEquiv = shareFC(childFC);

                if(childEquiv != childFC)
                {
                    mfPtrHandle->replace(j, childEquiv);
                }
            }
        }
#if 0
        else
        {
            SFAttachmentPtrMap::EditHandlePtr  amEditHandle =
                boost::dynamic_pointer_cast<SFAttachmentPtrMap::EditHandle>(
                    fHandle);

            SFAttachmentPtrMap::GetHandlePtr  amGetHandle =
                boost::dynamic_pointer_cast<SFAttachmentPtrMap::GetHandle>(
                    fc->getField(i));

            if(amEditHandle != NULL && amEditHandle->isValid() == true)
            {
                 const AttachmentMap &oAttMap = (*amGetHandle)->getValue();

                 AttachmentMap::const_iterator amIt  = oAttMap.begin();
                 AttachmentMap::const_iterator amEnd = oAttMap.end  ();

                 for(; amIt != amEnd; ++amIt)
                 {
                     Attachment *att      = (*amIt).second;
                     Attachment *attEquiv =  
                         dynamic_cast<Attachment *>(shareFC(att));

                     if(attEquiv != att)
                     {
                         amEditHandle->replaceByObj(att, attEquiv);
                     }
                 }
            }
        }
#endif
    }

    if(checkIncludeSet(fcTypeId) == false)
        return fc;

    if(checkExcludeSet(fcTypeId) == true)
        return fc;

    // can not share a FC with single parents
    if(singleParent == true)
        return fc;

    FCSetIt fcsIt  = tmIt->second.begin();
    FCSetIt fcsEnd = tmIt->second.end  ();

    for(; fcsIt != fcsEnd; ++fcsIt)
    {
        Time compareStart = getSystemTime();

        bool compare      = compareContainerEqual(*fcsIt, fc, true, true);

        _compareTime += getSystemTime() - compareStart;

        if(compare)
        {
            if(*fcsIt != fc)
                _shareCount[fcTypeId] += 1;

            return *fcsIt;
        }
    }

    // no equivalent FC known, add to set of unique containers
    tmIt->second.insert(fc);

    return fc;
}
Пример #11
0
void LookAndFeel::initUndefinedPrototypes(void)
{
    //Find all of the types that inherit off of the defined prototypes
    UInt32 NumFCTypes(FieldContainerFactory::the()->getNumTypes());
    const FieldContainerType* UndefinedPrototypeType(NULL);
    const FieldContainerType* ClosestAncestorType(NULL);
    FieldContainerRefPtr UndefinedPrototype(NULL);
    FieldContainerRefPtr ClosestAncestorPrototype(NULL);

    const FieldDescriptionBase* UndefinedPrototypeDesc(NULL);
    const FieldDescriptionBase* ClosestAncestorDesc(NULL);
    UInt32 NumTypesFound(0);
    for (UInt32 i(0); NumTypesFound < NumFCTypes ; ++i)
    {
        UndefinedPrototypeType = FieldContainerFactory::the()->findType(i);
        if(UndefinedPrototypeType == NULL)
        {
            continue;
        }
        else
        {
            ++NumTypesFound;
        }

        ClosestAncestorType = getClosestAncestor(UndefinedPrototypeType,
                                                 getMFPrototypes()->begin(),
                                                 getMFPrototypes()->end());
        if(ClosestAncestorType != NULL &&
           *ClosestAncestorType != *UndefinedPrototypeType &&
           !UndefinedPrototypeType->isAbstract())
        {
            SNOTICE << "UserInterface: LookAndFeel: Initializing undefined prototype for a derived user interface type" << std::endl
                    << "    Undefined Prototype Type: "   << UndefinedPrototypeType->getCName() << std::endl
                    << "    Closest Ancestor: "         << ClosestAncestorType->getCName() << std::endl;
            //For all of these types set the prototype values of all of the 
            //inherited fields to the same as the closest ancestor
            UndefinedPrototype = UndefinedPrototypeType->getPrototype();
            ClosestAncestorPrototype = ClosestAncestorType->getPrototype();
            for(UInt32 j(1); j<=ClosestAncestorType->getNumFieldDescs() ; ++j)
            {
                ClosestAncestorDesc = ClosestAncestorType->getFieldDesc(j);
                UndefinedPrototypeDesc = ClosestAncestorType->getFieldDesc(ClosestAncestorDesc->getCName());

                //Set the field to the same as this closest ancestor
                //Get the Undefined Field
                EditFieldHandlePtr UndefinedField =
                    UndefinedPrototype->editField(UndefinedPrototypeDesc->getFieldId());
                GetFieldHandlePtr ClosestAncestorField =
                    ClosestAncestorPrototype->getField(ClosestAncestorDesc->getFieldId());
                //Get the Closest Ancestor Field
                if(UndefinedField != NULL && 
                   ClosestAncestorField != NULL &&
                   !UndefinedPrototypeDesc->isInternal())
                {
                    if(UndefinedField->isPointerField())
                    {
                        UndefinedField->cloneValues(ClosestAncestorField);
                    }
                    else
                    {
                        UndefinedField->copyValues(ClosestAncestorField);
                    }
                }
            }
        }
    }
}