def adapt_animation_layout(animation):
layout = animation.layout<EOL>required = getattr(animation, '<STR_LIT>', None)<EOL>if not required or isinstance(layout, required):<EOL><INDENT>return<EOL><DEDENT>msg = LAYOUT_WARNING % (<EOL>type(animation).__name__, required.__name__, type(layout).__name__)<EOL>setter = layout.set<EOL>adaptor = None<EOL>if required is strip.Strip:<EOL><INDENT>if isinstance(layout, matrix.Matrix):<EOL><INDENT>width = layout.width<EOL>def adaptor(pixel, color=None):<EOL><INDENT>y, x = divmod(pixel, width)<EOL>setter(x, y, color or BLACK)<EOL><DEDENT><DEDENT>elif isinstance(layout, cube.Cube):<EOL><INDENT>lx, ly = layout.x, layout.y<EOL>def adaptor(pixel, color=None):<EOL><INDENT>yz, x = divmod(pixel, lx)<EOL>z, y = divmod(yz, ly)<EOL>setter(x, y, z, color or BLACK)<EOL><DEDENT><DEDENT>elif isinstance(layout, circle.Circle):<EOL><INDENT>def adaptor(pixel, color=None):<EOL><INDENT>layout._set_base(pixel, color or BLACK)<EOL><DEDENT><DEDENT><DEDENT>elif required is matrix.Matrix:<EOL><INDENT>if isinstance(layout, strip.Strip):<EOL><INDENT>width = animation.width<EOL>def adaptor(x, y, color=None):<EOL><INDENT>setter(x + y * width, color or BLACK)<EOL><DEDENT><DEDENT><DEDENT>if not adaptor:<EOL><INDENT>raise ValueError(msg)<EOL><DEDENT>log.warning(msg)<EOL>animation.layout.set = adaptor<EOL>
Adapt the setter in an animation's layout so that Strip animations can run
on on Matrix, Cube, or Circle layout, and Matrix or Cube animations can run
on a Strip layout.