def __init__(self): self.materialmanager = None # Set by materialmanager when it starts up. self.data = LabelTree() # Need to own the references to the key objects, which are # only weakly referenced in LabelTree, and used to identify # menus. This allows the menus to disappear automatically # when the PropertyManager is destroyed. (Why bother? The # PropertyManager isn't destroyed until the program quits.) self.parametrizekey = parametrizeKey self.loadkey = loadKey def paramcopy(object): # This routine is a callback function passed to # LabelTree.makeOOFMenu. makeOOFMenu uses it to get the # list of parameters for each menuitem that it creates. # The 'object' argument is the PropertyRegistration for # which the menu item is being built. # It's tempting to simply return the # PropertyRegistration's list of Parameters, so that the # registration and the menu item share Parameter objects, # and eliminating the need to copy values back and forth. # This temptation must be resisted. If the Parameters are # shared, then loading a named Property from a data file # will change the settings of an already parametrized # unnamed Property. if object: return [p.clone() for p in object.getDefaultParams()] return [] def kwarg_func(object): # Extra kwargs for OOFMenuItem ctor. if object and object.secret(): return {'secret': 1, 'no_doc': 1} return {} # Menu items are put into OOF.Property for scripts and # OOF.LoadData.Property for data files. The menus are created # automatically by the LabelTree, which uses the given key to # distinguish them. OOF.Property.addItem( self.data.makeOOFMenu( # The name 'Parametrize' is also used in _parametrizeDiscussion. # Don't change it here without changing it there. name='Parametrize', key=self.parametrizekey, param_func=paramcopy, kwarg_func=kwarg_func, callback=self.parametrizercallback, help=xmlmenudump.DiscussionFunc(_parametrizeHelp), discussion=xmlmenudump.DiscussionFunc(_parametrizeDiscussion))) OOF.LoadData.addItem( self.data.makeOOFMenu( name='Property', key=self.loadkey, param_func=paramcopy, kwarg_func=kwarg_func, callback=self.creatorcallback, params=[ parameter.StringParameter('name', tip="Name of Property.") ], discussion=xmlmenudump.DiscussionFunc(_loadDiscussion), help=xmlmenudump.DiscussionFunc(_loadHelp)))
def __init__(self): self.materialmanager = None # Set by materialmanager when it starts up. self.data = LabelTree() # Need to own the references to the key objects, which are # only weakly referenced in LabelTree, and used to identify # menus. This allows the menus to disappear automatically # when the PropertyManager is destroyed. (Why bother? The # PropertyManager isn't destroyed until the program quits.) self.parametrizekey = parametrizeKey self.loadkey = loadKey def paramcopy(object): # This routine is a callback function passed to # LabelTree.makeOOFMenu. makeOOFMenu uses it to get the # list of parameters for each menuitem that it creates. # The 'object' argument is the PropertyRegistration for # which the menu item is being built. # It's tempting to simply return the # PropertyRegistration's list of Parameters, so that the # registration and the menu item share Parameter objects, # and eliminating the need to copy values back and forth. # This temptation must be resisted. If the Parameters are # shared, then loading a named Property from a data file # will change the settings of an already parametrized # unnamed Property. if object: return [ p.clone() for p in object.getDefaultParams() ] return [] def kwarg_func(object): # Extra kwargs for OOFMenuItem ctor. if object and object.secret(): return {'secret':1, 'no_doc':1} return {} # Menu items are put into OOF.Property for scripts and # OOF.LoadData.Property for data files. The menus are created # automatically by the LabelTree, which uses the given key to # distinguish them. OOF.Property.addItem(self.data.makeOOFMenu( # The name 'Parametrize' is also used in _parametrizeDiscussion. # Don't change it here without changing it there. name='Parametrize', key=self.parametrizekey, param_func = paramcopy, kwarg_func = kwarg_func, callback = self.parametrizercallback, help=xmlmenudump.DiscussionFunc(_parametrizeHelp), discussion=xmlmenudump.DiscussionFunc(_parametrizeDiscussion))) OOF.LoadData.addItem(self.data.makeOOFMenu( name='Property', key=self.loadkey, param_func = paramcopy, kwarg_func = kwarg_func, callback = self.creatorcallback, params = [parameter.StringParameter('name', tip="Name of Property.")], discussion=xmlmenudump.DiscussionFunc(_loadDiscussion), help=xmlmenudump.DiscussionFunc(_loadHelp)))
class PropertyManager: def __init__(self): self.materialmanager = None # Set by materialmanager when it starts up. self.data = LabelTree() # Need to own the references to the key objects, which are # only weakly referenced in LabelTree, and used to identify # menus. This allows the menus to disappear automatically # when the PropertyManager is destroyed. (Why bother? The # PropertyManager isn't destroyed until the program quits.) self.parametrizekey = parametrizeKey self.loadkey = loadKey def paramcopy(object): # This routine is a callback function passed to # LabelTree.makeOOFMenu. makeOOFMenu uses it to get the # list of parameters for each menuitem that it creates. # The 'object' argument is the PropertyRegistration for # which the menu item is being built. # It's tempting to simply return the # PropertyRegistration's list of Parameters, so that the # registration and the menu item share Parameter objects, # and eliminating the need to copy values back and forth. # This temptation must be resisted. If the Parameters are # shared, then loading a named Property from a data file # will change the settings of an already parametrized # unnamed Property. if object: return [p.clone() for p in object.getDefaultParams()] return [] def kwarg_func(object): # Extra kwargs for OOFMenuItem ctor. if object and object.secret(): return {'secret': 1, 'no_doc': 1} return {} # Menu items are put into OOF.Property for scripts and # OOF.LoadData.Property for data files. The menus are created # automatically by the LabelTree, which uses the given key to # distinguish them. OOF.Property.addItem( self.data.makeOOFMenu( # The name 'Parametrize' is also used in _parametrizeDiscussion. # Don't change it here without changing it there. name='Parametrize', key=self.parametrizekey, param_func=paramcopy, kwarg_func=kwarg_func, callback=self.parametrizercallback, help=xmlmenudump.DiscussionFunc(_parametrizeHelp), discussion=xmlmenudump.DiscussionFunc(_parametrizeDiscussion))) OOF.LoadData.addItem( self.data.makeOOFMenu( name='Property', key=self.loadkey, param_func=paramcopy, kwarg_func=kwarg_func, callback=self.creatorcallback, params=[ parameter.StringParameter('name', tip="Name of Property.") ], discussion=xmlmenudump.DiscussionFunc(_loadDiscussion), help=xmlmenudump.DiscussionFunc(_loadHelp))) # __setitem__ gets called whenever a new registration is # instantiated. This happens for unnamed properties at start-up # time and for named properties whenever they're created. Does # collision detection by first attempting a retrieval on the key # -- if that succeeds, you drop through to the "else:". def __setitem__(self, key, value): try: collision = self.data[key] except KeyError: # Key not found, OK to insert. propclass = string.split(key, ':')[-1] # Add it to the labeltree. self.data.__setitem__(key, value, ordering=value.ordering) else: # Name-collision has occurred. This is only an error # if the parameter values conflict. for (p1, p2) in zip(collision.object.params, value.params): if (p1.name != p2.name) or (p1.value != p2.value): raise KeyError( "Assignment collision in PropertyManager, key %s." % ` key `) # Make a named instance of the given property. Called by # OOF.Property.Copy, so it's not necessary to do all the checks # done in __setitem__. The passed-in newname is the leaf # component, but oldname is a fully qualified name. def new_prop(self, oldname, newname): oldreg = self.data[oldname].object if hasattr(oldreg, "parent"): namelist = string.split(oldname, ':')[:-1] fullname = string.join(namelist + [newname], ':') else: fullname = oldname + ":" + newname newreg = oldreg.named_copy(fullname) switchboard.notify("new property", newreg) def __getitem__(self, key): return self.data[key].object # Delete the named item. LabelTree ("self.data") will raise # ErrUserError if the named item is a non-leaf. def delete(self, name): reg = self.data[name].object if hasattr(reg, "parent"): self.materialmanager.delete_prop(name) reg.unregister() self.data.delete(name) else: reporter.warn("Predefined properties cannot be deleted!") # Property name uniquifier, used when copying. "oldprop" is a # fully qualified name of an existing property, and newname is an # unqualfied candidate "leaf" name. def uniqueName(self, oldprop, newname): oldreg = self.data[oldprop].object try: contextreg = oldreg.parent except AttributeError: contextreg = oldreg # Get the labeltreenode. ltn = self.data[self.data.objpath(contextreg)] nameset = ltn.children() return utils.menUniqueName(newname, nameset) # This menu callback gets called when the parameters of a # property are changed. Figure out which property registration # object is relevant, and run its new_params() method. def parametrizercallback(self, menuitem, **kwargs): if parallel_enable.enabled(): OOF.LoadData.IPC.Property.Parametrize(**kwargs) else: # Translate the menuitem's path to the tree's path. The first # three words of the path are OOF.Property.Parametrize. # We want the remainder. treepath = string.split(menuitem.path(), ".")[3:] reg = self.data[treepath].object reg.new_params(**kwargs) switchboard.notify("redraw") # This method is called by propertymenuIPC.py during # initialization. It is not placed in PropertyManager.__init__ # because OOF.LoadData.IPC.Property has not been added yet. def set_parallel_parametrizercallback(self): def paramcopy(object): if object: return [p.clone() for p in object.getDefaultParams()] return [] def kwarg_func(object): # Extra kwargs for OOFMenuItem ctor. if object and object.secret(): return {'secret': 1, 'no_doc': 1} return {} # Take the ipc menu already created in propertymenuIPC and # build a menu for parametrizing to all processes ipcpropmenu = OOF.LoadData.IPC.Property ipcpropmenu.addItem( self.data.makeOOFMenu(name='Parametrize', key=self.parametrizekey, param_func=paramcopy, kwarg_func=kwarg_func, callback=self.parallel_parametrizercallback, threadable=oofmenu.PARALLEL_THREADABLE)) def parallel_parametrizercallback(self, menuitem, **kwargs): # The first five words of menuitem.path() are # OOF.LoadData.IPC.Property.Parametrize # We want the remainder. treepath = string.split(menuitem.path(), ".")[5:] reg = self.data[treepath].object reg.new_params(**kwargs) switchboard.notify("redraw") # Menu callback for OOF.LoadData.Property. "reg" is the # registration entry corresponding to the menu item that initiated # the callback, e.g. # "OOF.LoadData.Property.Create.Elasticity.IsoElasticity". The # PropertyRegistration and NamedPropertyRegistration's writeData # methods ensure that "reg" is always a PropertyRegistration. def creatorcallback(self, menuitem, **kwargs): treepath = string.split(menuitem.path(), ".")[3:] reg = self.data[treepath].object name = menuitem.params[0].value # Collision looks for the name under this tree, and if it # finds it, checks if the parameter values are all equal. If # a collision occurs and the parameters conflict, an exception # is raised. If collision returns "true", that means a # collision occurred but the parameters matched. If collision # returns "false", a collision did not occur. namecollision, parametercollision = reg.collision( name, menuitem.params[1:]) if namecollision: # name is a duplicate if parametercollision: # parameters disagree if name != "": raise ooferror.ErrSetupError( "Named property in datafile conflicts with existing property '%s'" % name) # reparametrization of unnamed property if reg.materials: raise ooferror.ErrSetupError( "Unnamed property in datafile conflicts with existing property '%s'" % name) # Unnamed property is being reparametrized, but it's # not used in any materials, so it's ok. reg.new_params(**kwargs) switchboard.notify("redraw") # A name collision with no parameter collision doesn't # require any action. The data file contained a property # identical to an existing property. else: # No collision, we must create a new NamedRegistration. # We know it's a NamedRegistration because unnamed # property registrations *always* produce a name conflict. fullname = string.join(treepath + [name], ":") newreg = reg.named_copy(fullname, menuitem.params[1:]) switchboard.notify("redraw")
class PropertyManager: def __init__(self): self.materialmanager = None # Set by materialmanager when it starts up. self.data = LabelTree() # Need to own the references to the key objects, which are # only weakly referenced in LabelTree, and used to identify # menus. This allows the menus to disappear automatically # when the PropertyManager is destroyed. (Why bother? The # PropertyManager isn't destroyed until the program quits.) self.parametrizekey = parametrizeKey self.loadkey = loadKey def paramcopy(object): # This routine is a callback function passed to # LabelTree.makeOOFMenu. makeOOFMenu uses it to get the # list of parameters for each menuitem that it creates. # The 'object' argument is the PropertyRegistration for # which the menu item is being built. # It's tempting to simply return the # PropertyRegistration's list of Parameters, so that the # registration and the menu item share Parameter objects, # and eliminating the need to copy values back and forth. # This temptation must be resisted. If the Parameters are # shared, then loading a named Property from a data file # will change the settings of an already parametrized # unnamed Property. if object: return [ p.clone() for p in object.getDefaultParams() ] return [] def kwarg_func(object): # Extra kwargs for OOFMenuItem ctor. if object and object.secret(): return {'secret':1, 'no_doc':1} return {} # Menu items are put into OOF.Property for scripts and # OOF.LoadData.Property for data files. The menus are created # automatically by the LabelTree, which uses the given key to # distinguish them. OOF.Property.addItem(self.data.makeOOFMenu( # The name 'Parametrize' is also used in _parametrizeDiscussion. # Don't change it here without changing it there. name='Parametrize', key=self.parametrizekey, param_func = paramcopy, kwarg_func = kwarg_func, callback = self.parametrizercallback, help=xmlmenudump.DiscussionFunc(_parametrizeHelp), discussion=xmlmenudump.DiscussionFunc(_parametrizeDiscussion))) OOF.LoadData.addItem(self.data.makeOOFMenu( name='Property', key=self.loadkey, param_func = paramcopy, kwarg_func = kwarg_func, callback = self.creatorcallback, params = [parameter.StringParameter('name', tip="Name of Property.")], discussion=xmlmenudump.DiscussionFunc(_loadDiscussion), help=xmlmenudump.DiscussionFunc(_loadHelp))) # __setitem__ gets called whenever a new registration is # instantiated. This happens for unnamed properties at start-up # time and for named properties whenever they're created. Does # collision detection by first attempting a retrieval on the key # -- if that succeeds, you drop through to the "else:". def __setitem__(self,key,value): try: collision = self.data[key] except KeyError: # Key not found, OK to insert. propclass = string.split(key,':')[-1] # Add it to the labeltree. self.data.__setitem__(key, value, ordering=value.ordering) else: # Name-collision has occurred. This is only an error # if the parameter values conflict. for (p1, p2) in zip(collision.object.params, value.params): if (p1.name != p2.name) or (p1.value != p2.value): raise KeyError( "Assignment collision in PropertyManager, key %s." % `key`) # Make a named instance of the given property. Called by # OOF.Property.Copy, so it's not necessary to do all the checks # done in __setitem__. The passed-in newname is the leaf # component, but oldname is a fully qualified name. def new_prop(self, oldname, newname): oldreg = self.data[oldname].object if hasattr(oldreg , "parent"): namelist = string.split(oldname, ':')[:-1] fullname = string.join(namelist+[newname], ':') else: fullname = oldname+":"+newname newreg = oldreg.named_copy(fullname) switchboard.notify("new property", newreg) def __getitem__(self,key): return self.data[key].object # Delete the named item. LabelTree ("self.data") will raise # ErrUserError if the named item is a non-leaf. def delete(self, name): reg = self.data[name].object if hasattr(reg, "parent"): self.materialmanager.delete_prop(name) reg.unregister() self.data.delete(name) else: reporter.warn("Predefined properties cannot be deleted!") # Property name uniquifier, used when copying. "oldprop" is a # fully qualified name of an existing property, and newname is an # unqualfied candidate "leaf" name. def uniqueName(self, oldprop, newname): oldreg = self.data[oldprop].object try: contextreg = oldreg.parent except AttributeError: contextreg = oldreg # Get the labeltreenode. ltn = self.data[self.data.objpath(contextreg)] nameset = ltn.children() return utils.menUniqueName(newname, nameset) # This menu callback gets called when the parameters of a # property are changed. Figure out which property registration # object is relevant, and run its new_params() method. def parametrizercallback(self, menuitem, **kwargs): if parallel_enable.enabled(): OOF.LoadData.IPC.Property.Parametrize(**kwargs) else: # Translate the menuitem's path to the tree's path. The first # three words of the path are OOF.Property.Parametrize. # We want the remainder. treepath = string.split(menuitem.path(),".")[3:] reg = self.data[treepath].object reg.new_params(**kwargs) switchboard.notify("redraw") # This method is called by propertymenuIPC.py during # initialization. It is not placed in PropertyManager.__init__ # because OOF.LoadData.IPC.Property has not been added yet. def set_parallel_parametrizercallback(self): def paramcopy(object): if object: return [ p.clone() for p in object.getDefaultParams() ] return [] def kwarg_func(object): # Extra kwargs for OOFMenuItem ctor. if object and object.secret(): return {'secret':1, 'no_doc':1} return {} # Take the ipc menu already created in propertymenuIPC and # build a menu for parametrizing to all processes ipcpropmenu=OOF.LoadData.IPC.Property ipcpropmenu.addItem(self.data.makeOOFMenu( name='Parametrize', key=self.parametrizekey, param_func = paramcopy, kwarg_func = kwarg_func, callback = self.parallel_parametrizercallback, threadable=oofmenu.PARALLEL_THREADABLE)) def parallel_parametrizercallback(self, menuitem, **kwargs): # The first five words of menuitem.path() are # OOF.LoadData.IPC.Property.Parametrize # We want the remainder. treepath = string.split(menuitem.path(),".")[5:] reg = self.data[treepath].object reg.new_params(**kwargs) switchboard.notify("redraw") # Menu callback for OOF.LoadData.Property. "reg" is the # registration entry corresponding to the menu item that initiated # the callback, e.g. # "OOF.LoadData.Property.Create.Elasticity.IsoElasticity". The # PropertyRegistration and NamedPropertyRegistration's writeData # methods ensure that "reg" is always a PropertyRegistration. def creatorcallback(self, menuitem, **kwargs): treepath = string.split(menuitem.path(),".")[3:] reg = self.data[treepath].object name = menuitem.params[0].value # Collision looks for the name under this tree, and if it # finds it, checks if the parameter values are all equal. If # a collision occurs and the parameters conflict, an exception # is raised. If collision returns "true", that means a # collision occurred but the parameters matched. If collision # returns "false", a collision did not occur. namecollision, parametercollision = reg.collision(name, menuitem.params[1:]) if namecollision: # name is a duplicate if parametercollision: # parameters disagree if name != "": raise ooferror.ErrSetupError("Named property in datafile conflicts with existing property '%s'" % name) # reparametrization of unnamed property if reg.materials: raise ooferror.ErrSetupError("Unnamed property in datafile conflicts with existing property '%s'" % name) # Unnamed property is being reparametrized, but it's # not used in any materials, so it's ok. reg.new_params(**kwargs) switchboard.notify("redraw") # A name collision with no parameter collision doesn't # require any action. The data file contained a property # identical to an existing property. else: # No collision, we must create a new NamedRegistration. # We know it's a NamedRegistration because unnamed # property registrations *always* produce a name conflict. fullname = string.join( treepath + [name], ":") newreg = reg.named_copy(fullname, menuitem.params[1:]) switchboard.notify("redraw")