[Openmcl-devel] Defining new objective C types
Michael Minerva
minerva at agentsheets.com
Wed Mar 9 14:58:33 PST 2011
Thank you very much for your very detailed and insightful response. All of the details about foreign types was something I had always been curious about, so even though it was not the cause of my problem this time, I am very thankful to have that information. Also, your "shorter version" did in fact describe my problem (once I put the timer in the main thread everything worked fine). Thanks a lot!
--Mike
On Mar 9, 2011, at 3:14 PM, Gary Byers wrote:
> The short version is that the foreign type :id describes anything that's
> "a foreign pointer to an ObjC object". The ObjC declaration
>
> - (void)timerFireMethod:(NSTimer*)theTimer
>
> says that the parameter is a pointer to (an instance of) a specific
> type of ObjC object (an NSTimer); it would have been correct to have
> said that the parameter was of type "id", but the more specific type
> helps the ObjC compiler do some compile-time typechecking and tells
> the human reader that the parameter will be an NSTimer.
>
> Note that the syntax - NSTimer*, "pointer to something of type
> NSTimer" - is essentially the same as would be used to describe a
> pointer to an NSRect or pointer to int or other foreign type. At some
> level in ObjC, the NSTimer is defined as a structure type (in the same
> way that NSRect is a structure type), but there's a tradeoff there:
> you generally want to think of an NSTimer as being something whose
> representation is a lot more opaque than an NSRect's is. (An NSTimer
> is a few notches above an NSRect on the food chain.)
>
> The interface files define "NSRect" to be the name of a foreign type
> (with an associated struct definition) and also the name of an ObjC
> class. The former can be referred to as :<NSR>ect (which is easier
> to write and read as #>NSRect) and the latter as NS:NS-RECT. The
> pointer to the timer method's parameter is both "a pointer to something
> described by the foreign type #>NSTimer" and "an instance of the NS:NS-TIMER
> class", and at some level those are basically the same thing; the former
> is a "foreign type" in CCL and the latter is a lisp type.
>
> OBJC:DEFMETHOD wants to know the foreign types of the method's arguments.
> We generally don't want to have to say that a parameter that's an instance
> of an ObjC class is a pointer to some random foreign type (it's further
> up the food chain than that), so it's easier to just say that the foreign
> type is just :id ("some kind of ObjC object"). It's be nice if OBJC:DEFMETHOD
> accepted ObjC class names and treated them as if they named a specific subclass
> of :id; that'd help the human reader (and writer) of the method definition and
> might help the compiler in some cases. We haven't done that, and essentially
> all of the :id-typed parameters to all of the methods that we/you/others have
> written are just declared/defaulted to be of type :id. If you really wanted
> to do so, you could say that the timer method's arg was of type (:* #>NSTimer),
> but that wouldn't really affect anything and probably doesn't make anything
> any clearer.
>
> The even shorter version (which might have been better) is "this has nothing
> to do with why your timer method isn't printing anything." Some things that
> might explain this:
>
> - #/scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: is defined
> to add the timer to the "current run loop", which is another way of saying
> "to the current thread's run loop." A run loop (the short version) is
> a thread-specific object that describes a set of event sources; when a
> thread "runs its run loop", it does whatever it needs to do to sample
> those sources. The main event thread runs its run loop almost all the
> time (it's almost always waiting for those event sources or responding
> to the events - with a small #\e - that occur). Other threads generally
> don't run their run loops unless explicitly told to do so.
>
> What run loop is current when the method that establishes the timer is
> called ? E.g., what thread does that code run in ?
>
> - I don't know either way, but it's certainly possible and wouldn't be
> surprising if NSTimers in general (or this particular way of establishing
> one) just don't/doesn't work in Cocotron. (I'm fairly sure that I've
> seen NSTimer-related code in the sources and if it didn't work it'd
> be more a case of "mostly/entirely implemented but broken for some
> reason" rather than "just stubbed out and not really implemented",
> and for all I know - which isn't much - the code's all there and works
> fine.)
>
>
>
> On Wed, 9 Mar 2011, Michael Minerva wrote:
>
>> I am curious if there is a way to define a new objc type that will be
>> recognized by objc methods as a parameter, I thought I could just find
>> where?:<NSI>nteger was defined but I had no luck when I looked for that
>> definition. ?Most of the time you can just list your parameter without a
>> type but it seems that in the case of an NSTimer you may need to define the
>> type explicitly. ? Here is my little example that seems to need this
>> explicit type definition for the timer parameter:
>> (defclass COCOTRON-VIEW (ns:ns-opengl-view)
>> ??()
>> ??(:metaclass ns:+ns-object))
>> (defun COCOTRON-TEST ()
>> ??(ns:with-ns-rect (frame 0 0 200 200)
>> ?? ?(let* ((window (make-instance ns:ns-window :height 300))
>> ?? ? ? ? ?(opengl-view (#/retain (#/initWithFrame:pixelFormat: (#/alloc
>> cocotron-view) frame (#/defaultPixelFormat ns:ns-opengl-view))))
>> ?? ? ? ? ?(timer (#/retain
>> (#/scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
>> ns:ns-timer .01d0 opengl-view (objc::@selector #/timer:) nil #$YES))))
>> ;;***********This is the line of importance***************
>> ?? ? ?(#/orderFront: window nil))))
>> ?? ? ?
>> (objc:defmethod (#/timer: :void) ((self cocotron-view) timer)
>> ??(print "TIMER"))
>> It seems to me that this code should work but timer is never printed, I
>> believe the problem is because I am not explicitly defining the type of the
>> parameter. ?The documentation of the
>> method?#/scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
>> states that the selector must have the following signature:
>> - (void)timerFireMethod:(NSTimer*)theTimer
>> So I assume my problem is that I am defining the type of the timer loosely.
>> ?Anyone know how I could explicitly define the parameter in this example?
>> ?Something like this: ?
>> (objc:defmethod (#/timer: :void) ((self cocotron-view) (timer ns:ns-timer))
>> ??(print "TIMER"))
>> gives this error:
>> > Error: Unknown foreign type: NS:NS-TIMER
>> > While executing: CCL::%PARSE-FOREIGN-TYPE, in process Listener(11).
>> > Type cmd-. to abort, cmd-\ for a list of available restarts.
>> > Type :? for other options.
>> 6 >?
>> Thanks a lot,
>> --Mike
>>
>
More information about the Openmcl-devel
mailing list