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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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 -
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 ...
// 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"
---------------------- 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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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!)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
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.
Was IAAF::CloneExternal() ever implemented? Does anyone know the status of it?
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!)
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.
The Copy and CloneExternal code in now in the main branch.
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
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?