Skip to content

Commit

Permalink
Feature/generator typing (#216)
Browse files Browse the repository at this point in the history
* initial compiler results typing

* more compiler results typing

* dates and correct exception enum

* cleanup
  • Loading branch information
dromer authored Dec 1, 2024
1 parent 29bd1c7 commit 925403e
Show file tree
Hide file tree
Showing 17 changed files with 424 additions and 404 deletions.
72 changes: 37 additions & 35 deletions hvcc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Copyright (C) 2014-2018 Enzien Audio, Ltd.
# Copyright (C) 2021-2023 Wasted Audio
# Copyright (C) 2021-2024 Wasted Audio
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -35,6 +35,7 @@
from hvcc.generators.c2wwise import c2wwise
from hvcc.generators.c2unity import c2unity
from hvcc.generators.types.meta import Meta
from hvcc.types.compiler import CompilerResp, CompilerNotif, CompilerMsg


class Colours:
Expand All @@ -50,19 +51,18 @@ class Colours:
end = "\033[0m"


def add_error(results: OrderedDict, error: str) -> OrderedDict:
def add_error(
results: Dict[str, CompilerResp],
error: str
) -> Dict[str, CompilerResp]:
if "hvcc" in results:
results["hvcc"]["notifs"]["errors"].append({"message": error})
results["hvcc"].notifs.errors.append(CompilerMsg(message=error))
else:
results["hvcc"] = {
"stage": "hvcc",
"notifs": {
"has_error": True,
"exception": None,
"errors": [{"message": error}],
"warnings": []
}
}
results["hvcc"] = CompilerResp(stage="hvcc",
notifs=CompilerNotif(
has_error=True,
errors=[CompilerMsg(message=error)],
))
return results


Expand Down Expand Up @@ -212,9 +212,9 @@ def compile_dataflow(
verbose: bool = False,
copyright: Optional[str] = None,
nodsp: Optional[bool] = False
) -> OrderedDict:
) -> Dict[str, CompilerResp]:

results: OrderedDict = OrderedDict() # default value, empty dictionary
results: OrderedDict[str, CompilerResp] = OrderedDict() # default value, empty dictionary
patch_meta = Meta()

# basic error checking on input
Expand Down Expand Up @@ -250,23 +250,26 @@ def compile_dataflow(
verbose=verbose)

# check for errors
if list(results.values())[0]["notifs"].get("has_error", False):

response: CompilerResp = list(results.values())[0]

if response.notifs.has_error:
return results

subst_name = re.sub(r'\W', '_', patch_name)
results["hv2ir"] = hv2ir.hv2ir.compile(
hv_file=os.path.join(list(results.values())[0]["out_dir"], list(results.values())[0]["out_file"]),
hv_file=os.path.join(response.out_dir, response.out_file),
# ensure that the ir filename has no funky characters in it
ir_file=os.path.join(out_dir, "ir", f"{subst_name}.heavy.ir.json"),
patch_name=patch_name,
verbose=verbose)

# check for errors
if results["hv2ir"]["notifs"].get("has_error", False):
if results["hv2ir"].notifs.has_error:
return results

# get the hvir data
hvir = results["hv2ir"]["ir"]
hvir = results["hv2ir"].ir
patch_name = hvir["name"]["escaped"]
externs = generate_extern_info(hvir, results)

Expand All @@ -278,25 +281,24 @@ def compile_dataflow(

c_src_dir = os.path.join(out_dir, "c")
results["ir2c"] = ir2c.ir2c.compile(
hv_ir_path=os.path.join(results["hv2ir"]["out_dir"], results["hv2ir"]["out_file"]),
hv_ir_path=os.path.join(results["hv2ir"].out_dir, results["hv2ir"].out_file),
static_dir=os.path.join(application_path, "generators/ir2c/static"),
output_dir=c_src_dir,
externs=externs,
copyright=copyright,
nodsp=nodsp)

# check for errors
if results["ir2c"]["notifs"].get("has_error", False):
if results["ir2c"].notifs.has_error:
return results

# ir2c_perf
results["ir2c_perf"] = {
"stage": "ir2c_perf",
"obj_counter": ir2c_perf.ir2c_perf.perf(results["hv2ir"]["ir"], verbose=verbose),
"in_dir": results["hv2ir"]["out_dir"],
"in_file": results["hv2ir"]["out_file"],
"notifs": {}
}
results["ir2c_perf"] = CompilerResp(
stage="ir2c_perf",
obj_perf=ir2c_perf.ir2c_perf.perf(results["hv2ir"].ir, verbose=verbose),
in_dir=results["hv2ir"].out_dir,
in_file=results["hv2ir"].out_file,
)

# reconfigure such that next stage is triggered
in_path = c_src_dir
Expand Down Expand Up @@ -442,25 +444,25 @@ def main() -> bool:
errorCount = 0
for r in list(results.values()):
# print any errors
if r["notifs"].get("has_error", False):
for i, error in enumerate(r["notifs"].get("errors", [])):
if r.notifs.has_error:
for i, error in enumerate(r.notifs.errors):
errorCount += 1
print("{4:3d}) {2}Error{3} {0}: {1}".format(
r["stage"], error["message"], Colours.red, Colours.end, i + 1))
r.stage, error.message, Colours.red, Colours.end, i + 1))

# only print exception if no errors are indicated
if len(r["notifs"].get("errors", [])) == 0 and r["notifs"].get("exception", None) is not None:
if len(r.notifs.errors) == 0 and r.notifs.exception is not None:
errorCount += 1
print("{2}Error{3} {0} exception: {1}".format(
r["stage"], r["notifs"]["exception"], Colours.red, Colours.end))
r.stage, r.notifs.exception, Colours.red, Colours.end))

# clear any exceptions such that results can be JSONified if necessary
r["notifs"]["exception"] = []
r.notifs.exception = None

# print any warnings
for i, warning in enumerate(r["notifs"].get("warnings", [])):
for i, warning in enumerate(r.notifs.warnings):
print("{4:3d}) {2}Warning{3} {0}: {1}".format(
r["stage"], warning["message"], Colours.yellow, Colours.end, i + 1))
r.stage, warning.message, Colours.yellow, Colours.end, i + 1))

if args.results_path:
results_path = os.path.realpath(os.path.abspath(args.results_path))
Expand Down
89 changes: 45 additions & 44 deletions hvcc/core/hv2ir/hv2ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
import os
import time

from typing import Optional, Dict
from typing import Optional

from .HeavyException import HeavyException
from .HeavyParser import HeavyParser

from hvcc.types.compiler import CompilerResp, CompilerNotif, CompilerMsg


class hv2ir:

Expand All @@ -34,7 +36,7 @@ def compile(
ir_file: str,
patch_name: Optional[str] = None,
verbose: bool = False
) -> Dict:
) -> CompilerResp:
""" Compiles a HeavyLang file into a HeavyIR file.
Returns a tuple of compile time in seconds, a notification dictionary,
and a heavy object counter.
Expand All @@ -50,21 +52,20 @@ def compile(
# parse heavy file
hv_graph = HeavyParser.graph_from_file(hv_file=hv_file, xname=patch_name)
except HeavyException as e:
return {
"stage": "hv2ir",
"compile_time": time.time() - tick,
"notifs": {
"has_error": True,
"exception": e,
"errors": [{"message": e.message}],
"warnings": []
},
"obj_counter": None,
"in_file": os.path.basename(hv_file),
"in_dir": os.path.dirname(hv_file),
"out_file": os.path.basename(ir_file),
"out_dir": os.path.dirname(ir_file)
}
return CompilerResp(
stage="hv2ir",
compile_time=time.time() - tick,
notifs=CompilerNotif(
has_error=True,
exception=e,
errors=[CompilerMsg(message=e.message)],
warnings=[]
),
in_file=os.path.basename(hv_file),
in_dir=os.path.dirname(hv_file),
out_file=os.path.basename(ir_file),
out_dir=os.path.dirname(ir_file)
)

try:
# get a counter of all heavy objects
Expand All @@ -80,21 +81,21 @@ def compile(
# generate Heavy.IR
ir = hv_graph.to_ir()
except HeavyException as e:
return {
"stage": "hv2ir",
"compile_time": time.time() - tick,
"notifs": {
"has_error": True,
"exception": e,
"errors": [{"message": e.message}],
"warnings": []
},
"obj_counter": hv_counter,
"in_file": os.path.basename(hv_file),
"in_dir": os.path.dirname(hv_file),
"out_file": os.path.basename(ir_file),
"out_dir": os.path.dirname(ir_file)
}
return CompilerResp(
stage="hv2ir",
compile_time=time.time() - tick,
notifs=CompilerNotif(
has_error=True,
exception=e,
errors=[CompilerMsg(message=e.message)],
warnings=[]
),
in_file=os.path.basename(hv_file),
in_dir=os.path.dirname(hv_file),
out_file=os.path.basename(ir_file),
out_dir=os.path.dirname(ir_file),
obj_counter=hv_counter
)

# write the hv.ir file
with open(ir_file, "w") as f:
Expand All @@ -121,17 +122,17 @@ def compile(
else:
print(o["type"])

return {
"stage": "hv2ir",
"compile_time": time.time() - tick, # record the total compile time
"notifs": hv_graph.get_notices(),
"obj_counter": hv_counter,
"in_file": os.path.basename(hv_file),
"in_dir": os.path.dirname(hv_file),
"out_file": os.path.basename(ir_file),
"out_dir": os.path.dirname(ir_file),
"ir": ir
}
return CompilerResp(
stage="hv2ir",
compile_time=time.time() - tick, # record the total compile time
notifs=CompilerNotif(**hv_graph.get_notices()),
in_file=os.path.basename(hv_file),
in_dir=os.path.dirname(hv_file),
out_file=os.path.basename(ir_file),
out_dir=os.path.dirname(ir_file),
obj_counter=hv_counter,
ir=ir
)


def main() -> None:
Expand All @@ -158,7 +159,7 @@ def main() -> None:
verbose=args.verbose)

if args.verbose:
print(f"Total hv2ir time: {(d['compile_time'] * 1000):.2f}ms")
print(f"Total hv2ir time: {(d.compile_time * 1000):.2f}ms")


if __name__ == "__main__":
Expand Down
60 changes: 27 additions & 33 deletions hvcc/generators/c2daisy/c2daisy.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from ..types.meta import Meta, Daisy
from . import parameters

from hvcc.interpreters.pd2hv.NotificationEnum import NotificationEnum
from hvcc.types.compiler import Compiler, CompilerResp, CompilerNotif, CompilerMsg


hv_midi_messages = {
"__hv_noteout",
Expand All @@ -23,7 +26,7 @@
}


class c2daisy:
class c2daisy(Compiler):
""" Generates a Daisy wrapper for a given patch.
"""

Expand All @@ -39,7 +42,7 @@ def compile(
num_output_channels: int = 0,
copyright: Optional[str] = None,
verbose: Optional[bool] = False
) -> Dict:
) -> CompilerResp:

tick = time.time()

Expand Down Expand Up @@ -138,36 +141,27 @@ def compile(

# ======================================================================================

return {
"stage": "c2daisy",
"notifs": {
"has_error": False,
"exception": None,
"warnings": [],
"errors": []
},
"in_dir": c_src_dir,
"in_file": "",
"out_dir": out_dir,
"out_file": os.path.basename(daisy_h_path),
"compile_time": time.time() - tick
}
return CompilerResp(
stage="c2daisy",
in_dir=c_src_dir,
out_dir=out_dir,
out_file=os.path.basename(daisy_h_path),
compile_time=time.time() - tick
)

except Exception as e:
return {
"stage": "c2daisy",
"notifs": {
"has_error": True,
"exception": e,
"warnings": [],
"errors": [{
"enum": -1,
"message": str(e)
}]
},
"in_dir": c_src_dir,
"in_file": "",
"out_dir": out_dir,
"out_file": "",
"compile_time": time.time() - tick
}
return CompilerResp(
stage="c2daisy",
notifs=CompilerNotif(
has_error=True,
exception=e,
warnings=[],
errors=[CompilerMsg(
enum=NotificationEnum.ERROR_EXCEPTION,
message=str(e)
)]
),
in_dir=c_src_dir,
out_dir=out_dir,
compile_time=time.time() - tick
)
Loading

0 comments on commit 925403e

Please sign in to comment.