From 714917cc90622f3621e77bc79beaebb5ed063198 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Thu, 28 Feb 2019 04:02:31 -0500 Subject: [PATCH] Tweak helper.py. Add "Expander" to plugin tags. Turn on all ModuleLightWidgets if module does not exist. --- helper.py | 93 ++++++++++++++++++++++++----------- src/app/ModuleLightWidget.cpp | 31 +++++++----- src/plugin.cpp | 1 + 3 files changed, 85 insertions(+), 40 deletions(-) diff --git a/helper.py b/helper.py index 014871df..c3596035 100755 --- a/helper.py +++ b/helper.py @@ -16,6 +16,11 @@ class UserException(Exception): pass +def find(f, array): + for a in array: + if f(a): + return f + def input_default(prompt, default=""): str = input(f"{prompt} [{default}]: ") if str == "": @@ -65,29 +70,15 @@ def create_plugin(slug): if os.path.exists(plugin_dir): raise UserException(f"Directory {plugin_dir} already exists") - # Query manifest information - manifest = {} - manifest['slug'] = slug - manifest['name'] = input_default("Plugin name", slug) - manifest['version'] = input_default("Version", "1.0.0") - manifest['license'] = input_default("License (if open-source, use license identifier from https://spdx.org/licenses/)", "proprietary") - manifest['author'] = input_default("Author") - manifest['authorEmail'] = input_default("Author email (optional)") - manifest['authorUrl'] = input_default("Author website URL (optional)") - manifest['pluginUrl'] = input_default("Plugin website URL (optional)") - manifest['manualUrl'] = input_default("Manual website URL (optional)") - manifest['sourceUrl'] = input_default("Source code URL (optional)") - manifest['donateUrl'] = input_default("Donate URL (optional)") - manifest['modules'] = [] - # Create plugin directory os.mkdir(plugin_dir) - # Dump JSON - manifest_filename = os.path.join(plugin_dir, 'plugin.json') - with open(manifest_filename, "w") as f: - json.dump(manifest, f, indent="\t") - print(f"Manifest created at {manifest_filename}") + # Create manifest + try: + create_manifest(plugin_dir, slug) + except Exception as e: + os.rmdir(plugin_dir) + raise e # Create subdirectories os.mkdir(os.path.join(plugin_dir, "src")) @@ -166,6 +157,32 @@ void init(Plugin *p) { print(f"You may use `make`, `make clean`, `make dist`, `make install`, etc in the {plugin_dir} directory.") +def create_manifest(plugin_dir, slug=None): + manifest = {} + + # Query manifest information + if not slug: + slug = input_default("Plugin slug (unique identifier)", slug) + manifest['slug'] = slug + manifest['name'] = input_default("Plugin name", slug) + manifest['version'] = input_default("Version", "1.0.0") + manifest['license'] = input_default("License (if open-source, use license identifier from https://spdx.org/licenses/)", "proprietary") + manifest['author'] = input_default("Author") + manifest['authorEmail'] = input_default("Author email (optional)") + manifest['authorUrl'] = input_default("Author website URL (optional)") + manifest['pluginUrl'] = input_default("Plugin website URL (optional)") + manifest['manualUrl'] = input_default("Manual website URL (optional)") + manifest['sourceUrl'] = input_default("Source code URL (optional)") + manifest['donateUrl'] = input_default("Donate URL (optional)") + manifest['modules'] = [] + + # Dump JSON + manifest_filename = os.path.join(plugin_dir, 'plugin.json') + with open(manifest_filename, "w") as f: + json.dump(manifest, f, indent="\t") + print(f"Manifest created at {manifest_filename}") + + def usage_create_module(script): text = f"""Usage: {script} createmodule @@ -208,14 +225,14 @@ def create_module(slug): manifest = json.load(f) # Check if module manifest exists - module_manifests = filter(lambda m: m['slug'] == slug, manifest['modules']) - if module_manifests: + module_manifest = find(lambda m: m['slug'] == slug, manifest['modules']) + if not module_manifest: # Add module to manifest module_manifest = {} module_manifest['slug'] = slug module_manifest['name'] = input_default("Module name", slug) module_manifest['description'] = input_default("One-line description (optional)") - tags = input_default("Tags (comma-separated, see https://github.com/VCVRack/Rack/blob/v1/src/plugin.cpp#L543 for list)") + tags = input_default("Tags (comma-separated, case-insensitive, see https://github.com/VCVRack/Rack/blob/v1/src/plugin.cpp#L543 for list)") tags = tags.split(",") tags = [tag.strip() for tag in tags] if len(tags) == 1 and tags[0] == "": @@ -230,20 +247,25 @@ def create_module(slug): print(f"Added {slug} to plugin.json") + else: + print(f"Module {slug} already exists in plugin.json. Edit this file to modify the module manifest.") + # Check filenames panel_filename = f"res/{slug}.svg" source_filename = f"src/{slug}.cpp" + if not os.path.exists(panel_filename): + print(f"Panel not found at {panel_filename}. If you wish to automatically generate a source file, run this command with no arguments for instructions for creating a panel file.") + return + + print(f"Panel found at {panel_filename}. Generating source file.") + if os.path.exists(source_filename): if input_default(f"{source_filename} already exists. Overwrite?", "n").lower() != "y": return # Read SVG XML - tree = None - try: - tree = xml.etree.ElementTree.parse(panel_filename) - except FileNotFoundError: - raise UserException(f"Panel not found at {panel_filename}. Run this command with no arguments for instructions to create panels.") + tree = xml.etree.ElementTree.parse(panel_filename) components = panel_to_components(tree) print(f"Components extracted from {panel_filename}") @@ -255,6 +277,17 @@ def create_module(slug): f.write(source) print(f"Source file generated at {source_filename}") + # Append model to plugin.hpp + identifier = slug_to_identifier(slug) + + # Tell user to add model to plugin.hpp and plugin.cpp + print(f"") + print(f"To enable the module, add") + print(f"extern Model *model{identifier};") + print(f"to plugin.hpp, and add") + print(f"p->addModel(model{identifier});") + print(f"to the init() function in plugin.cpp.") + def panel_to_components(tree): ns = { @@ -322,6 +355,7 @@ def panel_to_components(tree): if color == 'ffff00': components['widgets'].append(c) + print(f"Found {len(components['params'])} params, {len(components['inputs'])} inputs, {len(components['outputs'])} outputs, {len(components['lights'])} lights, and {len(components['widgets'])} custom widgets.") return components @@ -484,6 +518,9 @@ def parse_args(args): return usage_create_module(args[0]) return + if args[1] == 'createmanifest': + create_manifest('.') + return usage(args[0]) diff --git a/src/app/ModuleLightWidget.cpp b/src/app/ModuleLightWidget.cpp index db25d16e..c1f0aec5 100644 --- a/src/app/ModuleLightWidget.cpp +++ b/src/app/ModuleLightWidget.cpp @@ -6,21 +6,28 @@ namespace app { void ModuleLightWidget::step() { - if (!module) - return; - - assert(module->lights.size() >= firstLightId + baseColors.size()); std::vector brightnesses(baseColors.size()); - for (size_t i = 0; i < baseColors.size(); i++) { - float brightness = module->lights[firstLightId + i].getBrightness(); - if (!std::isfinite(brightness)) - brightness = 0.f; - // Because LEDs are nonlinear, this seems to look more natural. - brightness = std::sqrt(brightness); - brightness = math::clamp(brightness, 0.f, 1.f); - brightnesses[i] = brightness; + if (module) { + assert(module->lights.size() >= firstLightId + baseColors.size()); + + for (size_t i = 0; i < baseColors.size(); i++) { + float brightness = module->lights[firstLightId + i].getBrightness(); + if (!std::isfinite(brightness)) + brightness = 0.f; + // Because LEDs are nonlinear, this seems to look more natural. + brightness = std::sqrt(brightness); + brightness = math::clamp(brightness, 0.f, 1.f); + brightnesses[i] = brightness; + } + } + else { + // Turn all lights on + for (size_t i = 0; i < baseColors.size(); i++) { + brightnesses[i] = 1.f; + } } + setBrightnesses(brightnesses); } diff --git a/src/plugin.cpp b/src/plugin.cpp index 28609bb9..5abbe51a 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -559,6 +559,7 @@ const std::set allowedTags = { "Envelope follower", "Envelope generator", "Equalizer", + "Expander", // Expands the functionality of a "mother" module when placed next to it. Expanders should inherit the tags of its mother module. "External", "Flanger", "Function generator",