1
0
Fork 0
baconscript/OscCommentMacroListener.py

153 lines
5.1 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""OscCommentMacroListener.py: Hog 4 comment macro antlr4 listener for OSC."""
__author__ = "Kevin Matz"
__copyright__ = "Copyright 2018, Company 235, LLC"
__credits__ = ["Kevin Matz"]
__license__ = "MIT"
__version__ = "0.0.1"
__maintainer__ = "Kevin Matz"
__email__ = "kevin@company235.com"
__status__ = "Prototype"
import antlr4
from CommentMacroParser import CommentMacroParser
from CommentMacroListener import CommentMacroListener
from OscMacroDefinitions import *
from pythonosc import osc_message_builder
from pythonosc import udp_client
from time import sleep
def num(string):
try:
num = int(string)
return num
except ValueError:
num = float(string)
return num
# https://raw.githubusercontent.com/jszheng/py3antlr4book/master/bin/pygrun
# this is a python version of TestRig
def beautify_lisp_string(in_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):
def __init__(self, parser, server):
self.parser = parser
self.server = server
def button_press(self, device, path, delay=0.05):
self.send_message(device, path, 1) # button down
sleep(delay)
self.send_message(device, path, 0) # button up
def send_message(self, device, path, arg):
if device is None:
osc = list(self.server.values())[0]
else:
if (device.type.getText() != 'h'):
print("Only Hog type devices are curently supported.")
print("WARNIN: macro discarded!")
return -1
else:
try:
osc = self.server[device.number.value]
except KeyError:
print("Net# "+str(device.number.value)+" not configured.")
print("WARNING: macro discarded!")
return -1
osc.send_message(path, arg)
return 1
def exitDevice(self, ctx: CommentMacroParser.DeviceContext):
if isinstance(ctx.parentCtx, CommentMacroParser.MacroContext):
ctx.parentCtx.device = ctx
def enterMacro(self, ctx: CommentMacroParser.MacroContext):
ctx.device = None
ctx.number = None
ctx.master = None
ctx.targets = []
ctx.time = None
def exitMacro(self, ctx: CommentMacroParser.MacroContext):
# print the lisp tree of this macro
lisp_tree_str = ctx.toStringTree(recog=self.parser)
print(beautify_lisp_string(lisp_tree_str))
# execute macro from name
ret = -1
name = ctx.children[0].getText()
try:
ret = command[name](self, ctx)
except KeyError:
print(name + " macro is not compatable with OSC.")
return -1
print("Exiting Macro")
return ret
def enterMaster(self, ctx: CommentMacroParser.MasterContext):
ctx.targets = []
def exitMaster(self, ctx: CommentMacroParser.MasterContext):
ctx.targets = set(ctx.targets) # no duplicates
if isinstance(ctx.parentCtx, CommentMacroParser.MacroContext):
ctx.parentCtx.master = ctx
def exitNumber(self, ctx: CommentMacroParser.NumberContext):
ctx.value = num(ctx.getText())
if isinstance(ctx.parentCtx, CommentMacroParser.TargetContext):
ctx.parentCtx.targets.append(ctx.value)
if isinstance(ctx.parentCtx, CommentMacroParser.MacroContext):
ctx.parentCtx.number = ctx
if isinstance(ctx.parentCtx, CommentMacroParser.DeviceContext):
ctx.parentCtx.number = ctx
def exitSpan(self, ctx: CommentMacroParser.SpanContext):
number1 = ctx.children[0].value
number2 = ctx.children[2].value
if (isinstance(number1, int) and isinstance(number2, int)):
if isinstance(ctx.parentCtx, CommentMacroParser.TargetContext):
minimum = min(number1, number2)
maximum = max(number1, number2)
for i in (range(minimum, maximum + 1)):
ctx.parentCtx.targets.append(i)
else:
print("ERROR: Spans must be ranged with intigers.")
ctx.parentCtx.targets.append(-1)
def enterTarget(self, ctx: CommentMacroParser.TargetContext):
ctx.targets = []
def exitTarget(self, ctx: CommentMacroParser.TargetContext):
ctx.target = set(ctx.targets) # no duplicates
ctx.parentCtx.targets.extend(ctx.targets)
def exitNodeType(self, ctx: CommentMacroParser.NodeTypeContext):
if isinstance(ctx.parentCtx, CommentMacroParser.DeviceContext):
ctx.parentCtx.type = ctx