discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Wrapping C functions


From: David Chisnall
Subject: Re: Wrapping C functions
Date: Fri, 7 Aug 2009 00:44:37 +0100

A simple way of solving this is to have the designated initialiser in the classes for the video and audio subsystem call [Oh sharedInstance]. You may need these classes to have access to the Oh singleton anyway, in which case you should assign the result to a file static in the +initialize methods for each of these classes.

Note that this solution doesn't scale particularly well; you need to make sure either the Oh class or one of the video or audio subsystem classes are created before you call any SDL functions.

One more thing - if you are writing a library, it is customary to add a prefix to each of your classes and functions (e.g. NS for OpenStep classes, GS for GNUstep, ET for Étoilé classes) to reduce the likelihood of collisions (Objective-C has no namespaces).

David

On 7 Aug 2009, at 00:34, Martin Kalbfuß wrote:

I have to correct myself. I need to use load to call SDL_init because it has to be called before any subsystem is initialized. If I add SDL_init into the initialize function someone could create an instance of the video subsystem
ore something similar before he creates an instance of the Oh class. I
thought about adding factory functions to the Oh class initializing the subsystems and returning an instance of these systems. But then the user could still create an instance directly from the subsystem class which would
be unusable. Maybe I miss the point. I'm still a Objective-C noob.


David Chisnall wrote:

On 6 Aug 2009, at 22:13, Martin Kalbfuß wrote:


OK. I understand that a global and load isn't needed when using a
singleton.
The atexit cleanup is mainly for calling SDL_Quit;
I followed an example of apple for a singleton. Now my
implementation looks
like:

static Oh *sharedOhMangager = nil;

@implementation Oh

        +(  Oh * )sharedMangager
        {
                @synchronized(self)
                {
                        if ( sharedOhInstance == nil )
                        {
                                [ [ self alloc ] init ];
                        }
                }

                return sharedOhManager;
        }

This is ugly.  @synchronized is very slow and not required if you use
+initialize to create the singleton.

        + ( id )allocWithZone:( NSZone * )zone
        {
                @synchronized( self )
                {
                if ( sharedOhManager == nil )
                        {
                                SDL_Init();

                                sharedOhManager = [ super allocWithZone: zone ];

                                return sharedOhManager;
                }
                }

                return nil;
        }

Put the SDL_Init() code in +initialize.  If you create the singleton
in +initialize then you don't need the synchronization code here
either.  Anything in +initialize is guaranteed to only be called by
one thread; the runtime handles synchronization.  Replace these two
with:

+ (Oh*)sharedMangager
{
        return sharedOhManager;
}

+ (id)allocWithZone:( NSZone * )zone
{
        if (nil ==  sharedOhManager)
        {
                return [super allocWithZone: zone];
        }
        return nil;
}

+ (void)initialize
{
        if ([Oh class] != self) { return; }
        SDL_Init();
        sharedOhManager = [self new];
}

This is less code, simpler, and will be faster. The implementation of
@synchronized() in GNUstep is horrible (there's a slightly better one
in Étoilé's ObjectiveC2 framework) and means that every time you use
an @synchronized() directive in code that is reached, it makes all
other @synchronized() directive's slightly cheaper.

        - ( id )copyWithZone:( NSZone * )zone
        {
                return self;
        }

        - ( unsigned ) retainCount
        {
                return UINT_MAX;
        }

        - ( void )release
        {
        }

        - ( id )autorelease
        {
                return self;
        }

This all looks sensible.


@end

But what I don't understand is where the objects memory is going to be
freed. They don't tell. They only say it's for memory-managed code.
Release
and autorelease are overwritten. Should I or the user call dealloc
somwhere?

Singletons aren't freed, they persist for the lifespan of the program.

The documentation for SDL_Quit() implies that it actually needs to be
called, which is a bit strange; the OS should be able to reclaim any
resources when the program exits.  The best way of doing this is by
registering for aNSApplicationWillTerminateNotification notification
from NSApp.  If NSApp doesn't exist, then you need to make sure that
your application calls a method in the object that calls SDL_quit().

David

_______________________________________________
Discuss-gnustep mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/discuss-gnustep



--
View this message in context: 
http://www.nabble.com/Wrapping-C-functions-tp24850281p24856439.html
Sent from the GNUstep - General mailing list archive at Nabble.com.



_______________________________________________
Discuss-gnustep mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/discuss-gnustep





reply via email to

[Prev in Thread] Current Thread [Next in Thread]