In article <11************ **********@u30g 2000hsc.googleg roups.com>,
terminator <fa***********@ gmail.comwrote:
On May 25, 8:37 am, mark <trid...@ihug.c o.nzwrote:
SOFORef SOCastToSOF(SOR ef sor) {
SelectedFORef sof=nil;
...
return sof;
};
Is SelectedFORef castable to SOFORef ?(you have not declared the later
type.)
Really bad day for thinking yesterday.
Here's everything:
Mac OS X. XCode 2.4.
Here are the classes:
typedef class SelectedObject* SelectedObjectR ef;
typedef SelectedObjectR ef SORef;
typedef UInt32 SOOwnerID;
class SelectedObject {
UInt16 refCt;
SelObjectClass objectClass;
OSType ready;
protected:
SOOwnerID ID; // need to identify where the SO belongs. An SO in one
view will have
// different select flags to an SO in another view
SelObjectType objectType; // NYI
SelectionFlag selections;
static CFMutableSetRef soCache;
static void SOCacheSetProc( const void* value, void* ctx);
friend SORef CheckSOCache(Se lObjectClass objClass, UInt16 objType,
SOOwnerID iID, void* data);
virtual OSStatus CheckCache(SelO bjectClass objClass, UInt16 dataType,
void* data,
SORef *sor);
// the arrays are used to send one select/deselect event when a whole
lot
// of objects are selected/deselected. Sending 1000+ deselected
events is not a good
// idea
static CritRgn recentSelRgn;
static CFMutableSetRef recentlySelecte d;
static CFMutableSetRef recentlyDeselec ted;
static OSStatus PostMassSelOfOw ner(SOOwnerID ID, Boolean selOrDesel,
CFArrayRef itsItems);
static OSStatus PostMassSelectE vents(SOOwnerID whichID=0); // clears
both arrays after sending
// dtEventKindObje ctsSelected & dtEventKindObje ctsSelected
// If zero is passed, all are sent (in seperate events for each ID)
OSStatus AddToSelected() ;
OSStatus AddToDeselected ();
void SOCleanup();
public:
SelectedObject( SelObjectClass theObjClass, SOOwnerID ID);
SelectedObject( const SelectedObject &obj);
virtual ~SelectedObject ();
UInt16 Retain();
UInt16 Release();
SelObjectClass GetObjectClass( );
virtual SelObjectType GetObjectType() ; // NYI. Will always return
zero.
SOOwnerID GetOwnerID();
virtual CFStringRef CopySOString();
virtual UInt64 GetSOData64(); // these two will always return zero
for the base class
virtual UInt32 GetSOData32(); // it is up to the subclasses to return
the correct values
SelectionFlag GetSelectFlags( );
void DefineSelectFla g(SelectionFlag theFlags, Boolean newValue);
void ToggleSelectFla g(SelectionFlag theFlags);
Boolean IsSelectedOr(Se lectionFlag whichFlags); // returns true if
any of the passed flags are set
Boolean IsSelectedAnd(S electionFlag whichFlags); // returns true if
all of the passed flags are set
Boolean AnySelection(); // returns true is any flag is set
void PostSelectedEve nt(Boolean selected);
virtual Boolean operator==(Sele ctedObject &obj);
virtual void DebugPrint(UInt 32 v=0); // printf
virtual CFStringRef DebugString(UIn t32 v=0); // CFStringRef -CFShow
};
//-----------------------------------------------------------------------
--------------
class SelectedFileObj ect:public SelectedObject {
OSType sfoReady;
protected:
FSRef fsr;
virtual OSStatus CheckCache(SelO bjectClass objClass, UInt16 dataType,
void* data,
SORef *sor);
void SFOCleanup();
public:
SelectedFileObj ect(const FSRef* fsrptr, SOOwnerID ID);
SelectedFileObj ect(const char* cpath, SOOwnerID ID);
SelectedFileObj ect(CFURLRef url, SOOwnerID ID);
SelectedFileObj ect(const SelectedFileObj ect &obj);
~SelectedFileOb ject();
CFStringRef CopySOString();
UInt64 GetSOData64();
UInt32 GetSOData32();
FSRef* GetFSRefPtr();
virtual CFStringRef CopyName();
Boolean operator==(Sele ctedFileObject &obj);
void DebugPrint(UInt 32 v=0); // printf
CFStringRef DebugString(UIn t32 v=0); // CFStringRef -CFShow
};
typedef class SelectedFileObj ect* SelectedFORef;
typedef SelectedFORef SOFORef;
The plugin header uses this typedef:
// parent class
typedef void* SelectedObjectR ef;
typedef SelectedObjectR ef SORef; // shorter name
// selected file objects
typedef void* SelectedFileObj ectRef; // subclass of SORef
typedef SelectedFileObj ectRef SOFORef;
Here is the casting routine: (it is exported using extern "C")
SOFORef SOCastToSOF(SOR ef sor) {
if (sor==nil) {return nil;}
SelectedFORef sof=nil;
printf("%s\n", typeid(*sor).na me()); (1)
printf("%s\n", typeid(Selected FileObject).nam e()); (2)
if (typeid(*sor)== typeid(Selected FileObject)) { (3)
sof=(SOFORef)so r;
}
else {sof=nil;}
// sof=dynamic_cas t<SelectedFORef >(sor);
return sof;
};
The routine is used by plugins.
The plugins receive a SORef from the parent application via another
accessor routine and are
passed in an CFArray.
All the plugins ever receive are pointers.
The passed SORef is not guaranteed to be a SOFORef (much like a CFType
is not guaranteed to be a CFString). So they use this routine to convert
it if possible.
(1) & (2) typeid statements print '18SelectedFile Object' .
(3) always evaluates to false when the routine is called by the plugin.
But, if the owning app calls this casting routine directly, it succeeds.
Someone from a C++ newsgroup suggested that the vtable is getting 'lost'
or mangled when passed through the plugin.
Last bit of code. The CFArray callbacks:
const void* SORefRetain(CFA llocatorRef alloc, const void* value) {
SORef sor=(SORef)valu e;
sor->Retain();
return value;
};
void SORefRelease(CF AllocatorRef alloc, const void* value) {
SORef sor=(SORef)valu e;
sor->Release();
};