in src/spg/PatternGenerators/basePatternGenerator.py [0:0]
def _execute_per_frame_stage(self):
""" Triggers the control loop for the pattern generators which need patterns to change contents per frame,
but are required to move across the whole stage and are dependent on the order of the led walls
The user needs to implement generator method which is executed in separate thread per frame
:return: A dict of led wall name to frame and filepath values
"""
# Storage for a list of threads we are going to create, and the results we are going to return
threads = []
results = {}
# We loop over all the walls in the spd config
for self.led_wall in self.spg.walls.values():
results[self.led_wall.name] = {}
self.get_and_create_pattern_output_folder(
sub_folder="_".join([self.led_wall.name, self.name]))
# We add a hook to perform custom logic before we start a new sequence
self.sequence_start()
for self.frame in range(self.number_of_frames()):
# We add a hook to perform custom logic before we start a frame
self.frame_start()
# We get a dictionary of arguments to pass to our custom generator function
kwargs = self.get_kwargs()
# We create a new thread which executes our generator, which we start and keep track of
thread = _ThreadedFunction(self.generator, self.frame, kwargs, results)
thread.start()
threads.append(thread)
# We add a hook to perform custom logic as we end a frame
self.frame_end()
# We add a hook to perform custom logic as we end a sequence
self.sequence_end()
# We wait for all the frames to finish before we return the results
[thread.join() for thread in threads]
return results