Persistent (config stored) data

From The Foundry MODO SDK wiki
Jump to: navigation, search


Undoubtedly at some point you'll find yourself needing to store some data associated with a script or plugin that you're writing. While it's perfectly possible and, indeed, valid to employ the User Values that you're probably already familiar with from scripting previous versions of modo, the new python API supports the 'Persistent Data' model defined by the C++ SDK. What follows are some examples of how so set up and use persistent data to store information in the user config file.


# Persistent data: Example 1
# When installed, executing the custom command defined in this plugin with the
# commnd string:
#    hello.persist hash_name atom_value
# will result in the following fragment of XML being created in the user config
# file when modo is closed:
#    <atom type="PersistTest">
#      <hash type="MainHash" key="hash_name">
#        <atom type="StringAtom">atom_value</atom>
#      </hash>
#    </atom>
import lx
import lxifc
import lxu.command
class PersistData(lxifc.Visitor):
    '''This is the persistent data visitor class. It's is responsible for walking
       the XML structure inside the top level atom. The top (outer) level atom,
       in this example the 'PersistTest' atom, is created when our 'PersistData'
       instance is configured (see the '__init__' function of 'PersistTestCmd'
    def vis_Evaluate(self):
        # need a Persistence service object
        per_S = lx.service.Persistence()
        # start a hash element of type 'MainHash'
        per_S.Start("MainHash", lx.symbol.i_PERSIST_HASH)
        # Start an atom element of type 'StringAtom' - note the strings you use
        # for both the hash and atom elements are arbitrary, you can use anything
        # you like.
        per_S.Start("StringAtom", lx.symbol.i_PERSIST_ATOM)
        # add a value of type string to the atom
        per_S.AddValue (lx.symbol.sTYPE_STRING)
        # close the atom element
        self.atom_str = per_S.End()
        # need an attribute object to store the value for the atom
        self.attr_str = lx.object.Attributes(self.atom_str)
        # close the 'MainHash' hash element.
        self.hash_main = per_S.End()
# need a global reference to the persistent data object we'll be creating. 
persist_data = None
class PersistTestCmd(lxu.command.BasicCommand):
    '''A simple custom command plugin to use persistent data''' 
    def __init__(self):
        '''Add a couple of arguments to the custom command to be used as input
        for the persistent data
        global persist_data
        self.dyna_Add('hash',  lx.symbol.sTYPE_STRING)		# 0
        self.dyna_Add('value', lx.symbol.sTYPE_STRING)		# 1
        self.basic_SetFlags(1, lx.symbol.fCMDARG_OPTIONAL)
        # check to see if 'persist_data' already exists (we only want to create
        # it once per session), create and configure it if not. This also creates
        # the outermost hash of the XML fragment for our persistent data entry
        # in the user config file.
        if persist_data == None:
            persist_data = PersistData()
            lx.service.Persistence().Configure("PersistTest", persist_data)
    def basic_Execute(self, msg, flags):
        global persist_data
        # get the hash type string from the command's first argument
        hash_type_string = self.dyna_String(0)
        # check to see if the second argument is set
        if self.dyna_IsSet(1):
            # get the second argument to the command
            atom_value = self.dyna_String(1)
            # insert a hash element with the first argument to the command 
            # as the hash's 'key' attribute
            # add an atom element
            # set the atom's value to the second argument passed to the command
            persist_data.attr_str.SetString(0, atom_value)
            # second argument to the command wasn't set so look up the main hash
            # and delete it.
lx.bless(PersistTestCmd, "hello.persist")