Menu

Copying AAF objects between files

John Emmas
2002-07-28
2015-08-14
  • John Emmas

    John Emmas - 2002-07-28

    When I first downloaded the AAF toolkit some weeks ago, my biggest disappointment was that IAAFMob:CloneExternal() didn't function.  I'd been asked to write an application which would have required this functionality - so, in my naivety, I decided to write it myself.  It's turned out to be a mammoth task and, although I'm now about 70% of the way through it, to be perfectly honest I wish I'd never started.

    My first approach was to write a 'copying class' - the idea being that CloneExternal() would create an instance of this class which would then do all the hard work.  However, this proved to be much too unweildy, because many of its functions were just repeating the same blocks of code over and over again.  I've realised now that a simpler approach is to give AAF objects the ability to copy themselves - i.e. each IAAF class would acquire a 'CopyExternal' function (as would it's associated 'Impl' class).  This way is simpler, neater and (most importantly) it's object oriented.  To copy an object you call it's CopyExternal' function, passing a pointer to the destination file (i.e. the file you want the object to copy itself into) and also the address of a pointer so it can return the copied object.  The downside with this method is that it's much more invasive - requiring many additions to the exisiting library code.

    I don't know how the future development of IAAFMob::CloneExternal() has been planned but I'd like to canvass opinion on whether developers think this concept is a 'good thing'.  I'm willing to write the functionality myself and I could supply some sample code and a small app if anyone wants to test it.  The final code, of course, would be donated to the AAF Association.

     
    • Phil Tudor

      Phil Tudor - 2002-08-05

      John,

      FYI, here is Tim Bingham's response to this (this had been emailed to eng@aafassociation.org).

      Regards,

      Phil

      ------------------------------------------------

      Hi Phil,

      > FYI, some work on IAAFMob::CloneExternal. Any comments?

      It doesn't look like this is based on the work I've already done in the
      ObjectManager explicitly to support Copy/Clone.

      The required Object Manager support has existed on AAF.SourceForge.net as of
      RC1 (e.g. OMStorable.cpp,1.60 April 2001). What is missing is Impl
      code to exploit and expose it through the public API. I believe that work has
      been started here at Avid to write that missing Impl code.

      Details follow, once those have been digested lets see if we can combine John's
      work with what's already been done. The missing Copy/Clone stuff is a hole
      in the API functionality that would be nice to plug.

      Cheers,
      Tim.

      Details ....

      AAF objects already know how to copy themselves. All AAF objects descend from
      OMStorable which has the following methods -

        OMStorable* shallowCopy(void) const;
        OMStorable* shallowCopy(const OMClassFactory* factory) const;
        void deepCopyTo(OMStorable* destination, void* clientContext) const;

      these implement a two-stage copy that will correctly copy any descendant of OMStorable. The design for this is described in the attachment design1.txt

      There is AAF specific work that needs to be done in the Impl
      code i.e. 1) specific semantics of Copy/Clone with media etc and 2) ensuring that
      the correct definitions (class, property, type etc.) exist in the target file
      for the object being copied. The design for this is described in attachment
      design2.txt.

      These latter requirements are supported by the following callback functions
      which are currently stubs on AAF.SourceForge.net

      I've attached the most important design notes, with names changed to protect
      the innocent ;-)

      (included inline now... Phil)

      From:    Tim Bingham on 11/02/2001 10:33 AM
      To:    xxxxx
      cc:    Tim Bingham/AM/Avid@Avid
      Subject:    AAFMob::CloneExternal() and AAFMob::Copy()

      Hi xxxxx,

      This morning you asked about AAF support for cloning Mobs. Here's a
      reminder of where this stands ...

      As of RC1 the Object Manager support need for AAFMob::CloneExternal()
      and AAFMob::Copy() was not implemented and so those methods return
      NOT_IN_CURRENT_VERSION. Since RC1 I have implemented the required
      Object Manager functionality.

      Some work remains to implement AAFMob::CloneExternal() and
      AAFMob::Copy() in terms of OMStorable::shallowCopy(),
      OMStorable:deepCopyTo() and OMStorable::onCopy().

      Let me know if you have questions - I'll be happy to help.

      Cheers,
      Tim.

      ---------------------- Forwarded by Tim Bingham/AM/Avid on 11/02/2001 10:26 AM ---------------------------
      To:    xxxxx
      cc:    xxxxx
      Subject:    AAFMob::CloneExternal() and AAFMob::Copy()

      Hi xxxxx,

      I wanted to follow up on our phone conversation with some details. As
      of RC1 the methods AAFMob::CloneExternal() and AAFMob::Copy() return
      NOT_IN_CURRENT_VERSION.

      These Object Manager functionality needed by these functions is
      available but is not yet being used by the Impl classes.

      The ObjectManager functionality is in the form of the following
      OMStorable methods ...

        OMStorable* shallowCopy(void) const;

        void deepCopyTo(OMStorable* destination, void* clientContext) const;

        virtual void onCopy(void* clientContext) const;

      See the comments in OMStorable.h for details.

      The functions are designed to be used as ...

        // Create a shallow copy
        OMStorable* d =  s->shallowCopy();

        // Attach the shallow copy
        someProperty.someInsertionFunction(d);

        // Do the deep copy
        s->deepCopyTo(d, context);

      In fact, this is how deepCopy() is implemented.

      The onCopy() call back is made during deepCopy() on each newly copied
      object after the shallow portion of a copy has been made and before
      the deep portion is made. The onCopy() callback is intended for use in
      resolving weak references e.g. when copying from one file to another
      you need to make sure that all the new objects have definitions in the
      dictionary of the target file. The onCopy() callback is also intended
      for use in implementing the Copy() vs. Clone() semantics of whether
      new Mobs keep the same MobID or get a new one.

      Note that I didn't provide a direct way to implement the
      "includeMedia" flag on CloneExternal(). I suggest that you handle this
      by copying the Mobs and the EssenceData objects separately. To exclude
      the media, copy the EssenceData objects using shallowCopy(), to
      include it copy the EssenceData objects with deepCopyTo().

      I have tested these functions using my example (non-AAF) object model
      and everything seems to work OK. However, I can't be sure I've got
      everything right for AAF until someone tries to use these functions
      from the Impl classes.

      I'll be happy to work with you, or anyone else, to resolve any issues
      that arise.

      Cheers,
      Tim.

      From:    Tim Bingham on 12/04/2001 03:40 PM
      To:    xxxxx
      cc:    Tim Bingham/AM/Avid@Avid
      Subject:    copying objects/properties and definitions across files

      Hi xxxxx,

      In yyyyyyyyyyy I've put some changed files that define new OM function
      interfaces that the Impl layer must implement. I've included stbus for
      the new Impl functions. Search for "// tjb for ak - stub"

      The new Impl functions are

      virtual bool ImplAAFMetaDictionary::isRegistered(
                                                     const OMClassId& classId) const;
      virtual bool ImplAAFDictionary::isRegistered(const OMClassId& classId) const;

      virtual const OMUniqueObjectIdentification&
      ImplAAFPropertyDef::uniqueIdentification(void) const;

      virtual const OMPropertyDefinition*
      ImplAAFClassDefinition::propertyDefinition(
                                       const OMUniqueObjectIdentification& id) const;

      Cheers,
      Tim.

      ---------------------- Forwarded by Tim Bingham/AM/Avid on 12/04/2001
      03:30 PM ---------------------------
      From:    Tim Bingham on 11/30/2001 12:51 PM
      To:    xxxxx
      cc:    Tim Bingham/AM/Avid@Avid
      Subject:    copying objects/propertis and definitions across files

      Hi xxxxx,

      Here's an overview of my proposed solution to the issues you raised
      yesterday.

      The issues are

      property ids for extended properties are not the same across files how
      to ensure that definitions for objects/properties being copied are in
      the target file if definitions for objects/properties being copied are
      missing from the target file then those objects/properties should not
      be copied

      for issues 1 and 3 I propose

        const OMStoredObjectIdentification& id = classId();
        if (factory->isRegisteredClass(id) {
          OMStorable* object = factory->create(id);
          ASSERT("Registered class id", object != 0);

          OMPropertySetIterator iterator(_persistentProperties, OMBefore);
          while (++iterator) {
            OMProperty* source = iterator.property();
            ASSERT("Valid property", source != 0);
            if (!source->isOptional() || source->isPresent()) {
              // compute target pid
              OMPropertyId pid;
              if (source->isPredefined() || (classFactory() == factory)) {
                // predefined property or extension property to same file
                // target pid is same as source pid
                pid = source->propertyId();
              } else {
                // extension property to different file
                // target pid not same as source pid
                propId = source->definition()->identifier();
                destClassDef = dest->definition();
                destPropDef = destClassDef->lookUpPropertyDef(propId);
                pid = destPropDef->localIdentification();
              }
              // Copy property
              OMPropertySet* target = object->propertySet();
              ASSERT("Valid target property set", target != 0);
              if (target->isAllowed(pid) && target->isPresent(pid)) {
                OMProperty* dest = target->get(pid);
                source->shallowCopyTo(dest);
              } // else ignore unknown property
            }
          }
        } // else ignore unknown classes

      for issue 2 I propose

        // Add any definitions present in d but not already present in this.
      ImplAAFDictionary::merge(const ImplAADDictionary& d);

      This function can be called prior to calling OMStorable::shallowCopy() and
      OMStorable::deepCopyTo()

      Cheers,
      Tim.

       
    • Michelle Munson

      Michelle Munson - 2003-03-31

      Was IAAF::CloneExternal() ever implemented? Does anyone know the status of it?

       
      • John Emmas

        John Emmas - 2003-03-31

        Hi Michelle,

        I implemented most (though not all) of the ability for AAF interface objects to copy themselves, with or without the essence data (as appropriate).  I'll freely admit though that it was an interminably boring task and each time I completed a stage there seemed to be more and more stages still to do!  Some of the more esoteric interfaces definitely had me confused (things like IAAFMetaDefinition) but I'd estimate that I completed about 70% of the work though.

        Having said that, Tim's method of shallow and deep copying was far superior to my implementation - and, of course it forms part of the official spec (which mine doesn't) so I'd recommend pursuing that line first.  I don't know how far he got with it.  In my case, I simply needed the copying ability "there and then" and, as it wasn't available there and then, I just had to write it.  I had no other choice.  It does work but I don't want to set a precedent by distributing unofficial code.

        I would happily donate it to the AAF Association though, if someone would volunteer to help me with the bits I got stuck on (most of the work is genuinely done - honest!)

         
    • Jim Trainor

      Jim Trainor - 2003-04-26

      IAAFMob::{Copy,CloneExternal} implementations are now available.

      The new code is in a branch tagged: "BRANCH_CLONE_DEV".  The branch tag was only applied to the ref-impl directory.

      After a bit more testing, cleaning, and review, it will be merged into the main branch.

      I've tested it by cloning all the mob types in the aaf file generated by the "examples2/axExample" program.

      I've only tested WinNT/Debug.

       
    • Jim Trainor

      Jim Trainor - 2003-04-30

      The Copy and CloneExternal code in now in the main branch.

       
    • Jim Trainor

      Jim Trainor - 2003-05-29

      Support for cloning extended classes is now implemented.  It is currently residing in a ref-impl branch tagged Branch_Clone_Extended_Dev.

      It will make its way to the main branch in a week or two.

      Regards

       
  • Bill Baker

    Bill Baker - 2015-08-14

    To revive an extremely old discussion, was a method ever added to the AAF SDK to copy an object and its children to a new AAF file? The equivalent of IAAF::CloneExternal() (which works great) for objects, such as a component array from a sequence class?

     

Log in to post a comment.