Friday, 9 November 2012

Using MetaClass in your own classes

So in Red9 you have the power of a full MetaData api but how do you then expand and use that outside of the Red9 package? This came up recently with somebody inheriting from r9Meta.MetaClass in their own module outside of Red9. So I thought I give you a few pointers.

The first thing to note is that Red9_Meta builds up a global list of registered classes which inherit from MetaClass. Basically I need to know, when a node is passed into the MetaClass.__new__(), whether it's mClass attr (the string pointer that holds what class to instantiate on create) is in the known inheritance mapping. Think about it, I initialize the correct class object for you but the code needs to know if that class is available and registered in Python, otherwise I can't instantiate it for you.

This data is stored in global RED9_META_REGISTERY and in the Red9 pack that's setup in the Red9.core.__init__ by calling registerMClassInheritanceMapping()

All following!

Ok so Red9 is up and Meta knows about classes which have MetaClass as a base. By the way, this is found using the cls.__subclasses__(). But now you have a class outside of Red9 which is also using MetaClass and inorder for it to work correctly, you need to get that little bugger picked up and inside the RED9_META_REGISTERY!

This is all down to the order in which the modules are initialized. Lets say that you've booted Maya and Red9 is up. But you have a module in scripts which imports and uses Red9_Meta and it's not showing up in the meta registry. This is because until you import that module it won't show up in the subclasses cmd, and when you do import it, Red9 won't have it in the registry as it was imported after Red9 booted. So you need to first import your module, then force it into the RED9_META_REGISTERY by doing the following:

    #=========================================================================
    # Because we're now inheriting from Red9_Meta any reload on any module that
    # is instantiated from Meta will invalidate the RED9_META_REGISTERY. Here
    # we force the update on the Red9 internal registry
    #=========================================================================    
    from Red9.core import Red9_Meta as r9Meta
    r9Meta.registerMClassInheritanceMapping()  
    print '============================================='
    r9Meta.printSubClassRegistry()
    print '============================================='

Hope that makes sense, if not drop me a mail and I'll point you in the right direction!

Red