"""OscCommentMacroListener.py: Hog 4 comment macro antlr4 listener for OSC.""" import logging from time import sleep from .commentmacro.CommentMacroParser import CommentMacroParser from .commentmacro.CommentMacroListener import CommentMacroListener __all__ = [ "beautify_lisp_string", "OscCommentMacroListener", ] # https://raw.githubusercontent.com/jszheng/py3antlr4book/master/bin/pygrun # this is a python version of TestRig def beautify_lisp_string(in_string): """Prety output of a lisp string.""" # __author__ = 'jszheng' indent_size = 2 add_indent = ' ' * indent_size out_string = in_string[0] # no indent for 1st ( indent = '' for i in range(1, len(in_string) - 1): if in_string[i] == '(' and in_string[i + 1] != ' ': indent += add_indent out_string += "\n" + indent + '(' elif in_string[i] == ')': out_string += ')' if len(indent) > 0: indent = indent.replace(add_indent, '', 1) else: out_string += in_string[i] return out_string class OscCommentMacroListener(CommentMacroListener): """antlr4 listener for comment macros.""" def __init__(self): """Initialize the listener.""" self.osc = None def exitWait(self, ctx: CommentMacroParser.WaitContext): """On exiting the WAIT macro.""" logging.info("Waiting %d seconds.", ctx.number().value) sleep(ctx.number().value) def enterStatement(self, ctx: CommentMacroParser.StatementContext): """On entering a statement.""" # print the lisp tree of this macro lisp_tree_str = ctx.toStringTree(recog=ctx.parser) logging.debug(beautify_lisp_string(lisp_tree_str)) def enterTarget(self, ctx: CommentMacroParser.TargetContext): """On entering a target.""" ctx.targets = [] def exitTarget(self, ctx: CommentMacroParser.TargetContext): """On exiting a target.""" ctx.targets = set(ctx.targets) if isinstance(ctx.parentCtx, CommentMacroParser.TargetContext): ctx.parentCtx.targets.extend(ctx.targets) # add to parent targets def exitNumber(self, ctx: CommentMacroParser.NumberContext): """On exiting a number.""" try: ctx.value = int(ctx.getText()) except ValueError: ctx.value = float(ctx.getText()) if isinstance(ctx.parentCtx, CommentMacroParser.TargetContext): ctx.parentCtx.targets.append(ctx.value) def exitSpan(self, ctx: CommentMacroParser.SpanContext): """On exiting a span.""" lower = min(ctx.n1.value, ctx.n2.value) upper = max(ctx.n1.value, ctx.n2.value) while lower <= upper: ctx.parentCtx.targets.append(lower) lower += 1 def exitMasterGo(self, ctx: CommentMacroParser.MasterGoContext): """On exiting a Go macro.""" if ctx.target() is None: logging.info("Main GO") self.osc.button_press(ctx.device(), "/hog/hardware/maingo") return for i in ctx.target().targets: if isinstance(i, int) is not True: logging.error("GO MASTER macro targets must be intigers.") continue if i < 0: logging.error("Master %d is not greater than 0.", i) continue master = str(i) logging.info("GO on master %s", master) self.osc.button_press(ctx.device(), "/hog/hardware/go/" + master) def exitMasterGoto(self, ctx: CommentMacroParser.MasterGotoContext): """On exiting a GOTO macro.""" if ctx.target() is not None: logging.error("ERROR: limited to GOTO on current master only.") return logging.info("GOTO on current master.") cue = str(ctx.number().value) self.osc.button_press(ctx.device(), self.osc.buttonMap["goto"]) self.osc.number_entry(ctx.device(), cue) self.osc.button_press(ctx.device(), self.osc.buttonMap["enter"]) def exitMasterHalt(self, ctx: CommentMacroParser.MasterHaltContext): """On exiting a Master Halt macro.""" if ctx.target() is None: logging.info("Main HALT") self.osc.button_press(ctx.device(), "/hog/hardware/mainhalt") return for i in ctx.target().targets: if isinstance(i, int) is not True: logging.error("GO MASTER macro targets must be intigers.") continue if i < 0: logging.error("Master %d is not greater than 0.", i) continue master = str(i) logging.info("HALT on master %s", master) self.osc.button_press(ctx.device(), "/hog/hardware/pause/"+master) def exitMasterAssert(self, ctx: CommentMacroParser.MasterAssertContext): """On exiting a Master Assert macro.""" if ctx.target() is not None: logging.error("ERROR: limited to asserting current master only.") return logging.info("ASSERT on current master.") self.osc.button_press(ctx.device(), "/hog/hardware/assert") def exitMasterRelease(self, ctx: CommentMacroParser.MasterReleaseContext): """On exiting a Master Release macro.""" if ctx.target() is not None: logging.error("ERROR: limited to releasing current master only.") return logging.info("RELEASE on current master.") self.osc.button_press(ctx.device(), "/hog/hardware/release") def exitMasterFade(self, ctx: CommentMacroParser.MasterFadeContext): """On exiting a Master Fade macro.""" if ctx.target() is None: logging.error("ERROR: limited to fading specified masters only.") return level = ctx.number().value if (level < 0 or level > 100): logging.error("Level must be between 0 and 100.") return for i in ctx.target().targets: if isinstance(i, int) is not True: logging.error("FADE MASTER macro targets must be intigers.") continue if i < 0: logging.error("Master %d is not greater than 0.", i) continue master = str(i) logging.info("Fade Master %s to %d", master, level) level *= 255 / 100 # percent in Macro, 0>255 in OSC self.osc.send_message(ctx.device(), "/hog/hardware/fader/" + master, level) def exitFadeGrandMaster(self, ctx: CommentMacroParser.FadeGrandMasterContext): """On exiting a GM Fade Macro.""" level = ctx.number().value if (level < 0 or level > 100): logging.error("Level must be between 0 and 100.") return logging.info("Fading Grand Master to %d", level) level *= 255 / 100 # percent in Macro, 0>255 in OSC self.osc.send_message(ctx.device(), "/hog/hardware/fader/0", level) def exitMasterChoose(self, ctx: CommentMacroParser.MasterChooseContext): """On exiting a Master Choose macro.""" if ctx.number().value < 0: logging.error("Master must be greater than 0.") return master = str(ctx.number().value) logging.info("Choose Master %s", master) self.osc.button_press(ctx.device(), "/hog/hardware/choose/" + master) def exitReleaseAll(self, ctx: CommentMacroParser.ReleaseAllContext): """On exiting a Release All Macro.""" logging.info("Release All") self.osc.send_message(ctx.device(), "/hog/hardware/pig", self.osc.buttonDOWN) self.osc.button_press(ctx.device(), "/hog/hardware/release") self.osc.send_message(ctx.device(), "/hog/hardware/pig", self.osc.buttonUP) def exitListGo(self, ctx: CommentMacroParser.ListGoContext): """On exiting a List GO macro.""" for i in ctx.target().targets: logging.info("Go on List %d", i) self.osc.send_message(ctx.device(), "/hog/playback/go/0", i) def exitListGoto(self, ctx: CommentMacroParser.ListGotoContext): """On exiting a GOTO macro.""" for i in ctx.target().targets: cuelist = str(i) + "." + str(ctx.number().value) logging.info("Go on List %s", cuelist) self.osc.send_message(ctx.device(), "/hog/playback/go/0", list) def exitListHalt(self, ctx: CommentMacroParser.ListHaltContext): """On exiting a Halt macro.""" for i in ctx.target().targets: logging.info("Halting List %d", i) self.osc.send_message(ctx.device(), "/hog/playback/halt/0", i) def exitListRelese(self, ctx: CommentMacroParser.ListReleseContext): """On exiting a Release macro.""" for i in ctx.target().targets: logging.info("Releasing List %d", i) self.osc.send_message(ctx.device(), "/hog/playback/release/0", i) def exitSceneGo(self, ctx: CommentMacroParser.SceneGoContext): """On exiting a Scene GO macro.""" for i in ctx.target().targets: logging.info("Go on Scene %d", i) self.osc.send_message(ctx.device(), "/hog/playback/go/1", i) def exitSceneHalt(self, ctx: CommentMacroParser.SceneHaltContext): """On exiting a Scene Halt macro.""" for i in ctx.target().targets: logging.info("Halt Scene %d", i) self.osc.send_message(ctx.device(), "/hog/playback/halt/1", i) def exitSceneRelease(self, ctx: CommentMacroParser.SceneReleaseContext): """On exiting a Scene Release macro.""" for i in ctx.target().targets: logging.info("Release Scene %d", i) self.osc.send_message(ctx.device(), "/hog/playback/release/1", i) def exitMacroGo(self, ctx: CommentMacroParser.MacroGoContext): """On exiting a Macro GO macro.""" for i in ctx.target().targets: logging.info("Go on Macro %d", i) self.osc.send_message(ctx.device(), "/hog/playback/go/2", i) def exitMacroHalt(self, ctx: CommentMacroParser.MacroHaltContext): """On exiting a Macro Halt macro.""" for i in ctx.target().targets: logging.info("Pause Macro %d", i) self.osc.send_message(ctx.device(), "/hog/playback/halt/2", i) def exitMacroStop(self, ctx: CommentMacroParser.MacroStopContext): """On exiting a Macro Stop macro.""" for i in ctx.target().targets: logging.info("Stop Macro %d", i) self.osc.send_message(ctx.device(), "/hog/playback/release/2", i) def exitPageNext(self, ctx: CommentMacroParser.PageNextContext): """On exiting a Next Page macro.""" logging.info("Next Page") self.osc.button_press(ctx.device(), "/hog/hardware/nextpage") def exitPagePrev(self, ctx: CommentMacroParser.PagePrevContext): """On exiting a Previous Page macro.""" logging.info("Prev Page") self.osc.button_press(ctx.device(), "/hog/hardware/backpage") def exitSelectIntensity(self, ctx: CommentMacroParser.SelectIntensityContext): """On exiting a Select Intensity macro.""" if ctx.number().value < 0: logging.error("Pallet must be greater than 0.") return pallet = str(ctx.number().value) logging.info("Selecting intensity pallet %s", pallet) self.osc.button_press(ctx.device(), self.osc.buttonMap["intensity"]) self.osc.number_entry(ctx.device(), pallet) self.osc.button_press(ctx.device(), self.osc.buttonMap["enter"]) def exitSelectPosition(self, ctx: CommentMacroParser.SelectPositionContext): """On exiting a Select Intensity macro.""" if ctx.number().value < 0: logging.error("Pallet must be greater than 0.") return pallet = str(ctx.number().value) logging.info("Selecting position pallet %s", pallet) self.osc.button_press(ctx.device(), self.osc.buttonMap["position"]) self.osc.number_entry(ctx.device(), pallet) self.osc.button_press(ctx.device(), self.osc.buttonMap["enter"]) def exitSelectColour(self, ctx: CommentMacroParser.SelectColourContext): """On exiting a Select Intensity macro.""" if ctx.number().value < 0: logging.error("Pallet must be greater than 0.") return pallet = str(ctx.number().value) logging.info("Selecting colour pallet %s", pallet) self.osc.button_press(ctx.device(), self.osc.buttonMap["colour"]) self.osc.number_entry(ctx.device(), pallet) self.osc.button_press(ctx.device(), self.osc.buttonMap["enter"]) def exitSelectBeam(self, ctx: CommentMacroParser.SelectBeamContext): """On exiting a Select Intensity macro.""" if ctx.number().value < 0: logging.error("Pallet must be greater than 0.") return pallet = str(ctx.number().value) logging.info("Selecting beam pallet %s", pallet) self.osc.button_press(ctx.device(), self.osc.buttonMap["beam"]) self.osc.number_entry(ctx.device(), pallet) self.osc.button_press(ctx.device(), self.osc.buttonMap["enter"])