home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-10-16 | 11.2 KB | 281 lines | [TEXT/MPS ] |
- // UAppleObject.h
- // by Eric Berdahl
- // AppleLink: BERDAHL
- // Interget: eric_berdahl@taligent.com
- // May XX, 1992
- //
- // Copyright © 1992 Eric M. Berdahl
- // All rights reserved.
- //
- // LICENSE
- //
- // UAppleObject is provided under the ego-ware™ system. If you send me a note
- // telling me how cool you think it UAppleObject is, you may incorporate it into
- // any product you like (six-packs of good beer are also acceptable, no C.O.D.
- // shipments, please). Also, you must keep all copyright and other notices in
- // the source code, especially MY NAME (The system is called ego-ware™. Get it?).
- //
- // THEORY OF OPERATION
- //
- // This unit includes and uses two classes for the processing of AppleEvents,
- // especially AppleEvents whose targets are objects in the application domain
- // (ie: object specifiers). By properly utilizing TAppleObjectDispatcher and
- // MAppleObject, you should be able to, very easily, add full AppleEvent support
- // to any well designed object-oriented application.
- //
- // MAppleObject represents an encapsulation of the standard AppleEvent object
- // model. The various pure virtual methods are the hooks for the AppleEvent
- // world to be translated into application domain instances. Thus, the functionality
- // of MAppleObject is based on managing the translation between Object Model
- // categories and application domain instances.
- //
- // TAppleObjectDispatcher has a very different, yet equally important, function.
- // Whereas, MAppleObject defines the protocol for inter-object communication at a
- // very high level, TAppleObjectDispatcher encapsulates the mechanics of translating
- // the AppleEvent protocol into C++ objects and methods. It provides a generic
- // interface for handling AppleEvents and translating AppleEvent object specifiers
- // into application domain object instances. TAppleObjectDispatcher is implemented
- // by wrapping the Object Support Library for the object model-instance translation.
- //
- // Subclasses of TAppleObjectDispatcher may be created to add advanced OSL topics
- // to the melange of object distribution. Things I’d like to include in future
- // versions of this product, if any, include support for marking and lists.
- // Admitedly, what appears here is not the be all end all of object processing;
- // it’s simply a second approximation proof of concept that this is possible,
- // with the potential of being exceptionally easy to use and program.
-
- #ifndef _UAPPLEOBJECT_
- #define _UAPPLEOBJECT_
-
- #ifndef __APPLEEVENTS__
- #include <AppleEvents.h>
- #endif
-
- enum
- {
- errAppleObjectDispatcherAlreadyInstalled = 1000,
- errAlreadyHaveAnApplication = 1001,
- errCantCopyTheApplication = 1002
- };
-
-
- class TAppleObjectDispatcher;
- class MAppleObject;
-
- class TAppleObjectDispatcher
- {
- public:
- TAppleObjectDispatcher();
- virtual ~TAppleObjectDispatcher();
-
- virtual void Install();
-
- virtual MAppleObject* ExtractObject(const AEDesc& descriptor);
- virtual void StuffDescriptor(AEDesc& descriptor, MAppleObject* object);
-
- virtual void HandleAppleEvent(const AppleEvent& message,
- AppleEvent& reply,
- long refCon);
-
- virtual void AccessContainedObjects(DescType desiredClass,
- const AEDesc& container,
- DescType containerClass,
- DescType form,
- const AEDesc& selectionData,
- AEDesc& value,
- long refCon);
-
- virtual long CountObjects(const AEDesc& containerToken,
- DescType countObjectsOfType);
-
- virtual Boolean CompareObjects(DescType operation,
- const AEDesc& obj1,
- const AEDesc& obj2);
-
- virtual void DisposeToken(AEDesc& unneededToken);
-
- virtual MAppleObject* GetTarget(const AppleEvent& message);
-
- virtual void SetTokenObjectDisposal(MAppleObject* tokenObject,
- Boolean needsDisposal);
- // In addition to the needsDisposal argument returned from
- // GetContainedObject, an application may control the management of an
- // object by calling the SetTokenObjectDisposal routine. If true is
- // passed for needsDisposal, the tokenObject will be marked as needing
- // disposal if it is not previously marked as such. If false is passed
- // for needsDisposal, the tokenObject will be marked as not needing
- // disposal if it has previously been marked as such.
-
- virtual Boolean GetTokenObjectDisposal(const MAppleObject* tokenObject);
- // If you wish to inquire about the disposal status of any particular
- // object, this routine will return true if it is set to be deleted
- // when its token is disposed.
-
- virtual MAppleObject* ResolveSpecifier(AEDesc& objectSpecifier);
- // In the course of processing an AppleEvent, you may run across an object
- // of typeObjectSpecifier. If so, you may resolve that into a specific
- // object by calling ResolveSpecifier. This routine will never return
- // nil. If no such object exists or some other exception occurs, a
- // failure will be thrown. In the time of targeting AppleEvents, if
- // the direct parameter is an object specifier, this function will
- // be called by the framework.
-
- virtual void InstallAppleEventHandler(AEEventClass theClass, AEEventID theID,
- long refCon);
-
- static TAppleObjectDispatcher* GetDispatcher();
-
- private:
- static pascal OSErr AppleEventHandler(const AppleEvent* message,
- AppleEvent* reply,
- long refCon);
-
- static pascal OSErr OSLObjectAccessorHandler(DescType desiredClass,
- const AEDesc* container,
- DescType containerClass,
- DescType form,
- const AEDesc* selectionData,
- AEDesc* value,
- long refCon);
-
- static pascal OSErr OSLCountObjectsHandler(DescType countObjectsOfType,
- DescType containerClass,
- const AEDesc* containerToken,
- long* result);
-
- static pascal OSErr OSLCompareObjectsHandler(DescType operation,
- const AEDesc *obj1,
- const AEDesc *obj2,
- Boolean *result);
-
- static pascal OSErr OSLDisposeTokenHandler(AEDesc* unneededToken);
-
- static TAppleObjectDispatcher* fgDispatcher;
- static Boolean fgInited;
-
- MAppleObject*** fDisposalList;
- long fDisposalListSize;
- // List of objects to be disposed when we are finished with them.
-
- MAppleObject* fApplication;
- };
-
-
- class MAppleObject
- {
- public:
- MAppleObject();
- // default constructor
-
- MAppleObject(const MAppleObject& copy);
- // copy constructor
-
- virtual ~MAppleObject();
- // destructor, duh
-
- MAppleObject& operator=(const MAppleObject& assignTo);
- // Assignment operator
-
- virtual void DoAppleEvent(const AppleEvent& message,
- AppleEvent& reply,
- long refCon);
- // Once an AppleEvent has been resolved to the point of finding a
- // specific object which is its target, it will be sent the
- // DoAppleEvent message. The AppleEvent message and reply are in
- // their respective arguments, as is the refCon. Upon return from
- // this method, the AppleEvent handler will exit (this method is
- // called from within the handler itself) normally. If an error
- // occurs, throw a failure. The failure error will be caught and
- // returned as appropriate.
-
- virtual DescType GetAppleClass() const = 0;
- // Each instance must be able to inform the framework what type of
- // AppleEvent object it is. GetAppleClass must return the appropriate
- // DescType for the object.
-
- virtual long CountContainedObjects(DescType ofType);
- // Each AppleObject must be able to return a count of the number of
- // AppleEvent objects contained within it. The desiredType parameter
- // informs the object what types of objects it should count. All values
- // returned from this method will be considered valid from the framework.
- // Throw a failure if an exception occurs.
-
- virtual Boolean CompareAppleObjects(DescType operation,
- const MAppleObject& toWhat);
- // Given an object and a comparison operation to perform, this
- // method must be overridden to return a Boolean value indicating
- // whether the comparison is a true comparison or a false comparison
- // (e.g. 1 > 2 is a false comparison). The semantics for this
- // comparison are <this> <operation> <toWhat>. This ordering will
- // be important for comparisons that are not commutative (e.g. less
- // than, greater than, equal to. To cut down on the amount of code you
- // wish to write, you may wish to use a subclass of MAppleObject of your
- // own, say MMyAppleObject, where you override CompareAppleObjects to
- // catch the less than, greater than, equal to, before, after and other
- // generic ordering operations. MMyAppleObject would then define another
- // pure virtual function that returned an enum indicated wheter the
- // two objects ordering positions (ala the C library routine strcmp).
- // Such a function is left as an exercise for the reader.
-
- virtual MAppleObject* GetContainedObject(DescType desiredType,
- DescType keyForm,
- const AEDesc& keyData,
- Boolean& needDisposal);
- // An AppleObject must be able to return objects contained within it.
- // The desiredType, keyForm, and keyData arguments indicate to the
- // method which kind of object is desired. The requested object is
- // returned as the function result.
- //
- // If the resulting object was created by the method (ie: it was
- // “lazy evaluated” into existance), return true for needDisposal.
- // The assumption here is that the object should be deleted when it
- // is no longer needed for resolution of an object specifier. If the
- // resulting object was previously in existance (e.g. it is an object of
- // your application engine, or is one of your base abstractions), return
- // false for needDisposal. In that case, the object will not be deleted
- // by the UAppleObject framework and you will need to manage the storage
- // yourself.
- //
- // Returning nil from this method will cause the framework to throw
- // the errAENoSuchObject (???) error. If another error is appropriate
- // or more descriptive, throw the appropriate failure before returning.
-
- static void GotRequiredParameters(const AppleEvent& theAppleEvent);
- // This routine is here for convenience. To do AppleEvent processing
- // “right”, you really want to check that you have everything the
- // sender sent you. Almost every good AppleEvent sample will have this
- // routine and will call it from within the handlers. Since all handling
- // is done from within an MAppleObject (?), it makes sense for this to
- // be a member function of MAppleObject. However, the member function
- // really doesn’t need access to the object itself, so it is static
- // (ie: it can be called from anywhere).
-
- static void InitAppleObject(TAppleObjectDispatcher* dispatcher = nil);
- // This function should be called exactly once. It should be called
- // after initializing the toolbox and before entering your application’s
- // main event loop. InitAppleObject initializes the toolbox AppleEvent
- // manager to recognize the unit procedures.
-
- static void SetDefaultAppleObject(MAppleObject* defaultObject);
- static MAppleObject* GetDefaultAppleObject();
- private:
- static MAppleObject* fgDefaultAppleObject;
-
- static Boolean fgInited;
- // Used to ensure that the unit is only debugged once.
- };
-
-
- inline TAppleObjectDispatcher* TAppleObjectDispatcher::GetDispatcher()
- {
- return fgDispatcher;
- }
-
-
- inline MAppleObject* MAppleObject::GetDefaultAppleObject()
- {
- return fgDefaultAppleObject;
- }
-
-
- #endif