use ANTLR alternative labeling to refine parser logic
This commit is contained in:
parent
1fa50e0387
commit
8e7eb1b8f9
|
@ -39,37 +39,37 @@ statement : macro (':' macro)* NEWLINE?
|
||||||
;
|
;
|
||||||
|
|
||||||
macro
|
macro
|
||||||
: op='GM' ( t=target | '*' ) (dev=device)? // Go Master
|
: op='GM' ( t=target | '*' ) (dev=device)? #MasterGo
|
||||||
| op='GM' ( t=target | '*' ) '/' n=number (dev=device)? // Go Master
|
| op='GM' ( t=target | '*' ) '/' n=number (dev=device)? #MasterGoto
|
||||||
| op='HM' ( t=target | '*' ) (dev=device)? // Halt Master
|
| op='HM' ( t=target | '*' ) (dev=device)? #MasterHalt
|
||||||
| op='AM' ( t=target | '*' ) (dev=device)? // Assert Master
|
| op='AM' ( t=target | '*' ) (dev=device)? #MasterAssert
|
||||||
| op='RM' ( t=target | '*' ) (dev=device)? // Relesae Master
|
| op='RM' ( t=target | '*' ) (dev=device)? #MasterRelease
|
||||||
| op='RA' (dev=device)? // Release All
|
| op='RA' (dev=device)? #ReleaseAll
|
||||||
| op='RO' (dev=device)? // Release Others
|
| op='RO' (dev=device)? #ReleaseOthers
|
||||||
| op='FM' ( t=target | '*' ) '/' n=number (f=time)? (dev=device)? // Fade Master
|
| op='FM' ( t=target | '*' ) '/' n=number (f=time)? (dev=device)? #MasterFade
|
||||||
| op='FGM' n=number (f=time)? (dev=device)? // Fade Grand Master
|
| op='FGM' n=number (f=time)? (dev=device)? #FadeGrandMaster
|
||||||
| op='CM' n=number (dev=device)? // Choose Master
|
| op='CM' n=number (dev=device)? #MasterChoose
|
||||||
| op='GL' t=target (dev=device)? // Go List
|
| op='GL' t=target (dev=device)? #ListGo
|
||||||
| op='GL' t=target '/' n=number (dev=device)? // Go List
|
| op='GL' t=target '/' n=number (dev=device)? #ListGoto
|
||||||
| op='HL' t=target (dev=device)? // Halt List
|
| op='HL' t=target (dev=device)? #ListHalt
|
||||||
| op='AL' t=target (dev=device)? // Assert List
|
| op='AL' t=target (dev=device)? #ListAssert
|
||||||
| op='RL' t=target (dev=device)? // Release List
|
| op='RL' t=target (dev=device)? #ListRelese
|
||||||
| op='GB' t=target (dev=device)? // Go Batch
|
| op='GB' t=target (dev=device)? #BatchGo
|
||||||
| op='HB' t=target (dev=device)? // Halt Batch
|
| op='HB' t=target (dev=device)? #BatchHalt
|
||||||
| op='AB' t=target (dev=device)? // Assert Batch
|
| op='AB' t=target (dev=device)? #BatchAssert
|
||||||
| op='RB' t=target (dev=device)? // Release Batch
|
| op='RB' t=target (dev=device)? #BatchRelease
|
||||||
| op='GS' t=target (dev=device)? // Go Scene
|
| op='GS' t=target (dev=device)? #SceneGo
|
||||||
| op='HS' t=target (dev=device)? // Halt Scene
|
| op='HS' t=target (dev=device)? #SceneHalt
|
||||||
| op='AS' t=target (dev=device)? // Assert Scene
|
| op='AS' t=target (dev=device)? #SceneAssert
|
||||||
| op='RS' t=target (dev=device)? // Release Scene
|
| op='RS' t=target (dev=device)? #SceneRelease
|
||||||
| op='CP' n=number (dev=device)? // Change Page
|
| op='CP' n=number (dev=device)? #PageChange
|
||||||
| op='CP' d='+' (dev=device)? // Next Page
|
| op='CP' '+' (dev=device)? #PageNext
|
||||||
| op='CP' d='-' (dev=device)? // Prev Page
|
| op='CP' '-' (dev=device)? #PagePrev
|
||||||
| op='RV' n=number (dev=device)? // Recall View
|
| op='RV' n=number (dev=device)? #RecallView
|
||||||
| op='RN' dev=device // Reset Node
|
| op='RN' dev=device #NodeReset
|
||||||
| op='GK' t=target (dev=device)? // Go Keystroke Macro
|
| op='GK' t=target (dev=device)? #MacroGo
|
||||||
| op='HK' t=target (dev=device)? // Halt Keystroke Macro
|
| op='HK' t=target (dev=device)? #MacroHalt
|
||||||
| op='RK' t=target (dev=device)? // Stop Keystroke Macro
|
| op='RK' t=target (dev=device)? #MacroStop
|
||||||
;
|
;
|
||||||
|
|
||||||
time : TIME n=number ;
|
time : TIME n=number ;
|
||||||
|
|
|
@ -26,12 +26,282 @@ class CommentMacroListener(ParseTreeListener):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Enter a parse tree produced by CommentMacroParser#macro.
|
# Enter a parse tree produced by CommentMacroParser#MasterGo.
|
||||||
def enterMacro(self, ctx:CommentMacroParser.MacroContext):
|
def enterMasterGo(self, ctx:CommentMacroParser.MasterGoContext):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Exit a parse tree produced by CommentMacroParser#macro.
|
# Exit a parse tree produced by CommentMacroParser#MasterGo.
|
||||||
def exitMacro(self, ctx:CommentMacroParser.MacroContext):
|
def exitMasterGo(self, ctx:CommentMacroParser.MasterGoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#MasterGoto.
|
||||||
|
def enterMasterGoto(self, ctx:CommentMacroParser.MasterGotoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#MasterGoto.
|
||||||
|
def exitMasterGoto(self, ctx:CommentMacroParser.MasterGotoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#MasterHalt.
|
||||||
|
def enterMasterHalt(self, ctx:CommentMacroParser.MasterHaltContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#MasterHalt.
|
||||||
|
def exitMasterHalt(self, ctx:CommentMacroParser.MasterHaltContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#MasterAssert.
|
||||||
|
def enterMasterAssert(self, ctx:CommentMacroParser.MasterAssertContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#MasterAssert.
|
||||||
|
def exitMasterAssert(self, ctx:CommentMacroParser.MasterAssertContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#MasterRelease.
|
||||||
|
def enterMasterRelease(self, ctx:CommentMacroParser.MasterReleaseContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#MasterRelease.
|
||||||
|
def exitMasterRelease(self, ctx:CommentMacroParser.MasterReleaseContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#ReleaseAll.
|
||||||
|
def enterReleaseAll(self, ctx:CommentMacroParser.ReleaseAllContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#ReleaseAll.
|
||||||
|
def exitReleaseAll(self, ctx:CommentMacroParser.ReleaseAllContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#ReleaseOthers.
|
||||||
|
def enterReleaseOthers(self, ctx:CommentMacroParser.ReleaseOthersContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#ReleaseOthers.
|
||||||
|
def exitReleaseOthers(self, ctx:CommentMacroParser.ReleaseOthersContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#MasterFade.
|
||||||
|
def enterMasterFade(self, ctx:CommentMacroParser.MasterFadeContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#MasterFade.
|
||||||
|
def exitMasterFade(self, ctx:CommentMacroParser.MasterFadeContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#FadeGrandMaster.
|
||||||
|
def enterFadeGrandMaster(self, ctx:CommentMacroParser.FadeGrandMasterContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#FadeGrandMaster.
|
||||||
|
def exitFadeGrandMaster(self, ctx:CommentMacroParser.FadeGrandMasterContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#MasterChoose.
|
||||||
|
def enterMasterChoose(self, ctx:CommentMacroParser.MasterChooseContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#MasterChoose.
|
||||||
|
def exitMasterChoose(self, ctx:CommentMacroParser.MasterChooseContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#ListGo.
|
||||||
|
def enterListGo(self, ctx:CommentMacroParser.ListGoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#ListGo.
|
||||||
|
def exitListGo(self, ctx:CommentMacroParser.ListGoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#ListGoto.
|
||||||
|
def enterListGoto(self, ctx:CommentMacroParser.ListGotoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#ListGoto.
|
||||||
|
def exitListGoto(self, ctx:CommentMacroParser.ListGotoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#ListHalt.
|
||||||
|
def enterListHalt(self, ctx:CommentMacroParser.ListHaltContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#ListHalt.
|
||||||
|
def exitListHalt(self, ctx:CommentMacroParser.ListHaltContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#ListAssert.
|
||||||
|
def enterListAssert(self, ctx:CommentMacroParser.ListAssertContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#ListAssert.
|
||||||
|
def exitListAssert(self, ctx:CommentMacroParser.ListAssertContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#ListRelese.
|
||||||
|
def enterListRelese(self, ctx:CommentMacroParser.ListReleseContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#ListRelese.
|
||||||
|
def exitListRelese(self, ctx:CommentMacroParser.ListReleseContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#BatchGo.
|
||||||
|
def enterBatchGo(self, ctx:CommentMacroParser.BatchGoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#BatchGo.
|
||||||
|
def exitBatchGo(self, ctx:CommentMacroParser.BatchGoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#BatchHalt.
|
||||||
|
def enterBatchHalt(self, ctx:CommentMacroParser.BatchHaltContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#BatchHalt.
|
||||||
|
def exitBatchHalt(self, ctx:CommentMacroParser.BatchHaltContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#BatchAssert.
|
||||||
|
def enterBatchAssert(self, ctx:CommentMacroParser.BatchAssertContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#BatchAssert.
|
||||||
|
def exitBatchAssert(self, ctx:CommentMacroParser.BatchAssertContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#BatchRelease.
|
||||||
|
def enterBatchRelease(self, ctx:CommentMacroParser.BatchReleaseContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#BatchRelease.
|
||||||
|
def exitBatchRelease(self, ctx:CommentMacroParser.BatchReleaseContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#SceneGo.
|
||||||
|
def enterSceneGo(self, ctx:CommentMacroParser.SceneGoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#SceneGo.
|
||||||
|
def exitSceneGo(self, ctx:CommentMacroParser.SceneGoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#SceneHalt.
|
||||||
|
def enterSceneHalt(self, ctx:CommentMacroParser.SceneHaltContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#SceneHalt.
|
||||||
|
def exitSceneHalt(self, ctx:CommentMacroParser.SceneHaltContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#SceneAssert.
|
||||||
|
def enterSceneAssert(self, ctx:CommentMacroParser.SceneAssertContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#SceneAssert.
|
||||||
|
def exitSceneAssert(self, ctx:CommentMacroParser.SceneAssertContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#SceneRelease.
|
||||||
|
def enterSceneRelease(self, ctx:CommentMacroParser.SceneReleaseContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#SceneRelease.
|
||||||
|
def exitSceneRelease(self, ctx:CommentMacroParser.SceneReleaseContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#PageChange.
|
||||||
|
def enterPageChange(self, ctx:CommentMacroParser.PageChangeContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#PageChange.
|
||||||
|
def exitPageChange(self, ctx:CommentMacroParser.PageChangeContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#PageNext.
|
||||||
|
def enterPageNext(self, ctx:CommentMacroParser.PageNextContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#PageNext.
|
||||||
|
def exitPageNext(self, ctx:CommentMacroParser.PageNextContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#PagePrev.
|
||||||
|
def enterPagePrev(self, ctx:CommentMacroParser.PagePrevContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#PagePrev.
|
||||||
|
def exitPagePrev(self, ctx:CommentMacroParser.PagePrevContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#RecallView.
|
||||||
|
def enterRecallView(self, ctx:CommentMacroParser.RecallViewContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#RecallView.
|
||||||
|
def exitRecallView(self, ctx:CommentMacroParser.RecallViewContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#NodeReset.
|
||||||
|
def enterNodeReset(self, ctx:CommentMacroParser.NodeResetContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#NodeReset.
|
||||||
|
def exitNodeReset(self, ctx:CommentMacroParser.NodeResetContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#MacroGo.
|
||||||
|
def enterMacroGo(self, ctx:CommentMacroParser.MacroGoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#MacroGo.
|
||||||
|
def exitMacroGo(self, ctx:CommentMacroParser.MacroGoContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#MacroHalt.
|
||||||
|
def enterMacroHalt(self, ctx:CommentMacroParser.MacroHaltContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#MacroHalt.
|
||||||
|
def exitMacroHalt(self, ctx:CommentMacroParser.MacroHaltContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Enter a parse tree produced by CommentMacroParser#MacroStop.
|
||||||
|
def enterMacroStop(self, ctx:CommentMacroParser.MacroStopContext):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exit a parse tree produced by CommentMacroParser#MacroStop.
|
||||||
|
def exitMacroStop(self, ctx:CommentMacroParser.MacroStopContext):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,7 +16,6 @@ __status__ = "Prototype"
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import OscMacroDefinitions
|
|
||||||
from CommentMacroParser import CommentMacroParser
|
from CommentMacroParser import CommentMacroParser
|
||||||
from CommentMacroListener import CommentMacroListener
|
from CommentMacroListener import CommentMacroListener
|
||||||
|
|
||||||
|
@ -44,31 +43,60 @@ def beautify_lisp_string(in_string):
|
||||||
return out_string
|
return out_string
|
||||||
|
|
||||||
|
|
||||||
|
class HogDevice():
|
||||||
|
# button state constants
|
||||||
|
buttonDOWN = 1
|
||||||
|
buttonUP = 0
|
||||||
|
|
||||||
|
def __init__(self, servers):
|
||||||
|
self.servers = servers
|
||||||
|
|
||||||
|
def button_press(self, device, path, delay=0.05):
|
||||||
|
self.send_message(device, path, HogDevice.buttonDOWN) # button down
|
||||||
|
sleep(delay)
|
||||||
|
self.send_message(device, path, HogDevice.buttonUP) # button up
|
||||||
|
|
||||||
|
# utility function to send simple messages with one argument
|
||||||
|
def send_message(self, device, path, arg):
|
||||||
|
msg = osc_message_builder.OscMessageBuilder(address=path)
|
||||||
|
msg.add_arg(arg)
|
||||||
|
self.send(device, msg.build())
|
||||||
|
|
||||||
|
# send python-osc messages
|
||||||
|
def send(self, device, msg):
|
||||||
|
if device is None:
|
||||||
|
osc = list(self.servers.values())[0]
|
||||||
|
else:
|
||||||
|
if (device.ntype.getText().lower() != 'h'):
|
||||||
|
logger.error("ERROR: Only Hog type devices are supported.")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
osc = self.servers[device.n.value]
|
||||||
|
except KeyError:
|
||||||
|
logger.error("ERROR: Net# " + str(device.n.value) +
|
||||||
|
" not found.")
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
osc.send(msg)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
|
||||||
|
|
||||||
class OscCommentMacroListener(CommentMacroListener):
|
class OscCommentMacroListener(CommentMacroListener):
|
||||||
def __init__(self, servers):
|
def __init__(self, servers):
|
||||||
self.osc = OscMacroDefinitions.HogDevice(servers)
|
self.osc = OscMacroDefinitions.HogDevice(servers)
|
||||||
|
|
||||||
def exitMacro(self, ctx: CommentMacroParser.MacroContext):
|
def enterStatement(self, ctx: CommentMacroParser.StatementContext):
|
||||||
# print the lisp tree of this macro
|
# print the lisp tree of this macro
|
||||||
lisp_tree_str = ctx.toStringTree(recog=ctx.parser)
|
lisp_tree_str = ctx.toStringTree(recog=ctx.parser)
|
||||||
logger.info(beautify_lisp_string(lisp_tree_str))
|
logger.info(beautify_lisp_string(lisp_tree_str))
|
||||||
|
|
||||||
# disallow duplicate targets
|
|
||||||
if ctx.t is not None:
|
|
||||||
ctx.t.targets = set(ctx.t.targets)
|
|
||||||
|
|
||||||
# execute macro from name
|
|
||||||
name = ctx.op.text
|
|
||||||
try:
|
|
||||||
self.osc.command[name](self, ctx)
|
|
||||||
except KeyError:
|
|
||||||
print(name + " macro is not compatable with OSC.")
|
|
||||||
logger.debug("Exiting Macro")
|
|
||||||
|
|
||||||
def enterTarget(self, ctx: CommentMacroParser.TargetContext):
|
def enterTarget(self, ctx: CommentMacroParser.TargetContext):
|
||||||
ctx.targets = []
|
ctx.targets = []
|
||||||
|
|
||||||
def exitTarget(self, ctx: CommentMacroParser.TargetContext):
|
def exitTarget(self, ctx: CommentMacroParser.TargetContext):
|
||||||
|
ctx.targets = set(ctx.targets)
|
||||||
if isinstance(ctx.parentCtx, CommentMacroParser.TargetContext):
|
if isinstance(ctx.parentCtx, CommentMacroParser.TargetContext):
|
||||||
ctx.parentCtx.targets.extend(ctx.targets) # add to parent targets
|
ctx.parentCtx.targets.extend(ctx.targets) # add to parent targets
|
||||||
|
|
||||||
|
@ -77,7 +105,6 @@ class OscCommentMacroListener(CommentMacroListener):
|
||||||
ctx.value = int(ctx.getText())
|
ctx.value = int(ctx.getText())
|
||||||
except ValueError:
|
except ValueError:
|
||||||
ctx.value = float(ctx.getText())
|
ctx.value = float(ctx.getText())
|
||||||
|
|
||||||
if isinstance(ctx.parentCtx, CommentMacroParser.TargetContext):
|
if isinstance(ctx.parentCtx, CommentMacroParser.TargetContext):
|
||||||
ctx.parentCtx.targets.append(ctx.value)
|
ctx.parentCtx.targets.append(ctx.value)
|
||||||
|
|
||||||
|
@ -91,3 +118,157 @@ class OscCommentMacroListener(CommentMacroListener):
|
||||||
ctx.parentCtx.targets.append(i)
|
ctx.parentCtx.targets.append(i)
|
||||||
else:
|
else:
|
||||||
logger.error("ERROR: Spans must be ranged with intigers.")
|
logger.error("ERROR: Spans must be ranged with intigers.")
|
||||||
|
|
||||||
|
def exitMasterGo(self, ctx: CommentMacroParser.MasterGoContext):
|
||||||
|
if ctx.t is None:
|
||||||
|
logger.info("Main GO")
|
||||||
|
self.osc.button_press(ctx.dev, "/hog/hardware/maingo")
|
||||||
|
return
|
||||||
|
for i in ctx.t.targets:
|
||||||
|
if isinstance(i, int) is not True:
|
||||||
|
logger.warn("GO MASTER macro targets must be intigers. "
|
||||||
|
+ str(i) + " is not an intigers.")
|
||||||
|
continue
|
||||||
|
if (i < 0):
|
||||||
|
logger.warn("Master "+str(i)+" is not greater than 0.")
|
||||||
|
continue
|
||||||
|
master = str(i)
|
||||||
|
logger.info("GO on master " + master)
|
||||||
|
self.osc.button_press(ctx.dev, "/hog/hardware/go/" + master)
|
||||||
|
|
||||||
|
def exitMasterHalt(self, ctx: CommentMacroParser.MasterHaltContext):
|
||||||
|
if ctx.t is None:
|
||||||
|
logger.info("Main HALT")
|
||||||
|
self.osc.button_press(ctx.dev, "/hog/hardware/mainhalt")
|
||||||
|
return
|
||||||
|
for i in ctx.t.targets:
|
||||||
|
if isinstance(i, int) is not True:
|
||||||
|
logger.warn("GO MASTER macro targets must be intigers. "
|
||||||
|
+ str(i) + " is not an intigers.")
|
||||||
|
continue
|
||||||
|
if (i < 0):
|
||||||
|
logger.warn("Master "+str(i)+" is not greater than 0.")
|
||||||
|
continue
|
||||||
|
master = str(i)
|
||||||
|
logger.info("HALT on master " + master)
|
||||||
|
self.osc.button_press(ctx.dev, "/hog/hardware/pause/" + master)
|
||||||
|
|
||||||
|
def exitMasterAssert(self, ctx: CommentMacroParser.MasterAssertContext):
|
||||||
|
if ctx.t is None:
|
||||||
|
logger.error("ERROR: limited to asserting current master only.")
|
||||||
|
return
|
||||||
|
logger.info("ASSERT on current master.")
|
||||||
|
self.osc.button_press(ctx.dev, "/hog/hardware/assert")
|
||||||
|
|
||||||
|
def exitMasterRelease(self, ctx: CommentMacroParser.MasterReleaseContext):
|
||||||
|
if ctx.t is None:
|
||||||
|
logger.error("ERROR: limited to releasing current master only.")
|
||||||
|
return
|
||||||
|
logger.info("RELEASE on current master.")
|
||||||
|
self.osc.button_press(ctx.dev, "/hog/hardware/release")
|
||||||
|
|
||||||
|
def exitMasterFade(self, ctx: CommentMacroParser.MasterFadeContext):
|
||||||
|
if ctx.t is None:
|
||||||
|
logger.error("ERROR: limited to fading current master only.")
|
||||||
|
return
|
||||||
|
level = ctx.n.value
|
||||||
|
if (level < 0 or level > 100):
|
||||||
|
logger.error("Level must be between 0 and 100.")
|
||||||
|
return
|
||||||
|
for i in ctx.t.targets:
|
||||||
|
if isinstance(i, int) is not True:
|
||||||
|
logger.warn("FADE MASTER macro targets must be intigers. "
|
||||||
|
+ str(i) + " is not an intigers.")
|
||||||
|
continue
|
||||||
|
if (i < 0):
|
||||||
|
logger.warn("Master "+str(i)+" is not greater than 0.")
|
||||||
|
continue
|
||||||
|
master = str(i)
|
||||||
|
logger.info("Fade Master "+master+" to "+str(level)+"%")
|
||||||
|
level *= 255 / 100 # percent in Macro, 0>255 in OSC
|
||||||
|
self.osc.send_message(ctx.dev,
|
||||||
|
"/hog/hardware/fader/" + master,
|
||||||
|
level)
|
||||||
|
|
||||||
|
def exitFadeGrandMaster(self,
|
||||||
|
ctx: CommentMacroParser.FadeGrandMasterContext):
|
||||||
|
level = ctx.n.value
|
||||||
|
if (level < 0 or level > 100):
|
||||||
|
logger.error("Level must be between 0 and 100.")
|
||||||
|
return
|
||||||
|
logger.info("Fading Grand Master to " + str(level) + "%")
|
||||||
|
level *= 255 / 100 # percent in Macro, 0>255 in OSC
|
||||||
|
self.osc.send_message(ctx.dev, "/hog/hardware/fader/0", level)
|
||||||
|
|
||||||
|
def exitMasterChoose(self, ctx: CommentMacroParser.MasterChooseContext):
|
||||||
|
if (ctx.n.value < 0):
|
||||||
|
logger.error("Master must be greater than 0.")
|
||||||
|
return
|
||||||
|
master = str(ctx.n.value)
|
||||||
|
logger.info("Choose Master " + master)
|
||||||
|
self.osc.button_press(ctx.dev, "/hog/hardware/choose/" + master)
|
||||||
|
|
||||||
|
def exitReleaseAll(self, ctx: CommentMacroParser.ReleaseAllContext):
|
||||||
|
logger.info("Release All")
|
||||||
|
self.osc.send_message(ctx.dev, "/hog/hardware/pig",
|
||||||
|
self.osc.buttonDOWN)
|
||||||
|
self.osc.button_press(ctx.dev, "/hog/hardware/release")
|
||||||
|
self.osc.send_message(ctx.dev, "/hog/hardware/pig",
|
||||||
|
self.osc.buttonUP)
|
||||||
|
|
||||||
|
def exitListGo(self, ctx: CommentMacroParser.ListGoContext):
|
||||||
|
for i in ctx.t.targets:
|
||||||
|
if ctx.n is not None:
|
||||||
|
list = str(i) + "." + str(ctx.n.value)
|
||||||
|
else:
|
||||||
|
list = i
|
||||||
|
logger.info("Go on List " + str(list))
|
||||||
|
self.osc.send_message(ctx.dev, "/hog/playback/go/0", list)
|
||||||
|
|
||||||
|
def exitListHalt(self, ctx: CommentMacroParser.ListHaltContext):
|
||||||
|
for i in ctx.t.targets:
|
||||||
|
logger.info("Halting List " + str(i))
|
||||||
|
self.osc.send_message(ctx.dev, "/hog/playback/halt/0", i)
|
||||||
|
|
||||||
|
def exitListRelese(self, ctx: CommentMacroParser.ListReleseContext):
|
||||||
|
for i in ctx.t.targets:
|
||||||
|
logger.info("Releasing List " + str(i))
|
||||||
|
self.osc.send_message(ctx.dev, "/hog/playback/release/0", i)
|
||||||
|
|
||||||
|
def exitSceneGo(self, ctx: CommentMacroParser.SceneGoContext):
|
||||||
|
for i in ctx.t.targets:
|
||||||
|
logger.info("Go on Scene " + str(i))
|
||||||
|
self.osc.send_message(ctx.dev, "/hog/playback/go/1", i)
|
||||||
|
|
||||||
|
def exitSceneHalt(self, ctx: CommentMacroParser.SceneHaltContext):
|
||||||
|
for i in ctx.t.targets:
|
||||||
|
logger.info("Halt Scene " + str(i))
|
||||||
|
self.osc.send_message(ctx.dev, "/hog/playback/halt/1", i)
|
||||||
|
|
||||||
|
def exitSceneRelease(self, ctx: CommentMacroParser.SceneReleaseContext):
|
||||||
|
for i in ctx.t.targets:
|
||||||
|
logger.info("Release Scene " + str(i))
|
||||||
|
self.osc.send_message(ctx.dev, "/hog/playback/release/1", i)
|
||||||
|
|
||||||
|
def exitMacroGo(self, ctx: CommentMacroParser.MacroGoContext):
|
||||||
|
for i in ctx.t.targets:
|
||||||
|
logger.info("Go on Macro " + str(i))
|
||||||
|
self.osc.send_message(ctx.dev, "/hog/playback/go/2", i)
|
||||||
|
|
||||||
|
def exitMacroHalt(self, ctx: CommentMacroParser.MacroHaltContext):
|
||||||
|
for i in ctx.t.targets:
|
||||||
|
logger.info("Pause Macro " + str(i))
|
||||||
|
self.osc.send_message(ctx.dev, "/hog/playback/halt/2", i)
|
||||||
|
|
||||||
|
def exitMacroStop(self, ctx: CommentMacroParser.MacroStopContext):
|
||||||
|
for i in ctx.t.targets:
|
||||||
|
logger.info("Stop Macro " + str(i))
|
||||||
|
self.osc.send_message(ctx.dev, "/hog/playback/release/2", i)
|
||||||
|
|
||||||
|
def exitPageNext(self, ctx: CommentMacroParser.PageNextContext):
|
||||||
|
logger.info("Next Page")
|
||||||
|
self.osc.button_press(ctx.dev, "/hog/hardware/nextpage")
|
||||||
|
|
||||||
|
def exitPagePrev(self, ctx: CommentMacroParser.PagePrevContext):
|
||||||
|
logger.info("Prev Page")
|
||||||
|
self.osc.button_press(ctx.dev, "/hog/hardware/backpage")
|
||||||
|
|
|
@ -1,246 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""OscMacroDefinitions.py: Hog 4 comment macros in OSC for Python3."""
|
|
||||||
|
|
||||||
__author__ = "Kevin Matz"
|
|
||||||
__copyright__ = "Copyright 2018, Company 235, LLC"
|
|
||||||
__credits__ = ["Kevin Matz"]
|
|
||||||
|
|
||||||
__license__ = "MIT"
|
|
||||||
__version__ = "3.9"
|
|
||||||
__maintainer__ = "Kevin Matz"
|
|
||||||
__email__ = "kevin@company235.com"
|
|
||||||
|
|
||||||
__status__ = "Prototype"
|
|
||||||
|
|
||||||
import logging
|
|
||||||
from pythonosc import udp_client
|
|
||||||
from pythonosc import osc_message_builder
|
|
||||||
from pythonosc import osc_bundle_builder
|
|
||||||
from time import sleep
|
|
||||||
|
|
||||||
logger = logging.getLogger("CommentMacro")
|
|
||||||
|
|
||||||
|
|
||||||
class HogDevice():
|
|
||||||
# button state constants
|
|
||||||
buttonDOWN = 1
|
|
||||||
buttonUP = 0
|
|
||||||
|
|
||||||
def __init__(self, servers):
|
|
||||||
self.servers = servers
|
|
||||||
|
|
||||||
def button_press(self, device, path, delay=0.05):
|
|
||||||
self.send_message(device, path, HogDevice.buttonDOWN) # button down
|
|
||||||
sleep(delay)
|
|
||||||
self.send_message(device, path, HogDevice.buttonUP) # button up
|
|
||||||
|
|
||||||
# utility function to send simple messages with one argument
|
|
||||||
def send_message(self, device, path, arg):
|
|
||||||
msg = osc_message_builder.OscMessageBuilder(address=path)
|
|
||||||
msg.add_arg(arg)
|
|
||||||
self.send(device, msg.build())
|
|
||||||
|
|
||||||
# send python-osc messages
|
|
||||||
def send(self, device, msg):
|
|
||||||
if device is None:
|
|
||||||
osc = list(self.servers.values())[0]
|
|
||||||
else:
|
|
||||||
if (device.ntype.getText().lower() != 'h'):
|
|
||||||
logger.error("ERROR: Only Hog type devices are supported.")
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
osc = self.servers[device.n.value]
|
|
||||||
except KeyError:
|
|
||||||
logger.error("ERROR: Net# " + str(device.n.value) +
|
|
||||||
" not found.")
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
osc.send(msg)
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(e)
|
|
||||||
|
|
||||||
def _master_go(self, ctx):
|
|
||||||
if ctx.n is not None:
|
|
||||||
logger.warn("GO MASTER doesn't support goto. " +
|
|
||||||
"Cue number "+str(ctx.n.value)+" is ignored.")
|
|
||||||
if ctx.t is None:
|
|
||||||
logger.info("Main GO")
|
|
||||||
self.osc.button_press(ctx.dev, "/hog/hardware/maingo")
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
for i in ctx.t.targets:
|
|
||||||
if isinstance(i, int) is not True:
|
|
||||||
logger.warn("GO MASTER macro targets must be intigers. "
|
|
||||||
+ str(i) + " is not an intigers.")
|
|
||||||
continue
|
|
||||||
if (i < 0):
|
|
||||||
logger.warn("Master "+str(i)+" is not greater than 0.")
|
|
||||||
continue
|
|
||||||
master = str(i)
|
|
||||||
logger.info("GO on master " + master)
|
|
||||||
self.osc.button_press(ctx.dev, "/hog/hardware/go/" + master)
|
|
||||||
|
|
||||||
def _master_halt(self, ctx):
|
|
||||||
if ctx.t is None:
|
|
||||||
logger.info("Main HALT")
|
|
||||||
self.osc.button_press(ctx.dev, "/hog/hardware/mainhalt")
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
for i in ctx.t.targets:
|
|
||||||
if isinstance(i, int) is not True:
|
|
||||||
logger.warn("GO MASTER macro targets must be intigers. "
|
|
||||||
+ str(i) + " is not an intigers.")
|
|
||||||
continue
|
|
||||||
if (i < 0):
|
|
||||||
logger.warn("Master "+str(i)+" is not greater than 0.")
|
|
||||||
continue
|
|
||||||
master = str(i)
|
|
||||||
logger.info("HALT on master " + master)
|
|
||||||
self.osc.button_press(ctx.dev,
|
|
||||||
"/hog/hardware/pause/" + master)
|
|
||||||
|
|
||||||
def _master_assert(self, ctx):
|
|
||||||
if ctx.t is None:
|
|
||||||
logger.error("ERROR: limited to asserting current master only.")
|
|
||||||
return
|
|
||||||
logger.info("ASSERT on current master.")
|
|
||||||
self.osc.button_press(ctx.dev, "/hog/hardware/assert")
|
|
||||||
|
|
||||||
def _master_release(self, ctx):
|
|
||||||
if ctx.t is None:
|
|
||||||
logger.error("ERROR: limited to releasing current master only.")
|
|
||||||
return
|
|
||||||
logger.info("RELEASE on current master.")
|
|
||||||
self.osc.button_press(ctx.dev, "/hog/hardware/release")
|
|
||||||
|
|
||||||
def _master_fade(self, ctx):
|
|
||||||
level = ctx.n.value
|
|
||||||
if (level < 0 or level > 100):
|
|
||||||
logger.error("Level must be between 0 and 100.")
|
|
||||||
return
|
|
||||||
if (len(ctx.master.targets) == 0):
|
|
||||||
logger.error("MASTER FADE doesn't support * current master.")
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
for i in ctx.t.targets:
|
|
||||||
if isinstance(i, int) is not True:
|
|
||||||
logger.warn("FADE MASTER macro targets must be intigers. "
|
|
||||||
+ str(i) + " is not an intigers.")
|
|
||||||
continue
|
|
||||||
if (i < 0):
|
|
||||||
logger.warn("Master "+str(i)+" is not greater than 0.")
|
|
||||||
continue
|
|
||||||
master = str(i)
|
|
||||||
logger.info("Fade Master "+master+" to "+str(level)+"%")
|
|
||||||
level *= 255 / 100 # percent in Macro, 0>255 in OSC
|
|
||||||
self.osc.send_message(ctx.dev,
|
|
||||||
"/hog/hardware/fader/" + master,
|
|
||||||
level)
|
|
||||||
|
|
||||||
def _master_fade_grand(self, ctx):
|
|
||||||
level = ctx.n.value
|
|
||||||
if (level < 0 or level > 100):
|
|
||||||
logger.error("Level must be between 0 and 100.")
|
|
||||||
return
|
|
||||||
logger.info("Fading Grand Master to " + str(level) + "%")
|
|
||||||
level *= 255 / 100 # percent in Macro, 0>255 in OSC
|
|
||||||
self.osc.send_message(ctx.dev, "/hog/hardware/fader/0", level)
|
|
||||||
|
|
||||||
def _master_choose(self, ctx):
|
|
||||||
if (ctx.n.value < 0):
|
|
||||||
logger.error("Master must be greater than 0.")
|
|
||||||
return
|
|
||||||
master = str(ctx.n.value)
|
|
||||||
logger.info("Choose Master " + master)
|
|
||||||
self.osc.button_press(ctx.dev, "/hog/hardware/choose/" + master)
|
|
||||||
|
|
||||||
def _release_all(self, ctx):
|
|
||||||
logger.info("Release All")
|
|
||||||
self.osc.send_message(ctx.dev, "/hog/hardware/pig",
|
|
||||||
HogDevice.buttonDOWN)
|
|
||||||
self.osc.button_press(ctx.dev, "/hog/hardware/release")
|
|
||||||
self.osc.send_message(ctx.dev, "/hog/hardware/pig",
|
|
||||||
HogDevice.buttonUP)
|
|
||||||
|
|
||||||
def _list_go(self, ctx):
|
|
||||||
for i in ctx.t.targets:
|
|
||||||
if ctx.n is not None:
|
|
||||||
list = str(i) + "." + str(ctx.n.value)
|
|
||||||
else:
|
|
||||||
list = i
|
|
||||||
logger.info("Go on List " + str(list))
|
|
||||||
self.osc.send_message(ctx.dev, "/hog/playback/go/0", list)
|
|
||||||
|
|
||||||
def _list_halt(self, ctx):
|
|
||||||
for i in ctx.t.targets:
|
|
||||||
logger.info("Halting List " + str(i))
|
|
||||||
self.osc.send_message(ctx.dev, "/hog/playback/halt/0", i)
|
|
||||||
|
|
||||||
def _list_release(self, ctx):
|
|
||||||
for i in ctx.t.targets:
|
|
||||||
logger.info("Releasing List " + str(i))
|
|
||||||
self.osc.send_message(ctx.dev, "/hog/playback/release/0", i)
|
|
||||||
|
|
||||||
def _scene_go(self, ctx):
|
|
||||||
for i in ctx.t.targets:
|
|
||||||
logger.info("Go on Scene " + str(i))
|
|
||||||
self.osc.send_message(ctx.dev, "/hog/playback/go/1", i)
|
|
||||||
|
|
||||||
def _scene_halt(self, ctx):
|
|
||||||
for i in ctx.t.targets:
|
|
||||||
logger.info("Halt Scene " + str(i))
|
|
||||||
self.osc.send_message(ctx.dev, "/hog/playback/halt/1", i)
|
|
||||||
|
|
||||||
def _scene_release(self, ctx):
|
|
||||||
for i in ctx.t.targets:
|
|
||||||
logger.info("Release Scene " + str(i))
|
|
||||||
self.osc.send_message(ctx.dev, "/hog/playback/release/1", i)
|
|
||||||
|
|
||||||
def _macro_go(self, ctx):
|
|
||||||
for i in ctx.t.targets:
|
|
||||||
logger.info("Go on Macro " + str(i))
|
|
||||||
self.osc.send_message(ctx.dev, "/hog/playback/go/2", i)
|
|
||||||
|
|
||||||
def _macro_halt(self, ctx):
|
|
||||||
for i in ctx.t.targets:
|
|
||||||
logger.info("Pause Macro " + str(i))
|
|
||||||
self.osc.send_message(ctx.dev, "/hog/playback/halt/2", i)
|
|
||||||
|
|
||||||
def _macro_release(self, ctx):
|
|
||||||
for i in ctx.t.targets:
|
|
||||||
logger.info("Stop Macro " + str(i))
|
|
||||||
self.osc.send_message(ctx.dev, "/hog/playback/release/2", i)
|
|
||||||
|
|
||||||
def _page_change(self, ctx):
|
|
||||||
if ctx.d is None:
|
|
||||||
logger.error("ERROR: changing page by number is unsupported.")
|
|
||||||
return
|
|
||||||
if ctx.d.text == '+':
|
|
||||||
logger.info("Next Page")
|
|
||||||
self.osc.button_press(ctx.dev, "/hog/hardware/nextpage")
|
|
||||||
elif ctx.d.text == '-':
|
|
||||||
logger.info("Previous Page")
|
|
||||||
self.osc.button_press(ctx.dev, "/hog/hardware/backpage")
|
|
||||||
|
|
||||||
command = {"GM": _master_go,
|
|
||||||
"HM": _master_halt,
|
|
||||||
"AM": _master_assert,
|
|
||||||
"RM": _master_release,
|
|
||||||
"FM": _master_fade,
|
|
||||||
"FGM": _master_fade_grand,
|
|
||||||
"CM": _master_choose,
|
|
||||||
"RA": _release_all,
|
|
||||||
"GL": _list_go,
|
|
||||||
"HL": _list_halt,
|
|
||||||
"RL": _list_release,
|
|
||||||
"GS": _scene_go,
|
|
||||||
"HS": _scene_halt,
|
|
||||||
"RS": _scene_release,
|
|
||||||
"GK": _macro_go,
|
|
||||||
"HK": _macro_halt,
|
|
||||||
"RK": _macro_release,
|
|
||||||
"CP": _page_change
|
|
||||||
}
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
A theoretical exercise to control a Hog 4 via OSC, with comment macros.
|
A theoretical exercise to control a Hog 4 via OSC, with comment macros.
|
||||||
|
|
||||||
The comment macro grammar described in `CommentMacro.g4` is based upon the Hog 3.9 manual, Chapter 22.4. The python3 implementation in `OscMacroDefinitions.py` is based on Chapter 24.2 in the same manual.
|
The comment macro grammar described in `CommentMacro.g4` is based upon the Hog 3.9 manual, Chapter 22.4. The python3 implementation in `OscCommentMacroListener.py` is based on Chapter 24.2 in the same manual.
|
||||||
|
|
||||||
Some macros are unsupported/unsupportable with this method. Some macro features, like timing, are not yet implemented. Refer to the **Features** table for specific notes.
|
Some macros are unsupported/unsupportable with this method. Some macro features, like timing, are not yet implemented. Refer to the **Features** table for specific notes.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue