Tuesday, 16 October 2012

MetaClass - extra candy for complex Json attributes

Ok here's an interesting question. At the moment with the MetaClass stuff you can serialize a complex python structure, like a dictionary, to a string attribute on the MClass Maya node which then means you can do something like this:

#make an r9Meta.mClass node with an attribute managed by the JSON handler
mClass=r9Meta.MetaClass('myNode')
mClass.addAttr('newDict',{'A':2.0,'New':'hello'})

#return the original dict back from the Maya Node
mClass.newDict  
all goodness so far, but what if the user then does the following?

mClass.newDict['A']=5.0

mClass.newDict['A'] #2.0 ??????
You expect that would then modify the mClass attribute you added, wouldn't you? Well no, as the mClass.newDict returns a standard dict (by deserializing the Json string, which is then out of the scope of the metaClass code, it's just a dict and has no knowledge of the mClass itself.

So I've been thinking, what if the mClass.__getAttribute__ call that returns that dict actually returned a managed dict of my own type with an overloaded __setitem__ which would then push the changes back to the original mClass attribute? Well it works in testing, not sure if there's an easier way of linking these but I couldn't think of one. The beauty now is that you can do the following and this will pass the value back to the mClass and reserialize it back to the actual Maya string Json Attribute

mClass.newDict['A']='fooBar'
mClass.newDict['A']  #fooBar
I'm still looking into this but it certainly makes the code side a hell of a lot more manageable and flexible when you're using this class

 thoughts?

Red

2 comments:

  1. if it is know a head of time that setting an attr like that is going to be read only and then there is a method to make modifications to it, that works too. Being able to just assign a new value to the attr is always more convenient but that depends on the cost. If there is no risk the I'd say keep on with what you did to make it mutable.

    ReplyDelete
  2. We do exactly this in our metaclass code. There is a cost tho. When your inside your metaclass and you do self.foo = {} the __getattribute__ kicks in. Inspects the data cross references it data you might not want to serialize then automatically writes the data to the Maya node. You'll have to manage creating and deleting the attribute if the types change. Something to remember with references. It not cheap. Has benefits and drawbacks. Is not explicit. Your choice. Any heavy wrapping will slow you down. But if you only take the metadata when you about to work with it it's not an issue. I have scenes with 1000s of meta nodes. I only create these heavy instances when I'm about to work with them.

    ReplyDelete

Note: only a member of this blog may post a comment.