예제 #1
0
void 
Sdf_ConnectionListEditor<ChildPolicy>::_OnEdit(
    SdfListOpType op,
    SdfSpecType specType,
    const std::vector<SdfPath>& oldItems, 
    const std::vector<SdfPath>& newItems) const
{
    if (op != SdfListOpTypeAdded and op != SdfListOpTypeExplicit) {
        return;
    }

    const SdfPath propertyPath = GetPath();
    SdfLayerHandle layer = GetLayer();
    const std::set<value_type> oldItemSet(oldItems.begin(), oldItems.end());
    const std::set<value_type> newItemSet(newItems.begin(), newItems.end());

    // Need to remove all children in oldItems that are not in newItems.
    std::vector<SdfPath> childrenToRemove;
    std::set_difference(oldItemSet.begin(), oldItemSet.end(),
                        newItemSet.begin(), newItemSet.end(), 
                        std::back_inserter(childrenToRemove));
    TF_FOR_ALL(child, childrenToRemove) {
        if (not Sdf_ChildrenUtils<ChildPolicy>::RemoveChild(
                layer, propertyPath, *child)) {

            const SdfPath specPath = 
                ChildPolicy::GetChildPath(propertyPath, *child);
            TF_CODING_ERROR("Failed to remove spec at <%s>", specPath.GetText());
        }
    }

    // Need to add all children in newItems that are not in oldItems.
    std::vector<SdfPath> childrenToAdd;
    std::set_difference(newItemSet.begin(), newItemSet.end(), 
                        oldItemSet.begin(), oldItemSet.end(),
                        std::back_inserter(childrenToAdd));
    TF_FOR_ALL(child, childrenToAdd) {
        const SdfPath specPath = ChildPolicy::GetChildPath(propertyPath, *child);
        if (layer->GetObjectAtPath(specPath)) {
            continue;
        }

        if (not Sdf_ChildrenUtils<ChildPolicy>::CreateSpec(layer, specPath,
                specType)) {
            TF_CODING_ERROR("Failed to create spec at <%s>", specPath.GetText());
        }
    }
}
void 
Sdf_ConnectionListEditor<ChildPolicy>::_OnEditShared(
    SdfListOpType op,
    SdfSpecType specType,
    const std::vector<SdfPath>& oldItems, 
    const std::vector<SdfPath>& newItems) const
{
    // XXX The following code tries to manage lifetime of the target
    // specs associated with this list, but it slightly buggy: if
    // multiple lists mention the same target -- ex. if a target is
    // added, appended, and prepended -- then this proxy for a single
    // list has no way to know if the target also exists in those
    // other lists, and so it cannot mangae lifetime on its own.

    if (op == SdfListOpTypeOrdered || op == SdfListOpTypeDeleted) {
        // These ops do not affect target spec lifetime, so there's
        // nothing to do.
        return;
    }

    const SdfPath propertyPath = GetPath();
    SdfLayerHandle layer = GetLayer();
    const std::set<value_type> oldItemSet(oldItems.begin(), oldItems.end());
    const std::set<value_type> newItemSet(newItems.begin(), newItems.end());

    // Need to remove all children in oldItems that are not in newItems.
    std::vector<SdfPath> childrenToRemove;
    std::set_difference(oldItemSet.begin(), oldItemSet.end(),
                        newItemSet.begin(), newItemSet.end(), 
                        std::back_inserter(childrenToRemove));
    TF_FOR_ALL(child, childrenToRemove) {
        if (!Sdf_ChildrenUtils<ChildPolicy>::RemoveChild(
                layer, propertyPath, *child)) {
            // Some data backends procedurally generate the children specs based
            // on the listops as an optimization, so if we failed to remove a
            // child here, it could be that.  If no spec is present, then we
            // consider things to be okay and do not issue an error.
            const SdfPath specPath = 
                ChildPolicy::GetChildPath(propertyPath, *child);
            if (layer->GetObjectAtPath(specPath)) {
                TF_CODING_ERROR("Failed to remove spec at <%s>",
                                specPath.GetText());
            }
        }
    }

    // Need to add all children in newItems that are not in oldItems.
    std::vector<SdfPath> childrenToAdd;
    std::set_difference(newItemSet.begin(), newItemSet.end(), 
                        oldItemSet.begin(), oldItemSet.end(),
                        std::back_inserter(childrenToAdd));
    TF_FOR_ALL(child, childrenToAdd) {
        const SdfPath specPath = ChildPolicy::GetChildPath(propertyPath, *child);
        if (layer->GetObjectAtPath(specPath)) {
            continue;
        }

        if (!Sdf_ChildrenUtils<ChildPolicy>::CreateSpec(layer, specPath,
                specType)) {
            TF_CODING_ERROR("Failed to create spec at <%s>", specPath.GetText());
        }
    }
}