The problem of the code I listed above, is that when “loading” a script, what it does is actually creating an instance of the script. So if I have properties inside the script, loading a script multiple times will create multiple instances of properties.
What I’d like to have, is a central place to store both common properties and routines, and only one copy of each of them. For the handlers it’s probably already true (that only one copy is instantiated even when multiple instances of script objects are instantiated), but how do I share properties among several scripts?
You can load the script 1 time at startup (static or dinamically), and use a single script (the main script, for example) to collect and modify data. Or, better, use a external text file (a temp file or the preferences file). (but I’m pretty sure you already know this)
What strikes me as obvious is the need to address an already imlicitly loaded script. My understanding is all scripts in an ASS app that are connected to some widget are automatically loaded. But there seems to be no way to address them. Say I have a script main.applescript connected to my main NIB file, and I know for sure it’s loaded. But I can’t do this in another script:
Ok let’s consider this scenario. I have two scripts A and B, which correspond to, say, two windows in my app. And I have a third script, called Common.
I can load Common in “awake from nib” handler of A, and set various properties in Common from A. Now when B needs to access the properties stored in Common, the only way I know is to load in script Common. But this created another instance of Common, with its properties being in the unmodified state!
A kludgy way to work around this is to move the code initializing properties in Common to Common itself, say, a handler initProperties(). Then we call initProperties() from both A and B. This essentially creates TWO copies of Common, with identical properties in each of them.
FaceSpan allowed shared properties in different scpt resources (I don’t really know how does it work the current beta for os x, but I think that sharing works equal than in OS 9 version). Nearly all ASStudio apps I developed use a single script, or a main script, which controls the interface (gets and formats the user input) and auxiliar scripts to do the real job (passing them the propper data).
Actually, I think the best way could be using external text files. As you describe, sharing data is very problematic. You can initialize several instance of the same script from several places, but they won’t share the same data. A shares with B, but B won’t share A’s bussinesses with C.
I ran into the same problem with properties not being persistent in multiple instances of a loaded script. The workaround I devised was (as suggested above) to create a handler for loading and saving the properties to an external .plist file via the users defaults commands. Every time I ran a handler from my secondary loaded script, I had it updates it’s properties from the external file and when the handler was finished, if the properties had been modified, I wrote them back out to the external file. This enabled my app to function but the performance hit was pretty significant. Ultimately I decided that the performance hit was too much and that the benefits of having my script separated in two was not worth the slowdown. This seems especially true since you can have Xcode/Project Builder automatically jump to a specific handler using the function drop down menu, use the find feature, and have multiple views of the script in different editor panes. (Incidentally, it took me a while to figure out in Xcode that it is possible to split the editor window more than once just like in Project Builder.)
And a guy over there suggested that I can “attach handlers” to a widget, and the persistence of the widget will help achieve what I want (sharing handlers/properties). But I don’t know how to do this, in code. Maybe someone here can help me out a bit? Thanks.
He, he…
The folk is Emmanuel, the clever developer of Smile, and most probably he is talking about Smile’s dialogs.
I don’t know “them” (Smile’s dialogs) so good, but I think he means that you can attach scripts to objects (buttons, etc.), as the methods used in FaceSpan, so you can call those scripts (handlers) from any place. As he says:
tell button "Utils" of dialog "EMail" to SendMail()
Smile is a very unique context for scripting, since it is “factored” (as we call it in our faq), which means that it uses AppleScript internally, and you can attach objects to its global context. For example, you can use its own internal methods from any script:
sort({4, 2, 7, 34, 98})
Where “sort” is a handler in the “Context” scripts within its “Class Scripts” folder.
Most probably you can also attach variables to Smile’s global context, and access them from all scripts (but I don’t know how). More info, Emmanuel or Smile’s documentation…