[texworks] Scripts: Globals

Stefan Löffler st.loeffler at gmail.com
Tue Nov 2 07:56:13 CET 2010


Am 2010-11-02 01:24, schrieb Paul A Norman:
>>> What is the difference between
>>>     TW.app.setGlobal(QString,QVariant);
>>> and
>>>     TW.script.setGlobal(QString,QVariant);
>> Practically, there is not very much difference at the moment -
>> conceptionaly, there is, though.
>> With TW.script...., things are stored with the script. I.e., the data
>> only exist as long as the script does. If the script is reloaded (e.g.,
>> because it was moved, or the file changes, ...), the data is thrown
>> away. Note that "reload script list" _should_ be intelligent enough to
>> reload scripts only when necessary.
> What are the advantages of storing data globally in TW.script.xxxGlobal
> If a script's own global will do the trick anyway(?) - is this
> conceived for some future thing when it will be possible to run
> scripts con-currently and use this mechanism to pass objects between
> them while active?

Note: Storing data globally is done with TW.app, not TW.script.
IIRC, historically TW.app globals were added first. Only later, the
TW.script object was actually exposed to scripting and globals could be
assigned to that.
The general idea indeed is that TW.app globals are really global
(accessible everywhere), whereas TW.script globals are "local" to the
script in question, but allow to pass data between different invocations
of the same script.

One thing I should emphasize (and forgot to before), though, is that
scripts in Tw live longer than you might think. Under normal
circumstances, they are loaded when Tw starts, and are unloaded when it
ends (provided you don't change and refresh them in between). This is
entirely different from their execution (which only lasts a relatively
short time, e.g. when the user clicks the menu item).

>> Tw.app.... on the other hand stores data in the application data itself.
>> As such, all scripts can access the data. Therefore, extra care is
>> necessary to use unique names (e.g., prefix them with the name of your
>> script or something). ATM, these TW.app globals are not stored on the
>> disk, so the data is not persistent (maybe this will change sometime in
>> the future?).
>> As such, it is usually better to store data in TW.script unless you need
>> to access it from another script.
> Same question as above - why do it if the running Script has access to
> its own variables any way?

I'm not sure I'm getting this question...
As I tried to say above: using "local" TW.script globals, you can pass
data between different invocations of the script.
(Stupid) example:

    TW.script.setGlobal("i", 0)


TW.script.setGlobal("i", TW.script.getGlobal("i") + 1)

which implements a kind of counter.

>>> And is a QTScript object able to be passed as a QVariant?
>> I just tested your code fragment below and yes, it seems so.
> Ok, I asked because it was not working for me with more complex
> objects including functions, I'll revisit it and check my work again
> carefully.

Hm, functions may be a different matter as they don't convert to a
simple Qt type (see
http://doc.trolltech.com/4.5/qscriptvalue.html#toVariant). As such, I
wouldn't expect functions to work, unfortunately. Note, though, that
there is no safe way to use such a global in other scripts (maybe even
written in another scripting language), so it's kind of beside the
point, at least for TW.app globals. Globals are primarily intended to
store/transfer data (as in integers, strings, arrays, ...), not to
transfer code.
I'm not 100% sure, though, since there might be some specialties
involved in how JavaScript handles methods (something to do with the
prototype, I think, but I'm no expert here).

Note that you could store the string that goes into eval() in a global,
though. I'm not sure if that's what you want (speedwise, for instance).

> Is there any memory limitation to TW.app.xxxGlobal object sizes?

Not coded by us, no. Maybe there is some internal limit in Qt, though I
doubt it.

> Is my use of a $ in the global name a problem for TW.app.xxxGlobal("$dahdah") ?

No, that shouldn't be a problem. That key is just stored as a string,
nothing else is done with it.

> My hope is to use the hook NewFile which is called when Tw opens ( -
> and by default makes a new file), to test for gloabls and if not
> present TW.app.hasGlobal($dahdah)  then pre-load common objects with
> functions and data  which I want following scripts to use, and so
> TW.app.setGlobal("$dahdah")  , so that following scripts need only
> TW.app.getGlobal("$dahdah") and not have to load and create them again
> and again again when instantiated themselves (big time saving
> overall).

Interesting. An ApplicationStartup hook would definitely be more suited
for that ;). (Note that in that case, you wouldn't really need to run
your checks (though checks are always a good idea ;)) as there aren't
any globals present at startup)
Regarding the function problem, see above. You may need to do

> >From your knowledge of the overall framework, could a whole complex
> (memory-wise -> large) dialog be safely/**reliably** stored in this
> way?

Um, that's a tough one. The size in memory shouldn't be a problem. What
I'm a little more concerned about is the complexity. A dialog usually
isn't just one object, it contains separate widgets, etc. Overall, I'd
expect it to work, though. Note that if you want to reuse the dialog,
you may need to reinitialize some data (e.g., clear all fields the user
should edit) during each run of the dialog. Note also that you should
pass NULL (or any equivalent) to the parent parameter of createUI...()
to avoid the destruction of the dialog when its parent is closed.
It's been a while since I've actively worked on the code, though, so
there may be some unpleasant surprises that slipped my memory - like
some garbage collection routines somewhere...


More information about the texworks mailing list