How do 2 AS files interact with each other?

I have a project with 2 AS files, one is a subclass of NSObject and the other is a subclass of NSView. In the first one I have:

property mList:{}

on getLetters_(numb)
set aList to items 1 thru (numb as integer) of mList
return aList
end getLetters_

on applicationWillFinishLaunching_(aNotification)
set mList to {“A”,“B”,“C”,“D”,“E”,“F”}
end applicationWillFinishLaunching_

If I connect getLetters to a button and call it that way, I get a subset of the list as I should, but if I call it from my other applescript, I get an error like: can’t get items 1 thru 3 of {}. It seems like when you call from the other AS, the array is being reset to empty. How do I get around this? Do I need to have everything in one script?

That should work fine. What do you get if you just return mList?

Shane, I just get an empty list. I changed the program to do this:

script TilesAppDelegate
	property parent : class "NSObject"
	property mlist : {}
	property myB : missing value
	
	on getLetters_(numb)
		return mlist & (numb as integer)
	end getLetters_
	
	on push_(sender)
		set n to getLetters_(6)
		log n
	end push_
	
	
	on applicationWillFinishLaunching_(aNotification)
		set mlist to {1, 2, 3, 4, 5}
	end applicationWillFinishLaunching_

myB is a button attached to push_(sender) and in my other AS I access the get letters_ method with the following call:

on mouseDown_(theEvent)
		set ans to TilesAppDelegate's getLetters_(6)
		log ans
	end mouseDown_

If I click on myB, the log gives me (1,2,3,4,5,6), but if I click the mouse button anywhere else in the window I just get (6).

Try changing

 set mlist to {1, 2, 3, 4, 5}

to

       set my mlist to {1, 2, 3, 4, 5}

I tried that, and it made no difference.

I also changed the return statement in getLetters_ to:

“return mlist & (numb as integer) & {7,8}” just to make sure there was nothing weird going on about the return value being a list. Clicking myB gives me (1,2,3,4,5,6,7,8) and clicking elsewhere in the window gives me (6,7,8). I’m not getting any warnings or error messages in the log either.

Is TilesAppDelegate a property referring to the AS class correctly?

Shane,

I’m not clear on what is correct as far as ASOC is concerned, but I do have : property TilesAppDelegate : class “TilesAppDelegate” at the top of the TilesView script. I’ve created 3 “letter tiles”, which are NSImageView objects with images of the letters A,B and C on them. The program allows me to drag them around with the mouse. The call to getLetters_ is just testing something right now, it doesn’t actually do anything other than print the log – the whole script is:

-- TilesView.applescript
-- Tiles
-- Must set the content view of  myWindow to class TilesView
-- otherwise the mouseDown events aren't captured!!

script TilesView
	property parent : class "NSView"
	property TilesAppDelegate : class "TilesAppDelegate"
	property Tester : class "Tester" --an Objective-C class that tests the identity of what's been clicked on
	property tileA : missing value --connected to an NSImageView
	property tileB : missing value --connected to an NSImageView
	property tileC : missing value --connected to an NSImageView
	property myWindow : missing value
	property hit : 0
	property kX : 0
	property kY : 0
	property thing : 0 --the current object that has been clicked on
	
	on mouseDown_(theEvent)
		set ans to TilesAppDelegate's getLetters_(6)
		log ans
		set mouseLoc to (theEvent's locationInWindow()) as record
		set thing to hitTest_(mouseLoc)
		if Tester's classTest_(thing) is 1 then
			set hit to 1
			set cLoc to thing's convertPoint_fromView_(mouseLoc, missing value)
			set loc to {((mouseLoc's x) - (cLoc's x)), ((mouseLoc's y) - (cLoc's y))}
			thing's setFrameOrigin_(loc)
			set kX to cLoc's x --this is the x offset between where the mouse was clicked and "thing's" x origin
			set kY to cLoc's y --this is the y offset between where the mouse was clicked and "thing's" y origin
		end if
	end mouseDown_
	
	on mouseDragged_(theEvent)
		if hit = 1 then
			set mouseLoc to (theEvent's locationInWindow()) as record
			set newLoc to {x:((mouseLoc's x) - kX), y:((mouseLoc's y) - kY)}
			thing's setFrameOrigin_(newLoc)
		end if
	end mouseDragged_
	
	on mouseUp_(theEvent)
		set hit to 0
	end mouseUp_
end script

   property TilesAppDelegate : class "TilesAppDelegate"

By doing that, you’re calling the handler on the TilesAppDelegate class, not on the instance that applicationWillFinishLaunching_ gets called in. You need to make the equivalent of an IBOutlet so that you’re calling the handler in the TilesAppDelegate object you’ve instantiated.

Shane, if you know how to instantiate a class in ASOC without using an IBOutlet, please post.

I’ve been struggling with the same issue.

Shane,

Now that I think about it, your diagnosis of the problem makes sense to me. But I don’t understand the solution. Doesn’t the blue cube, TilesAppDelegate, represent the instance of the TilesAppDelegate class? I tried creating a property in the TilesView script and connecting it to that, but that didn’t work, so now I’m at a loss. I’m somewhat confused as to what an AS script is - is it a class or an object? My reading of the release notes makes me think it is a class.

It does – but you’re not addressing the blue cube, you’re addressing the class – that’s what ‘property TilesAppDelegate : class “TilesAppDelegate”’ says.

Try it again :slight_smile: Have both scripts as instances.

it’s a class, but making it a blue cube instantiates it. An app delegate (or any delegate) has to be an instance of a class, not a class itself – that’s why the template provides the app delegate pre-instantiated.

set x to current application’s theClass’s alloc()'s init()

But I’m not sure that’s the problem here…

Shane,
Something seems to have gotten really messed up with that project. I never could get it to work, and the more I messed with it the weirder the results got. So I started over with a fresh project with basically the same functionality and now after attaching a property from one script to the AppDelegate of the other it works fine. Thanks for your help. I may get my head wrapped around this yet.

FWIW, your post sounds eerily familiar :wink:

While messing around with the project last night, I thought I may have broken something in the program, so this morning I started over and wrote this program to test some things:

-- UpwordsView.applescript
-- Upwords
--The class of the content view of the window was changed to UpwordsView 
script UpwordsView
	property parent : class "NSView"
	property controller : missing value --connected to the UpwordsAppDelegate
	property myB : missing value --connected to action, endTurn_
	
	on mouseDown_(theEvent)
		set mouseLoc to (theEvent's locationInWindow()) as record
		log hitTest_(mouseLoc) --returns the object clicked on
		log pick()
		log controller's iVar
	end mouseDown_
	
	on endTurn_(sender)
		log controller's iVar
	end endTurn_
	
	on pick()
		return 47
	end pick
	
end script

In the other script, UpwordsAppDelegate, I have “property iVar:100” which I am trying to access in the above script either through a button click attached to endTurn_ or by a mouseDown_ event. The button click works fine, it accesses the iVar from the other script. But if I click the mouse anywhere else in the window I get the following log:

2010-04-14 12:05:00.603 Upwords[8957:a0f] <UpwordsView @0x200698e80: OSAID(11)>
2010-04-14 12:05:00.604 Upwords[8957:a0f] 47
2010-04-14 12:05:00.611 Upwords[8957:a0f] *** -[UpwordsView mouseDown:]: Can’t get iVar of missing value. (error -1728)

So, the mouseDown_ method correctly reports what it’s been clicked on and correctly accesses a method within the same script, but doesn’t access iVar in the other script. It looks like it thinks “controller” is still a missing value. Any Idea on what’s going on here?

When you link controller, what are you linking it to?

I linked it to the blue cube, UpwordsAppDelegate. The link seems fine since the button connected to endTurn_ is able to access the data. In the connections panel of Upwords App Delegate it shows up under Referencing Outlets as controller-------Upwords View. In the Upwords View connections panel it shows up under Outlets as
controller------Upwords App Delegate.

When you say the “Upwords View connections panel”, do you mean when you control-click on the instance that is in the window, and not one you have instantiated as a blue cube?

I’m not sure what you mean by “the instance that is in the window”. The only way I know to open a connections panel is by right clicking on the blue cube (the one called Upwords View), and that is what I did.

You changed the class of the window’s content view to UpwordsView. That makes it an instance of UpwordsView, and so you need to make any IBOutlet connections to that instance, not another one you’ve made with a blue cube. You’re getting different responses because the mouseDown is being triggered in a different instance.