import sys import json import random import logger this = sys.modules[__name__] this.encoded = None this.pattern = None this.values = { "stack": 0, "stack2": 0, "stack3": 0, "stack4": 0, "stack5": 0, "stack6": 0, "stackr": 0, "stackg": 0, "stackb": 0, "r": 0, "g": 0, "b": 0, "tick": 0, "index": 0, "fadeval": 0, "fadeinc": True } def constant(target, arg, index): return (arg, index) def add(target, arg, index): return (target + arg, index) def sub(target, arg, index): return (target - arg, index) def mult(target, arg, index): return (target * arg, index) def div(target, arg, index): return (target / arg, index) def mod(target, arg, index): if arg <= 0: return target return (target % arg, index) def fade(target, arg, index): value = this.values['fadeval'] if this.values['fadeinc']: value += 1 if value >= arg: this.values['fadeinc'] = False else: value -= 1 if value <= 0: this.values['fadeinc'] = True this.values['fadeval'] = value return (value, index) def rand(target, arg, index): return (random.randrange(0, 255), index) def jmp(target, arg, index): return (target, target) def jnz(target, arg, index): if target != 0: return (target, arg) else: return (target, index) def jez(target, arg, index): if target == 0: return (target, arg) else: return (target, index) def _apply(index, target, arg, func): if type(arg) is int: logger.debug("ran: {} {} {} {}".format(index, func.__name__, target, arg)) return func(target, arg, index) elif type(arg) is str and arg in this.values: logger.debug("ran: {} {} {} {}".format( index, func.__name__, target, this.values[arg])) return func(target, this.values[arg], index) def apply(index, targets, args, func): j = index for target in range(len(targets)): if this.values[targets[target]['channel']] != None: logger.debug("target: {}".format(targets[target]['channel'])) if target < len(args): val, jump = _apply( index, this.values[targets[target]['channel']], args[target], func) if val != this.values[targets[target]['channel']]: this.values[targets[target]['channel']] = val j = jump else: val, jump = _apply( index, this.values[targets[target]['channel']], 0, func) if val != this.values[targets[target]['channel']]: this.values[targets[target]['channel']] = val j = jump return j this.instructions = { "CONSTANT": constant, "ADD": add, "SUBTRACT": sub, "MULTIPLY": mult, "DIVIDE": div, "MODULO": mod, "FADE": fade, "RANDOM": rand, "JMP": jmp, "JNZ": jnz, "JEZ": jez } def default(index, tick): return (((index + tick) * 5) % 255, (tick * 42) % 255, (tick * 50) % 255) def pat(index, tick, previous_values): this.values['tick'] = tick this.values['index'] = index if this.pattern != None: i = 0 while i < len(this.pattern): if i < len(this.pattern): name = this.pattern[i]['instruction']['name'] targets = this.pattern[i]['instruction']['targets'] args = [] if 'args' in this.pattern[i]['instruction']: args = this.pattern[i]['instruction']['args'] if this.instructions[name] != None: jump = apply(i, targets, args, this.instructions[name]) logger.debug("{} {} {} {} {}".format(jump, i, len( this.pattern), jump != i, jump <= len(this.pattern))) if jump != i and jump <= len(this.pattern): logger.debug("jumping to {}".format(jump - 1)) i = jump - 1 i += 1 r = this.values["r"] g = this.values["g"] b = this.values["b"] this.values["r"] = 0 this.values["g"] = 0 this.values["b"] = 0 this.values["stack"] = 0 if r > 255: r = 255 elif r < 0: r = 0 if g > 255: g = 255 elif g < 0: g = 0 if b > 255: b = 255 elif b < 0: b = 0 logger.debug("final color: {}".format((r, g, b))) return (r, g, b) else: return default(index, tick) def parse(str): this.encoded = str logger.debug(this.encoded) this.pattern = json.loads(this.encoded)