Using the ScriptData Communications Area



Created January 31, 2005 © Copyright SuzShook
Made "Version-Independent" March 2009
Property of SuzShook

This tutorial is my own creation;
however, most of the techniques used in this tutorial, I have learned from others!
Therefore, if you recognize any contribution you have made, I thank you!
And I thank you as well for respecting this as my work by not posting it,
in whole or in part,
in any other location without written permission from me!

Individuals and PSP graphics groups are invited to share my tutorials with others with TEXT LINKS ONLY.
You can e-mail me to let me know you are adding one or more of my tutorials to your list if you like -
it's always fun to know who is doing them!

This tutorial will teach you how to use the undocumented ScriptData Communications Area available in PSP beginning in PSP 9 to pass data from script to script. This tutorial is based primarily on what I have learned from Gary Barton, the ScriptData Communications Area architect. Thanks, Gary, for all you do for the PSP community!



I make my tutorials as brief as possible, without the customary paths, details, and how-to's. For those veterans among you, this will be welcome! But for those less familiar with PSP, I included a "Glossary" that contains all the details omitted in the tutorial. If you need a little extra help, check the Glossary section. Just click on the button below - the Glossary will open in a new window.

PSP glossary button


This tutorial assumes you have a working knowledge of Paint Shop Pro at the intermediate level (or advanced beginner level with the Glossary). It was originally written in and for PSP Version 9, and now made "version-independent". Screen shots for this tutorial can come from any version of PSP - where there are significant differences from version to version, a green "Version Note" will be included, along with multiple screen shots if necessary.

Where a note/tip refers to a version of PSP and all higher versions, a + sign will be used to indicate this. For example, if a note/tip applies to PSP X and higher versions, I will use the convention "PSP X+".

If you try this tutorial, and find something is inaccurate for your version of PSP, please EMAIL ME to let me know so I can fix it!

Screen shots in this tutorial are resized - your work will be larger than this!



Supplies - For this tutorial, you will need the following:

What is the ScriptData Communications Area?

The ScriptData Communications Area is a dynamic area which exists in the Python interpreter's memory, and is available for the duration of the PSP session. As such, it can be used to pass data from script to script during that PSP session. Though the ScriptData Communications Area is available throughout the PSP session, it is lost when PSP is closed, and then rebuilt anew for the next PSP session.

The information stored in the ScriptData Communications Area is stored in the form of a dictionary. This dictionary is predefined as ScriptData = {}, and resides within the JascUtils module.

Python Dictionaries Primer
It might be a good idea at this point to expose you to some concepts about dictionaries. If you know all about Python dictionaries, you can skip this primer box. For the rest of you, here's all you ever wanted to know about dictionaries and were afraid to ask!

A Python dictionary is a set of 'key:value' pairs contained in curly braces, a "mapping" whose values are stored and retrieved using keys. A Python dictionary consists of pairs separated by a colon (:) - the first part of the pair is the key, and the second part of the pair is the value associated with that key. One such pair in PSP might be 'Width':300. In this case the key is 'Width' and the associated value is 300. Another example might be 'Height':200, and a third might be 'Size':(300,200).

We could store those values in the ScriptData dictionary this way:

ScriptData['Width'] = 300
ScriptData['Height'] = 200
ScriptData['Size'] = (300,200)

The resulting ScriptData dictionary might look like this:

ScriptData = {'Width':300, 'Height':200, 'Size':(300,200)}

We could print the dictionary if we wanted to, using the print command:

print ScriptData

which would produce this in the Script Output Palette (SOP):

{'Width':300, 'Size':(300,200), 'Height':200}
Note: The items in a dictionary are "unordered" - hence they may appear in any order in a listing. The SOP results listed above might just as well be any of the following:
{'Width':300, 'Height':200, 'Size':(300,200)}
{'Size':(300,200), 'Width':300, 'Height':200}
{'Size':(300,200), 'Height':200, 'Width':300}
{'Height':200, 'Width':300, 'Size':(300,200)}
{'Height':200, 'Size':(300,200), 'Width':300}

We can also retrieve values from a Python dictionary. Python uses a system called indexing to get to individual elements in a dictionary. In a real dictionary, you would use a word to look up its meaning. In Python, you use a key (like a word) to look up or find the associated value (meaning). The format that's used to return a value from a dictionary is:

dictionaryname[key]

Returning to the sample ScriptData dictionary above, to retrieve the width, you could code:

ScriptData['Width']

This says: "Go into the ScriptData dictionary, find the key called 'Width', and return its associated value". Therefore, if you code:

print
print ScriptData['Width']

the SOP would list:

300

To print the height from this dictionary, you could code:

print
print ScriptData['Height']

and the SOP will list:

200

There's one more thing you need to know about the values stored in dictionaries - those values can be many things, including other dictionaries. If I want to isolate the values stored in a dictionary so that they are associated with some specific reference, like a script name, I could do that by placing them in a dictionary within a dictionary (sometimes called a "nested" dictionary). Let's suppose the above values are associated with a script called Framing. I could set up a new dictionary within the ScriptData dictionary with a key called Framing, like this:

ScriptData = {'Framing': {}}

My new key is "Framing", and its associated value is an empty dictionary. I could then populate that dictionary as above, with these commands:

ScriptData['Framing']['Width'] = 300
ScriptData['Framing']['Height'] = 200
ScriptData['Framing']['Size'] = (300,200)

If the information was stored as above, the ScriptData dictionary might look like this:

ScriptData = {'Framing':{'Width':300, 'Height':200, 'Size':(300,200)}}

To retrieve the width from the above dictionary, code:

ScriptData['Framing']['Width']

This says: "Go into the ScriptData dictionary, find the key called 'Framing', whose associated value is a dictionary (or a nested dictionary). Within that dictionary, find the key called 'Width', and return its associated value". Therefore, if you code:

print
print ScriptData['Framing']['Width']

the SOP would list:

300

To print the height from this dictionary, code:

print
print ScriptData['Framing']['Height']

and the SOP will list:

200
Note: Nested dictionaries are referenced by a series of indexes (keys in square brackets). Index into the outer dictionary first, then into the inner or nested dictionary.

In summary, then, here's what you need to know about dictionaries:

  • The dictionary elements are enclosed in curly braces {}.

  • Each "key-value" pair in the dictionary is separated by a colon (:).

  • The individual key-value pairs are separated from other key-value pairs by commas.

  • To access any value in a dictionary, code the dictionary name, followed by the key associated with the value you want, in square brackets. Be very careful to code the key exactly as you see it in the dictionary, including the quotes, or you'll get an error.

  • To access a value within a nested or internal dictionary, index into the outer dictionary first, and then into the inner dictionary.

That's it for dictionary basics. If this is new to you, reread the Primer. It's essential that you understand dictionaries to use the ScriptData Communications Area.


How Do I Activate the ScriptData Communications Area?

In order to make the ScriptData dictionary available for use in a script, insert the following line in your script, right after the 'from JascApp import *' line:

from JascUtils import ScriptData

Therefore, the first two lines of your scripts that utilize the ScriptData Communications Area should look like this:

from JascApp import *
from JascUtils import ScriptData
Version Note: In PSP X, JascApp was renamed to PSPApp and JascUtils was renamed to PSPUtils. Therefore, starting in PSP X, you can have either the above two lines, or your code can look like this:
from PSPApp import *
from PSPUtils import ScriptData

However, if you want your scripts to run in any version of PSP, it is essential that you use the from JascApp import * and from JascUtils import ScriptData commands here.


How Do I Add Data to the ScriptData Communications Area?

Elements are added to the ScriptData dictionary just as they are added to any dictionary. There are basically three methods to do this:

    1. Simple Method: This is the basic, no frills method of updating the ScriptData dictionary. It's not the preferred method, because there is always the danger of accidently overlaying values placed in the ScriptData dictionary by one script with values placed there by another script, but it does the job. For example, to add the Width, Height, and FontName to the ScriptData dictionary using this method, you could code the following:
    ScriptData['Width'] = 200
    ScriptData['Height'] = 300
    ScriptData['FontName'] = "Arial"

    The ScriptData dictionary would look like this, after the above additions:

    {'Width': 200, 'Height': 300, 'FontName': 'Arial'}

    2. AppendedTag Method: One way to make the keys in the ScriptData dictionary unique is to include the script name as part of the key name when storing values. For example, a script called MutedTonesFrame might store values in the ScriptData dictionary like this:

    ScriptData['MutedTonesFrame_Width'] = 200
    ScriptData['MutedTonesFrame_Height'] = 300
    ScriptData['MutedTonesFrame_FontName'] = "Arial"

    After the above additions, the ScriptData dictionary would look like this:

    {'MutedTonesFrame_Width': 200, 'MutedTonesFrame_Height': 300, 'MutedTonesFrame_FontName': 'Arial'}

    3. NestedDictionary Method: Another way to make the keys stored in the ScriptData Communications Area unique would be to have each script write data to its own dictionary within the ScriptData dictionary, using the script's name as the key pointing to this inner (nested) dictionary. Using the same example as above, the MutedTonesFrame script might store values in the ScriptData dictionary in the following manner:

    ScriptData['MutedTonesFrame'] = {}
    ScriptData['MutedTonesFrame']['Width'] = 200
    ScriptData['MutedTonesFrame']['Height'] = 300
    ScriptData['MutedTonesFrame']['FontName'] = "Arial"

    In the first line above, a new dictionary is created within the ScriptData dictionary - you can't store anything in a dictionary until it's defined or created. This dictionary is the value associated with the key 'MutedTonesFrame'. The next 3 lines write the Width, Height, and FontName to that dictionary. The ScriptData dictionary would look like this, after the above additions:

    {'MutedTonesFrame': {'Width': 200, 'Height': 300, 'FontName': 'Arial'}}

The NestedDictionary way of storing values in a dictionary might seem more complex, but it definitely has its advantages. As this tutorial progresses and I show you how to manipulate the data in the ScriptData Communications Area, I will always demonstrate using all three methods - the Simple Method, the AppendedTag Method, and the NestedDictionary Method. Thus you can choose the method that makes the most sense to you. I tend to lean heavily towards the latter two methods, as they create entries in the ScriptData Communications Area that are durable and not likely to get overwritten as other scripts are played during a PSP session.


How Do I Retrieve Data From the ScriptData Communications Area?

To retrieve values from the ScriptData dictionary, use keys, just as you would for any dictionary.

    1. Simple Method: If the ScriptData dictionary looks like this:
    {'Width': 200, 'Height': 300, 'FontName': 'Arial'}

    any of those values can be retrieved like this:

    NewWidth = ScriptData['Width']
    NewHeight = ScriptData['Height']
    FontName = ScriptData['FontName']

    2. AppendedTag Method: If the ScriptData dictionary looks like this:

    {'MutedTonesFrame_Width': 200, 'MutedTonesFrame_Height': 300, 'MutedTonesFrame_FontName': 'Arial'}

    any of those values can be retrieved like this:

    NewWidth = ScriptData['MutedTonesFrame_Width']
    NewHeight = ScriptData['MutedTonesFrame_Height']
    FontName = ScriptData['MutedTonesFrame_FontName']

    3. NestedDictionary Method: If the ScriptData dictionary looks like this:

    {'MutedTonesFrame': {'Width': 200, 'Height': 300, 'FontName': 'Arial'}}

    any of those values can be retrieved like this:

    NewWidth = ScriptData['MutedTonesFrame']['Width']
    NewHeight = ScriptData['MutedTonesFrame']['Height']
    FontName = ScriptData['MutedTonesFrame']['FontName']

Any of these methods would set the NewWidth variable to 200, the NewHeight variable to 300, and the FontName variable to "Arial". These variables could be used anywhere in the script, once they're retrieved from the ScriptData dictionary.

Note: I used NewWidth, NewHeight and FontName for my variable names. You can use any variable names you want to store the information retrieved from the ScriptData Communications Area.

Can I Remove An Entry From the ScriptData Communications Area?

Dictionary entries can be removed using the del command. To remove the Width entry from the ScriptData Communications Area, use the following:

    1. Simple Method: To remove the Width entry, printing the ScriptData dictionary both before and after the change, for comparison:
    print
    print " ScriptData dictionary before deleting Width - ", ScriptData
    print
    del ScriptData['Width']
    print " ScriptData dictionary after deleting Width - ", ScriptData
    print

    This would produce the following in the SOP:

      ScriptData dictionary before deleting Width - {'Width': 200, 'Height': 300, 'FontName': 'Arial'}

      ScriptData dictionary after deleting Width - {'Height': 300, 'FontName': 'Arial'}

    2. AppendedTag Method: To remove the MutedTonesFrame_Width entry, printing the ScriptData dictionary both before and after the change, for comparison:

    print
    print " ScriptData dictionary before deleting MutedTonesFrame_Width - ", ScriptData
    print
    del ScriptData['MutedTonesFrame_Width']
    print " ScriptData dictionary after deleting MutedTonesFrame_Width - ", ScriptData
    print

    This would produce the following in the SOP:

      ScriptData dictionary before deleting MutedTonesFrame_Width - {'MutedTonesFrame_Width': 200, 'MutedTonesFrame_Height': 300, 'MutedTonesFrame_FontName': 'Arial'}

      ScriptData dictionary after deleting MutedTonesFrame_Width - {'MutedTonesFrame_Height': 300, 'MutedTonesFrame_FontName': 'Arial'}

    3. NestedDictionary Method: To remove the Width entry from the MutedTonesFrame nested dictionary, printing the ScriptData dictionary both before and after the change, for comparison:

    print
    print " ScriptData dictionary before deleting nested Width entry - ",ScriptData
    print
    del ScriptData['MutedTonesFrame']['Width']
    print " ScriptData dictionary after deleting nested Width entry - ",ScriptData
    print

    This would produce the following in the SOP:

      ScriptData dictionary before deleting nested Width entry - {'MutedTonesFrame':{'Width': 200, 'Height': 300, 'FontName': 'Arial'}}

      ScriptData dictionary after deleting nested Width entry - {'MutedTonesFrame':{'Height': 300, 'FontName': 'Arial'}}

Can I Replace An Entry In the ScriptData Communications Area?

Once you've populated the ScriptData Communications Area, a subsequent assignment of a value to an already existing key will replace the value:

    1. Simple Method: If the ScriptData Communications Area contains the following:
    {'Width': 200, 'Height': 300, 'FontName': 'Arial'}

    to replace the FontName entry, assign a new entry like this:

    ScriptData['FontName'] = "Flubber"

    The ScriptData Communications Area will now look like this:

    {'Width': 500, 'Height': 300, 'FontName': 'Flubber'}

    2. AppendedTag Method: If the ScriptData Communications Area contains the following:

    {'MutedTonesFrame_Width': 200, 'MutedTonesFrame_Height': 300, 'MutedTonesFrame_FontName': 'Arial'}

    to replace the MutedTonesFrame_FontName entry, assign a new entry like this:

    ScriptData['MutedTonesFrame_FontName'] = "Flubber"

    The ScriptData Communications Area will now look like this:

    {'MutedTonesFrame_Width': 500, 'MutedTonesFrame_Height': 300, 'MutedTonesFrame_FontName': 'Flubber'}

    3. NestedDictionary Method: If the ScriptData Communications Area contains the following:

    {'MutedTonesFrame':{'Width': 200, 'Height': 300, 'FontName': 'Arial'}}

    to replace the FontName entry for the MutedTonesFrame script, assign a new entry like this:

    ScriptData['MutedTonesFrame']['FontName'] = "Flubber"

    The ScriptData Communications Area will now look like this:

    {'MutedTonesFrame':{'Width': 500, 'Height': 300, 'FontName': 'Flubber'}}

Can I Remove ALL Entries From the ScriptData Communications Area?

To clear all values from the ScriptData Communications Area, use the clear() method:

ScriptData.clear()

This effectively empties the dictionary, and all key-value pairs are removed.

To remove ALL entries associated with a particular script only:

    1. Simple Method: There is no way to remove entries made by a particular script when using the Simple Method, as there is no connection between the script name and the ScriptData dictionary entries. Each entry would have to be individually deleted. See "Can I Remove An Entry From the ScriptData Communications Area?" above.

    2. AppendedTag Method: Each entry has to be individually deleted. See "Can I Remove An Entry From the ScriptData Communications Area?" above.

    3. NestedDictionary Method: If the ScriptData Communications Area contains the following:

    {'MutedTonesFrame':{'Width': 200, 'Height': 300, 'FontName': 'Arial'}}

    and you wish to remove the entries from the MutedTonesFrame dictionary without removing the dictionary, code the following:

    ScriptData['MutedTonesFrame'].clear()

    The ScriptData Communications Area will now look like this:

    {'MutedTonesFrame':{}}

    If you wish to remove all entries, including the MutedTonesFrame dictionary itself, code the following:

    del ScriptData['MutedTonesFrame']

    In this case, the ScriptData Communications Area will now look like this:

    {}

Can I List What's Currently Located In the ScriptData Communications Area?

You can print out the contents of the ScriptData Communications Area at any time, just as you would any dictionary, using the print command:

print
print " The ScriptData dictionary contains the following - ", ScriptData
    1. Simple Method: For a dictionary populated with these commands:
    ScriptData['Width'] = 200
    ScriptData['Height'] = 300
    ScriptData['FontName'] = "Arial"

    the following results would be printed in the SOP:

      The ScriptData dictionary contains the following - {'Width': 200, 'FontName': 'Arial', 'Height': 300}

    2. AppendedTag Method: For a dictionary populated with these commands:

    ScriptData['MutedTonesFrame_Width'] = 200
    ScriptData['MutedTonesFrame_Height'] = 300
    ScriptData['MutedTonesFrame_FontName'] = "Arial"

    ScriptData['RippleRibbonFrame_Width'] = 400
    ScriptData['RippleRibbonFrame_Height'] = 400
    ScriptData['RippleRibbonFrame_FontName'] = "Comic Sans MS"

    ScriptData['BigBlinkie_Width'] = 350
    ScriptData['BigBlinkie_Height'] = 350
    ScriptData['BigBlinkie_FontName'] = "Flubber"

    the following results would be printed in the SOP:

      The ScriptData dictionary contains the following - {'BigBlinkie_FontName': 'Flubber', 'MutedTonesFrame_Width': 200, 'MutedTonesFrame_FontName': 'Arial', 'RippleRibbonFrame_FontName': 'Comic Sans MS', 'RippleRibbonFrame_Height': 400, 'RippleRibbonFrame_Width': 400, 'MutedTonesFrame_Height': 300, 'BigBlinkie_Height': 350, 'BigBlinkie_Width': 350}

    3. NestedDictionary Method: For a dictionary populated with these commands:

    ScriptData['MutedTonesFrame'] = {}
    ScriptData['MutedTonesFrame']['Width'] = 200
    ScriptData['MutedTonesFrame']['Height'] = 300
    ScriptData['MutedTonesFrame']['FontName'] = "Arial"

    ScriptData['RippleRibbonFrame'] = {}
    ScriptData['RippleRibbonFrame']['Width'] = 400
    ScriptData['RippleRibbonFrame']['Height'] = 400
    ScriptData['RippleRibbonFrame']['FontName'] = "Comic Sans MS"

    ScriptData['BigBlinkie'] = {}
    ScriptData['BigBlinkie']['Width'] = 350
    ScriptData['BigBlinkie']['Height'] = 350
    ScriptData['BigBlinkie']['FontName'] = "Flubber"

    the following results would be printed in the SOP:

      The ScriptData dictionary contains the following - {'MutedTonesFrame': {'Width': 200, 'FontName': 'Arial', 'Height': 300}, 'BigBlinkie': {'Width': 350, 'FontName': 'Flubber', 'Height': 350}, 'RippleRibbonFrame': {'Width': 400, 'FontName': 'Comic Sans MS', 'Height': 400}}
Note: Remember, the dictionary is an unordered set of key:value pairs - the listing can produce those pairs in any order.

Can I List Just the Dictionary Keys?

To print all the keys in the ScriptData dictionary, use the keys() method:

print "ScriptData keys: ",ScriptData.keys()

The keys will be returned in a list, in random order:

    1. Simple Method: If the ScriptData Communications Area contains the following:
    {'Width': 200, 'Height': 300, 'FontName': 'Arial'}

    the above print command will produce this, or a similar, listing:

    ScriptData keys: ['Width', 'Height', 'FontName']

    2. AppendedTag Method: If the ScriptData Communications Area contains the following:

    {'FrameX_Width': 200, 'FrameX_Height': 300, 'FrameX_FontName': 'Arial'}

    the above print command will produce this, or a similar, listing:

    ScriptData keys: ['FrameX_Width', 'FrameX_Height', 'FrameX_FontName']

    3. NestedDictionary Method: If the ScriptData Communications Area contains the following:

    {'SigTag3': {'FontName': 'Flubber', 'PointSize': 36, 'TextToAdd': 'Hello!'}}

    the above print command will produce this listing:

    ScriptData keys: ['SigTag3']

    To list the keys from the inner dictionary only, code the following:

    print "ScriptData['SigTag3'] keys: ",ScriptData['SigTag3'].keys()

    which will produce a list something like this:

    ScriptData['SigTag3'] keys: ['FontName', 'PointSize', 'TextToAdd']

Can I List Just the Dictionary Values?

To print all the values in the ScriptData dictionary, use the values() method:

print "ScriptData values: ",ScriptData.values()

The values will be returned in a list, in random order:

    1. Simple Method: If the ScriptData Communications Area contains the following:
    {'Width': 200, 'Height': 300, 'FontName': 'Arial'}

    the above print command will produce this, or a similar, listing:

    ScriptData values: [200, 300, 'Arial']

    2. AppendedTag Method: If the ScriptData Communications Area contains the following:

    {'FrameX_Width': 200, 'FrameX_Height': 300, 'FrameX_FontName': 'Arial'}

    the above print command will produce this, or a similar, listing:

    ScriptData values: [200, 300, 'Arial']

    3. NestedDictionary Method: If the ScriptData Communications Area contains the following:

    {'SigTag3':{'FontName': 'Flubber', 'PointSize':36, 'TextToAdd':'Hello!'}}

    the above print command will produce this listing:

    ScriptData values: [{'FontName': 'Flubber', 'PointSize': 36, 'TextToAdd': 'Hello!'}]

    To list the values from the inner dictionary only, code the following:

    print "ScriptData['SigTag3'] values: ",ScriptData['SigTag3'].values()

    which will produce the a list something like this:

    ScriptData['SigTag3'] values: ['Flubber', 36, 'Hello!']

Can I Check the ScriptData Communications Area For A Certain Key?

To check to see if the ScriptData dictionary has a certain key, use the has_key() method:

if ScriptData.has_key('FrameX_FontName'):
        print "ScriptData has key 'FrameX_FontName'"
else:
        print "ScriptData does not have key 'FrameX_FontName'"
    1. Simple Method: If the ScriptData Communications Area contains the following:
    {'Width': 200, 'Height': 300, 'FontName': 'Arial'}

    the above command will produce the following:

    ScriptData does not have key 'FrameX_FontName'

    2. AppendedTag Method: If the ScriptData Communications Area contains the following:

    {'FrameX_Width': 200, 'FrameX_Height': 300, 'FrameX_FontName': 'Arial'}

    the above command will produce the following:

    ScriptData has key 'FrameX_FontName'

    3. NestedDictionary Method: If the ScriptData Communications Area contains the following:

    {'SigTag3':{'FontName': 'Flubber', 'PointSize':36, 'TextToAdd':'Hello!'}}

    the above command will produce the following:

    ScriptData does not have key 'FrameX_FontName'

    To check for a key within the inner dictionary, code the following:

    if ScriptData['SigTag3'].has_key('FontName'):
            print "ScriptData['SigTag3'] has key 'FontName'"
    else:
            print "ScriptData['SigTag3'] does not have key 'FontName'"

    which will print:

    ScriptData['SigTag3'] has key 'FontName'

An alternate way to check to see if the ScriptData dictionary has a certain key is to use the in operator with the keys() method:

if 'FrameX_FontName' in ScriptData.keys():
        print "'FrameX_FontName' key found in ScriptData"
else:
        print ""
        print "'FrameX_FontName' key not found in ScriptData"
    1. Simple Method: If the ScriptData Communications Area contains the following:
    {'Width': 200, 'Height': 300, 'FontName': 'Arial'}

    the above command will produce the following:

    'FrameX_FontName' key not found in ScriptData

    2. AppendedTag Method: If the ScriptData Communications Area contains the following:

    {'FrameX_Width': 200, 'FrameX_Height': 300, 'FrameX_FontName': 'Arial'}

    the above command will produce the following:

    'FrameX_FontName' key found in ScriptData

    3. NestedDictionary Method: If the ScriptData Communications Area contains the following:

    {'SigTag3':{'FontName': 'Flubber', 'PointSize':36, 'TextToAdd':'Hello!'}}

    the above command will produce the following:

    'FrameX_FontName' key not found in ScriptData

    However, if the original command is changed to this:

    if 'FontName' in ScriptData['SigTag3'].keys():
            print "'FontName' key found in ScriptData['SigTag3']"
    else:
            print ""
            print "'FontName' key not found in ScriptData['SigTag3']"

    the following will be printed:

    'FontName' key found in ScriptData['SigTag3']

If I Undo A Script That Wrote To the ScriptData Communications Area, Is the Data Removed From The ScriptData Dictionary?

The information stored in the ScriptData dictionary is not "undoable". Therefore, if you make a change to ScriptData during the execution of a script, and then undo the script, the ScriptData change is NOT undone.


ScriptData Practice Scripts

To assist you in learning how to use the ScriptData Communication Area, I have included several scripts in the ZIP for this tutorial - there are three for each of the three methods described in this tutorial.

Note: Though I've included scripts for all three methods, I do not recommend using the Simple Method. It's too easy to overlay values when using a method that does not distinguish which script stored the data.
  1. The first script contains code much like that included in the examples in this tutorial. This script passes the width and height for an image, and the font, point size, and text characters to be written, and then internally calls a second script to create an image and write some text. Finally, after the called script completes, the calling script checks to see if the called script has sent a message, and prints it if found.
    • The Simple Method version is called ss-S1ScriptDataSend.PspScript.
    • The AppendedTag Method version is called ss-AT1ScriptDataSend.PspScript.
    • The NestedDictionary Method version is called ss-ND1ScriptDataSend.PspScript.
    Version Note: Due to the text "quirks" introduced in PSP X and inherited in part by PSP XI, you might want to change the text size in these scripts so the text is rendered "coherently" in your version of PSP. I used a text size of 48 in the sample scripts.

  2. The second script retrieves the data stored by the first script, creates a new image, fills it with the Foreground Material, writes some text using the font, point size and text characters received, and then centers that text on the image. The text is written using the Background Material as fill, with no stroke. Finally, the called script returns a message to the calling script.
    • The Simple Method version is called ss-S2ScriptDataRetrieve.PspScript.
    • The AppendedTag Method version is called ss-AT2ScriptDataRetrieve.PspScript.
    • The NestedDictionary Method version is called ss-ND2ScriptDataRetrieve.PspScript.

  3. The third script contains examples of many other commands that can be used with the ScriptData Communications Area.
    • The Simple Method version is called ss-S3ScriptDataMiscCommands.PspScript.
    • The AppendedTag Method version is called ss-AT3ScriptDataMiscCommands.PspScript.
    • The NestedDictionary Method version is called ss-ND3ScriptDataMiscCommands.PspScript.

These scripts should be installed in your PSP Scripts-Restricted folder. You can use these scripts as models when you build your own scripts using the ScriptData Communications Area. I encourage you to practice and experiment - just make copies of these scripts, varying the parameters sent by the calling script, and watch how that information is used by the called script.

Note: You're probably wondering at this point which method you should adopt when using the ScriptData Communications Area to pass data between scripts. I would not recommend using the Simple Method because it does not distinguish "who" stored the data in the ScriptData Communications Area, which can become a critical issue. However, there are instances where just such a simple approach may be acceptable for you.

If we eliminate the Simple Method as a viable choice, you are then left with the AppendedTag Method and the NestedDictionary Method. There are advantages and disadvantages to both methods. With the AppendedTag Method, the indexing is easier, but the names are rather bulky and long. With the NestedDictionary Method, you always have to pre-allocate the nested dictionary you are going to use, and the indexing is more complex because of the two level indexes, but it's easier to remove all the values when you no longer need them, merely deleting the nested dictionary itself. So you'll have to make this decision yourself. Adopt one method, and stick with it - consistency is a wonderful thing.

The sample scripts distributed with this tutorial show you one way to use the Script Data Communications Area - one script stores data, then internally calls a second script which uses that stored data and passes additional data back to the original script. Another way to use the Script Data Communications Area would be to execute scripts consecutively (and independently). The first script in this scenario might store data and then terminate. Later, another script could be started which checks to see if certain data has been stored in the Script Data Communications Area, use it if it is found, or use default data values if the sought-for data is not found in the Script Data Communications Area.

Note: There is no requirement for the receiving script to be called internally by the script storing the data, as in the example scripts provided. The script which retrieves the data can be executed several hours after the script which stored the data completes. However, it must run within the same PSP session or the stored data is lost.

Does the ScriptData Communications Area Replace the "Pause Script" Structure?

Though the emergence of the ScriptData Communications Area provides a tool for data exchange which is broader in scope than the "Pause Script" format, I personally find Gary Barton's "Pause Script" format a tidy way to present a script unchallenged by the ScriptData Communications Area facility. I like to use the "Pause Script" format to provide necessary instructions and documentation to users who are running my scripts. ReadMe files and Quick Guides will get lost - I find no more convenient vehicle for presenting script information than the "Pause Script" structure, so I don't think it will go away.



I hope this tutorial helps you to get the most out of the ScriptData Communications Area, and further simplifies your work in PSP.


If you have any problems, comments, or questions, please do not hesitate to Email me.


Email


Version Independent Tutorials ~ About Me ~ Home ~ Email

All graphics and content 2002-present by SuzShook