1
- from demosys import context
2
- from demosys import resources
1
+ from typing import Any , List , Type , Union
2
+
3
+ import moderngl
4
+ from demosys import context , resources
5
+ from demosys .effects import Effect
3
6
from demosys .effects .registry import effects
7
+ from demosys .resources .meta import ResourceDescription
8
+ from demosys .scene import Scene
4
9
5
10
6
11
class BaseProject :
@@ -16,37 +21,52 @@ def __init__(self):
16
21
self ._scenes = {}
17
22
self ._data = {}
18
23
19
- def get_default_effect (self ):
20
- raise NotImplementedError ()
21
-
22
24
def create_effect_classes (self ):
23
- """Create effect classes in the registry"""
25
+ """
26
+ Registers effect packages defined in ``effect_packages``.
27
+ """
24
28
effects .polulate (self .effect_packages )
25
29
26
- def create_external_resources (self ):
30
+ def create_external_resources (self ) -> List [ ResourceDescription ] :
27
31
"""
28
- Create resources defined externally such as resource modules in effect packages.
32
+ Fetches all resource descriptions defined in effect packages.
29
33
30
- :returns: List of resource descriptions to load
34
+ Returns:
35
+ List of resource descriptions to load
31
36
"""
32
37
return effects .get_effect_resources ()
33
38
34
- def create_resources (self ):
39
+ def create_resources (self ) -> List [ ResourceDescription ] :
35
40
"""
36
- Create resources for the project
41
+ Create resources for the project.
42
+ Simply returns the ``resources`` list and can be implemented to
43
+ modify what a resource list is programmatically.
37
44
38
- :returns: List of resource descriptions to load
45
+ Returns:
46
+ List of resource descriptions to load
39
47
"""
40
48
return self .resources
41
49
42
50
def create_effect_instances (self ):
43
51
"""
44
- Create instances of effects
52
+ Create instances of effects.
53
+ Must be implemented or ``NotImplementedError`` is raised.
45
54
"""
46
55
raise NotImplementedError ()
47
56
48
- def create_effect (self , label , name , * args , ** kwargs ):
49
- """Create an effect instance"""
57
+ def create_effect (self , label : str , name : str , * args , ** kwargs ) -> Effect :
58
+ """
59
+ Create an effect instance adding it to the internal effects dictionary using the label as key.
60
+
61
+ Args:
62
+ label (str): The unique label for the effect instance
63
+ name (str): Name or full python path to the effect class we want to instantiate
64
+ args: Positional arguments to the effect initializer
65
+ kwargs: Keyword arguments to the effect initializer
66
+
67
+ Returns:
68
+ The newly created Effect instance
69
+ """
50
70
params = name .split ('.' )
51
71
effect_cls = effects .find_effect_class (params [- 1 ], package_name = "." .join (params [:- 1 ]))
52
72
effect = effect_cls (* args , ** kwargs )
@@ -61,12 +81,16 @@ def create_effect(self, label, name, *args, **kwargs):
61
81
62
82
def post_load (self ):
63
83
"""
64
- Actions after loading is complete
84
+ Called after resources are loaded before effects starts rendering.
85
+ It simply iterates each effect instance calling their ``post_load`` methods.
65
86
"""
66
87
for _ , effect in self ._effects .items ():
67
88
effect .post_load ()
68
89
69
90
def load (self ):
91
+ """
92
+ Loads this project instance
93
+ """
70
94
self .create_effect_classes ()
71
95
72
96
self ._add_resource_descriptions_to_pools (self .create_external_resources ())
@@ -88,53 +112,118 @@ def load(self):
88
112
self .post_load ()
89
113
90
114
def _add_resource_descriptions_to_pools (self , meta_list ):
115
+ """
116
+ Takes a list of resource descriptions adding them
117
+ to the resource pool they belong to scheduling them for loading.
118
+ """
91
119
if not meta_list :
92
120
return
93
121
94
122
for meta in meta_list :
95
123
getattr (resources , meta .resource_type ).add (meta )
96
124
97
125
def reload_programs (self ):
126
+ """
127
+ Reload all shader programs with the reloadable flag set
128
+ """
98
129
print ("Reloading programs:" )
99
130
for name , program in self ._programs .items ():
100
131
if getattr (program , 'program' , None ):
101
132
print (" - {}" .format (program .meta .label ))
102
133
program .program = resources .programs .load (program .meta )
103
134
104
- def get_effect (self , label ):
135
+ def get_effect (self , label : str ) -> Effect :
136
+ """
137
+ Get an effect instance by label
138
+
139
+ Args:
140
+ label (str): The label for the effect instance
141
+
142
+ Returns:
143
+ Effect class instance
144
+ """
105
145
return self ._get_resource (label , self ._effects , "effect" )
106
146
107
- def get_effect_class (self , class_name , package_name = None ):
147
+ def get_effect_class (self , class_name , package_name = None ) -> Type [Effect ]:
148
+ """
149
+ Get an effect class from the effect registry.
150
+
151
+ Args:
152
+ class_name (str): The exact class name of the effect
153
+
154
+ Keyword Args:
155
+ package_name (str): The python path to the effect package the effect name is located.
156
+ This is optional and can be used to avoid issue with class name collisions.
157
+
158
+ Returns:
159
+ Effect class
160
+ """
108
161
return effects .find_effect_class (class_name , package_name = package_name )
109
162
110
- def get_scene (self , label ):
163
+ def get_scene (self , label : str ) -> Scene :
164
+ """
165
+ Gets a scene by label
166
+
167
+ Args:
168
+ label (str): The label for the scene to fetch
169
+
170
+ Returns:
171
+ Scene instance
172
+ """
111
173
return self ._get_resource (label , self ._scenes , "scene" )
112
174
113
- def get_program (self , label ) :
175
+ def get_program (self , label : str ) -> moderngl . Program :
114
176
return self ._get_resource (label , self ._programs , "program" )
115
177
116
- def get_texture (self , label ):
178
+ def get_texture (self , label : str ) -> Union [moderngl .Texture , moderngl .TextureArray ,
179
+ moderngl .Texture3D , moderngl .TextureCube ]:
180
+ """
181
+ Get a texture by label
182
+
183
+ Args:
184
+ label (str): The label for the texture to fetch
185
+
186
+ Returns:
187
+ Texture instance
188
+ """
117
189
return self ._get_resource (label , self ._textures , "texture" )
118
190
119
- def get_data (self , label ):
191
+ def get_data (self , label : str ) -> Any :
192
+ """
193
+ Get a data resource by label
194
+
195
+ Args:
196
+ label (str): The labvel for the data resource to fetch
197
+
198
+ Returns:
199
+ The requeted data object
200
+ """
120
201
return self ._get_resource (label , self ._data , "data" )
121
202
122
- def _get_resource (self , label , source , resource_type ):
203
+ def _get_resource (self , label : str , source : dict , resource_type : str ):
204
+ """
205
+ Generic resoure fetcher handling errors.
206
+
207
+ Args:
208
+ label (str): The label to fetch
209
+ source (dict): The dictionary to look up the label
210
+ resource_type str: The display name of the resource type (used in errors)
211
+ """
123
212
try :
124
213
return source [label ]
125
214
except KeyError :
126
215
raise ValueError ("Cannot find {0} with label '{1}'.\n Existing {0} labels: {2}" .format (
127
216
resource_type , label , list (source .keys ())))
128
217
129
- def get_runnable_effects (self ):
218
+ def get_runnable_effects (self ) -> List [ Effect ] :
130
219
"""
131
- Returns all runnable effects in the project
220
+ Returns all runnable effects in the project.
132
221
133
222
:return: List of all runnable effects
134
223
"""
135
224
return [effect for name , effect in self ._effects .items () if effect .runnable ]
136
225
137
226
@property
138
- def ctx (self ):
227
+ def ctx (self ) -> moderngl . Context :
139
228
"""The MondernGL context"""
140
229
return context .ctx ()
0 commit comments