// Copyright 2000 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/Frameworks/OmniFoundation/OFWeakRetainConcreteImplementation.h,v 1.2 2000/10/27 08:51:47 kc Exp $

#import <Foundation/NSObject.h>

@class NSLock;

#import "OFWeakRetainProtocol.h"

@protocol OFWeakRetainConcreteImplementationHelperCallback
- (void)invalidateWeakRetains; // Must be implemented by referenced object
- (void)releaseFromWeakRetainHelper; // Implemented by OFWeakRetainConcreteImplementation_IMPLEMENTATION macro
@end

@interface OFWeakRetainConcreteImplementationHelper : NSObject
{
    unsigned int count;
    NSLock *lock;
}

- (void)incrementWeakRetainCount;
- (void)decrementWeakRetainCount;

- (void)releaseReferencedObject:(id)referencedObject;
    // This releases the referenced object via -releaseFromWeakRetainHelper, and if the only remaining retains are due to weak retains it calls -invalidateWeakRetains

@end

#define OFWeakRetainConcreteImplementation_IVARS \
    OFWeakRetainConcreteImplementationHelper *weakRetainHelper

#define OFWeakRetainConcreteImplementation_INTERFACE \
- (void)invalidateWeakRetains;

#define OFWeakRetainConcreteImplementation_INIT \
{ \
    weakRetainHelper = [[OFWeakRetainConcreteImplementationHelper alloc] init]; \
}

#define OFWeakRetainConcreteImplementation_DEALLOC \
{ \
    [weakRetainHelper release]; \
}

#define OFWeakRetainConcreteImplementation_IMPLEMENTATION \
\
/* These methods go in the class implementation */ \
\
- (void)incrementWeakRetainCount; \
{ \
    [weakRetainHelper incrementWeakRetainCount]; \
} \
\
- (void)decrementWeakRetainCount; \
{ \
    [weakRetainHelper decrementWeakRetainCount]; \
} \
\
- (void)releaseFromWeakRetainHelper; \
{ \
    [super release]; \
} \
\
- (void)release; \
{ \
    [weakRetainHelper releaseReferencedObject:self]; \
}
