// Copyright 1997-1999 Omni Development, Inc.  All rights reserved.
//
// This software may only be used and reproduced according to the
// terms in the file OmniSourceLicense.html, which should be
// distributed with this project and can also be found at
// http://www.omnigroup.com/DeveloperResources/OmniSourceLicense.html.
//
// $Header: /Network/Source/CVS/OmniGroup/OmniBase/OBPostLoader.h,v 1.10 1999/03/30 21:25:15 kc Exp $

#import "OBObject.h"


@interface OBPostLoader : OBObject
/*.doc.
OBPostLoader provides the functionality that you might expect to get from implementing a +load method.  Unfortunately, some implementations of OpenStep have bugs with their  implementation of +load.  Rather than attempt to use +load, OBPostLoader provides similar functionality that actually works.  Early in your program startup, you should call +processClasses.  This will go through the ObjC runtime and invoke all of the +performPosing and +didLoad methods.  Each class may have multiple implementations of each of theses selectors -- all will be called.

OBPostLoader listens for bundle loaded notifications and will automatically reinvoke +processClasses to perform any newly loaded methods.

OBPostLoader also listens for NSBecomingMultiThreaded and will invoke every implementation of +becomingMultiThreaded.

On HP-UX, an additional pass is made through the classes looking for +registerFramework methods.  HP-UX doesn't support the automatic registration of framework paths.  This is intended to solve that problem.  The +registerFramework methods are processed BEFORE the +didLoad methods so that the code in the +didLoad methods may use +[NSBundle allFrameworks].
*/


+ (void)processClasses;
/*.doc.
Searches the ObjC runtime for particular methods and invokes them.  Each implementation will be invoked exactly once.  Currently, there is no guarantee on the order that these messages will occur.  This should be called as the first line of main().  Once this has been called at the beginning of main, it will automatically be called each time a bundle is loaded (view the NSBundle loading notification).

This method makes several passes, each time invoking a different selector.  On the first pass, +performPosing implementations are invoked.  Then, if on HP-UX,  +registerFramework implementations are processed.  This is used by some to work around the fact that PDO 4.0 on HP-UX doesn't correctly register frameworks with NSBundle.  Finally, +didLoad implementations are processed.  Finally, on HP-UX, a third pass is processed in which 
*/

+ (void) processSelector: (SEL) selectorToCall
              initialize: (BOOL) shouldInitialize;
/*.doc.
This method does the work of looping over the runtime searching for implementations of selectorToCall and invoking them when they haven't already been invoked.
*/

@end

@interface NSObject (OBPostLoader)

+ (void) performPosing;
/*.doc.
This method will be called on every class (or category) which implements it.
*/

+ (void) didLoad;
/*.doc.
This method will be called on every class (or category) which implements it.
*/

+ (void) becomingMultiThreaded;
/*.doc.
This is called on each class implementation with this selector name the first time the application is about to become multi-threaded.  Classes can implement this method to allocate locks that will be necessary to arbitrate access to shared data owned by the class.  This method is NOT automatically called on instances -- they will need to manually subscribe to NSWillBecomeMultiThreadedNotification.
*/

@end
