annotate pyink/trait.py @ 1345:e0400a2b7c35

Use trait instead of mixin for component_manager
author Thinker K.F. Li <thinker@codemud.net>
date Fri, 11 Feb 2011 15:10:37 +0800
parents
children 4fdc998d3dc3
rev   line source
1345
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
1 ## \brief Implement descriptors for mapping attributes for traits.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
2 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
3 # The instances of require map attributes of traits to corresponding
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
4 # attributes of the instance of the composition class.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
5 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
6 class require(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
7 def __get__(self, instance, owner):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
8 if not instance: # from a class object
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
9 return self
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
10
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
11 attrname = instance._trait_attrname_map[self]
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
12 composite_obj = instance._trait_composite_obj
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
13 val = getattr(composite_obj, attrname)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
14 return val
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
15
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
16 def __set__(self, instance, value):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
17 attrname = instance._trait_attrname_map[self]
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
18 composite_obj = instance._trait_composite_obj
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
19 setattr(composite_obj, attrname, value)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
20 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
21 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
22
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
23
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
24 ## \brief Decorator for making a class being a trait.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
25 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
26 def trait(trait_clazz):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
27 attrname_map = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
28 trait_clazz._trait_attrname_map = attrname_map
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
29
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
30 for attr in dir(trait_clazz):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
31 value = getattr(trait_clazz, attr)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
32 if value != require:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
33 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
34
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
35 require_o = require()
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
36 setattr(trait_clazz, attr, require_o)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
37 attrname_map[require_o] = attr
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
38 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
39
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
40 trait_clazz._is_trait = True
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
41
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
42 return trait_clazz
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
43
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
44
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
45 ## \brief The function to return a proxy for a method of a trait.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
46 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
47 def trait_method_proxy(trait_clazz, method):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
48 def trait_method_proxy_real(self, *args, **kws):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
49 if not hasattr(self, '_all_trait_objs'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
50 # self is an instance of the class composed from traits.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
51 self._all_trait_objs = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
52 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
53
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
54 try:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
55 trait_obj = self._all_trait_objs[trait_clazz]
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
56 except KeyError:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
57 trait_obj = trait_clazz()
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
58 trait_obj._trait_composite_obj = self
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
59 self._all_trait_objs[trait_clazz] = trait_obj
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
60 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
61
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
62 r = method(trait_obj, *args, **kws)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
63
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
64 return r
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
65
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
66 return trait_method_proxy_real
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
67
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
68
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
69 ## \brief Derive and modify an existing trait.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
70 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
71 def derive_trait(a_trait, composite_clazz):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
72 attrname_map = None
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
73 if hasattr(composite_clazz, 'provide_traits'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
74 provide_traits = composite_clazz.provide_traits
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
75 if a_trait in provide_traits:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
76 provide_trait = provide_traits[a_trait]
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
77 attrname_map = dict(a_trait._trait_attrname_map)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
78 attrname_map.update(provide_trait)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
79 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
80 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
81
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
82 dic = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
83 if attrname_map:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
84 dic['_trait_attrname_map'] = attrname_map
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
85 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
86
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
87 derived = type('derived_trait', (a_trait,), dic)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
88
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
89 return derived
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
90
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
91 ## \brief A decorator to make class composited from traits.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
92 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
93 # The class decorated by composite must own a use_traits attribute.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
94 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
95 # \verbatim
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
96 # @trait
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
97 # class trait_a(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
98 # var_a = require
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
99 # def xxx(self): return self.var_a
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
100 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
101 # @trait
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
102 # class trait_b(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
103 # def ooo(self): pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
104 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
105 # @composite
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
106 # class foo(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
107 # use_traits = (trait_a, trait_b)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
108 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
109 # var_a = 'value of var_a'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
110 # pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
111 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
112 # obj = foo()
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
113 # \endverbatim
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
114 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
115 # To make a class from a set of traits. You must decorate the class
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
116 # with the decorator 'composite'. The class must has an attribute,
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
117 # named use_traits, to provide a list or tuple of traits.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
118 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
119 # Class that defines a trait must decorated with the decorator
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
120 # 'trait'. If the trait need to access state (varaibles) of the
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
121 # intances of composition class, it must define attributes with value
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
122 # 'require', likes what 'var_a' of trait_a does. Then, the attributes
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
123 # would be mapped to corresponding attributes of instances of
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
124 # composition class. For example, when you call obj.xxx(), it returns
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
125 # value of 'var_a', and attribute 'var_a' is a property that returns
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
126 # the value of 'var_a' of 'obj', an instance of class foo.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
127 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
128 # By default, traits map attribute 'var_a' to 'var_a' of instances of
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
129 # composition classes. But, you can change it by specifying the map
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
130 # in an attribute, named 'provide_traits', defined in composition
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
131 # class. The attribute provide_traits is a dictionary mapping from
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
132 # trait class to a dictionary, named 'attrname_map' for the trait.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
133 # The attrname_map maps require attributes of the trait to names of
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
134 # attributes of instances of the composition class.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
135 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
136 def composite(clazz):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
137 if not hasattr(clazz, 'use_traits'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
138 raise KeyError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
139 '%s has no use_trait: it must be a list of traits' % (repr(clazz))
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
140 traits = clazz.use_traits
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
141
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
142 for a_trait in traits:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
143 if not hasattr(a_trait, '_is_trait'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
144 raise TypeError, '%s is not a trait' % (repr(a_trait))
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
145 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
146
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
147 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
148 # Check content of clazz.provide_traits
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
149 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
150 if hasattr(clazz, 'provide_traits'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
151 if not isinstance(clazz.provide_traits, dict):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
152 raise TypeError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
153 'provide_traits of a composite must be a dictionary'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
154
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
155 provide_set = set(clazz.provide_traits.keys())
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
156 trait_set = set(traits)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
157 unused_set = provide_set - trait_set
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
158 if unused_set:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
159 raise ValueError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
160 'can not find %s in provide_traits' % (repr(unused_set.pop()))
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
161
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
162 for trait, attrname_map in clazz.provide_traits.items():
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
163 for req in attrname_map:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
164 if not isinstance(req, require):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
165 raise TypeError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
166 '%s is not a require: key of an ' \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
167 'attribute name map must be a require' % (repr(req))
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
168 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
169 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
170 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
171
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
172 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
173 # Count number of appearing in all traits for every attribute name.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
174 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
175 attrname_cnts = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
176 for a_trait in traits:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
177 for attr in dir(a_trait):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
178 if attr.startswith('_'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
179 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
180
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
181 value = getattr(a_trait, attr)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
182 if value == require:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
183 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
184
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
185 attrname_cnts[attr] = attrname_cnts.setdefault(attr, 0) + 1
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
186 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
187 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
188
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
189 if hasattr(clazz, 'method_map_traits'):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
190 method_map_traits = clazz.method_map_traits
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
191 else:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
192 method_map_traits = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
193 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
194
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
195 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
196 # Set a proxy for every exported methods.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
197 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
198 derived_traits = clazz._derived_traits = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
199 for a_trait in traits:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
200 derived = derive_trait(a_trait, clazz)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
201 derived_traits[a_trait] = derived
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
202
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
203 if a_trait in method_map_traits:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
204 method_map_trait = method_map_traits[a_trait]
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
205 else:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
206 method_map_trait = {}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
207
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
208 for attr in dir(derived):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
209 if attr not in attrname_cnts: # hidden
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
210 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
211 if attrname_cnts[attr] > 1: # conflict
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
212 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
213
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
214 if hasattr(clazz, attr): # override
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
215 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
216
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
217 value = getattr(a_trait, attr)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
218 if value in method_map_trait: # do it later
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
219 continue
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
220
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
221 value = getattr(derived, attr)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
222
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
223 if not callable(value):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
224 raise TypeError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
225 '%s.%s is not a callable' % (repr(a_trait), attr)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
226
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
227 func = value.im_func
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
228 proxy = trait_method_proxy(derived, func)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
229 setattr(clazz, attr, proxy)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
230 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
231 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
232
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
233 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
234 # Map methods specified in method_map_traits.
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
235 #
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
236 for a_trait, method_map_trait in method_map_traits.items():
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
237 if a_trait not in derived_traits:
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
238 raise TypeError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
239 '%s is not a trait used by the composition class' % \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
240 (repr(a_trait))
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
241
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
242 derived = derived_traits[a_trait]
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
243 for method, attrname in method_map_trait.items():
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
244 if not callable(method):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
245 raise TypeError, \
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
246 '%s.%s is not a callable' % (repr(a_trait), repr(method))
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
247 func = method.im_func
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
248 proxy = trait_method_proxy(derived, func)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
249 setattr(clazz, attrname, proxy)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
250 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
251 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
252
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
253 return clazz
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
254
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
255
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
256 if __name__ == '__main__':
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
257 @trait
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
258 class hello(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
259 msg = require
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
260
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
261 def hello(self, name):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
262 return self.msg + ' hello ' + name
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
263 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
264
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
265 @trait
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
266 class bye(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
267 msg = require
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
268
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
269 def bye(self, name):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
270 return self.msg + ' bye ' + name
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
271 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
272
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
273 @composite
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
274 class hello_bye(object):
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
275 use_traits = (hello, bye)
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
276
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
277 provide_hello = {hello.msg: 'msg1'}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
278 provide_traits = {hello: provide_hello}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
279
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
280 method_map_hello = {hello.hello: 'hello1'}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
281 method_map_traits = {hello: method_map_hello}
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
282
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
283 msg = 'hello_bye'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
284 msg1 = 'hello_bye_msg1'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
285 pass
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
286
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
287 o = hello_bye()
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
288 assert o.hello1('Miky') == 'hello_bye_msg1 hello Miky'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
289 assert o.bye('Miky') == 'hello_bye bye Miky'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
290 print 'OK'
e0400a2b7c35 Use trait instead of mixin for component_manager
Thinker K.F. Li <thinker@codemud.net>
parents:
diff changeset
291 pass