From d05c62d061cb26301f97e3bed84fc4976e14b41b Mon Sep 17 00:00:00 2001 From: Benjamin Klum Date: Mon, 21 Oct 2024 19:24:51 +0200 Subject: [PATCH] #1256 Docs: Move architecture images and add initial Playtime docs --- ARCHITECTURE.adoc | 154 ++++++++++++------ .../images/components-management.svg | 0 .../images/components-midi-device.svg | 0 .../images/components-midi-fx.svg | 0 .../images/components-osc.svg | 0 doc/{ => architecture}/images/components.svg | 0 doc/{ => architecture}/images/logo.svg | 0 doc/{ => architecture}/images/modules.svg | 0 .../images/onion-layers.svg | 0 .../helgobox/screenshots/app-window.png | Bin .../helgobox/screenshots/plugin-window.png | Bin .../modules/ROOT/pages/introduction.adoc | 2 +- doc/helgobox/modules/ROOT/pages/usage.adoc | 4 +- doc/playtime/README.adoc | 6 + doc/playtime/antora.yml | 12 ++ doc/playtime/modules/ROOT/nav.adoc | 2 + .../modules/ROOT/pages/installation.adoc | 3 + .../modules/ROOT/pages/introduction.adoc | 14 ++ doc/realearn/modules/ROOT/nav.adoc | 1 + .../modules/ROOT/pages/installation.adoc | 3 + .../modules/ROOT/pages/introduction.adoc | 8 +- doc/svg-gen/index.js | 19 ++- .../midi-fighter-twister-helgoboss.mfs | Bin 23 files changed, 166 insertions(+), 62 deletions(-) rename doc/{ => architecture}/images/components-management.svg (100%) rename doc/{ => architecture}/images/components-midi-device.svg (100%) rename doc/{ => architecture}/images/components-midi-fx.svg (100%) rename doc/{ => architecture}/images/components-osc.svg (100%) rename doc/{ => architecture}/images/components.svg (100%) rename doc/{ => architecture}/images/logo.svg (100%) rename doc/{ => architecture}/images/modules.svg (100%) rename doc/{ => architecture}/images/onion-layers.svg (100%) rename doc/helgobox/modules/ROOT/images/{images => }/helgobox/screenshots/app-window.png (100%) rename doc/helgobox/modules/ROOT/images/{images => }/helgobox/screenshots/plugin-window.png (100%) create mode 100644 doc/playtime/README.adoc create mode 100644 doc/playtime/antora.yml create mode 100644 doc/playtime/modules/ROOT/nav.adoc create mode 100644 doc/playtime/modules/ROOT/pages/installation.adoc create mode 100644 doc/playtime/modules/ROOT/pages/introduction.adoc create mode 100644 doc/realearn/modules/ROOT/pages/installation.adoc rename {doc/resources => resources/controller-specific-files/djtechtools/midi-fighter-twister}/midi-fighter-twister-helgoboss.mfs (100%) diff --git a/ARCHITECTURE.adoc b/ARCHITECTURE.adoc index 06116c624..10c4cc007 100644 --- a/ARCHITECTURE.adoc +++ b/ARCHITECTURE.adoc @@ -3,45 +3,75 @@ :sectnums: :sectnumlevels: 2 -This document describes the software architecture of ReaLearn. It's a work in progress. +This document describes the software architecture of ReaLearn. +It's a work in progress. == Basics Technically, ReaLearn is a *third-party native VST plug-in for REAPER which makes heavy use of the REAPER extension API*. -… Woah! That is a lot to take in! Let’s see what this means in detail: - -* First and foremost, ReaLearn is a *plug-in for REAPER*. That means ReaLearn is a software module which is loaded by REAPER dynamically (at runtime). It comes in the form of a link:https://en.m.wikipedia.org/wiki/Dynamic-link_library[DLL] on Windows, a link:https://stackoverflow.com/questions/2339679/what-are-the-differences-between-so-and-dylib-on-macos[DYLIB] on macOS and a link:https://superuser.com/questions/71404/what-is-an-so-file[SO] on Linux. Communication goes both ways: ReaLearn calls REAPER functions and REAPER calls ReaLearn functions ("callbacks"). -* It makes heavy use of the *REAPER extension API*. That means ReaLearn uses functions and data structures of REAPER which are _specific to REAPER_, so they are _not_ part of a DAW-agnostic plug-in standard. In theory, other DAWs could implement this API as well, but in practice only REAPER itself does it. The reason is that this API is huge and that many parts of it only make sense for REAPER. As a consequence, ReaLearn runs in REAPER only! -* At the same time, it is a *VST plug-in*. That means … -** … it's not loaded immediately at REAPER startup time. It gets loaded as soon as the user adds the first ReaLearn plug-in instance (in the form of a REAPER FX) or loads a project or FX chain containing a ReaLearn instance. -** … once loaded, there can be arbitrary many instances of ReaLearn (a big difference to REAPER extensions, which can "exist" only once). Adding more instances is rather cheap because the dynamic library is already loaded at that time. -** … plug-in data is saved per instance (as a VST chunk). As a consequence, plug-in data is typically saved along with a specific project (but it doesn't have to because you can put ReaLearn on the monitoring FX chain as well). +… Woah! +That is a lot to take in! +Let’s see what this means in detail: + +* First and foremost, ReaLearn is a *plug-in for REAPER*. +That means ReaLearn is a software module which is loaded by REAPER dynamically (at runtime). +It comes in the form of a link:https://en.m.wikipedia.org/wiki/Dynamic-link_library[DLL] on Windows, a link:https://stackoverflow.com/questions/2339679/what-are-the-differences-between-so-and-dylib-on-macos[DYLIB] on macOS and a link:https://superuser.com/questions/71404/what-is-an-so-file[SO] on Linux. +Communication goes both ways: ReaLearn calls REAPER functions and REAPER calls ReaLearn functions ("callbacks"). +* It makes heavy use of the *REAPER extension API*. +That means ReaLearn uses functions and data structures of REAPER which are _specific to REAPER_, so they are _not_ part of a DAW-agnostic plug-in standard. +In theory, other DAWs could implement this API as well, but in practice only REAPER itself does it. +The reason is that this API is huge and that many parts of it only make sense for REAPER. +As a consequence, ReaLearn runs in REAPER only! +* At the same time, it is a *VST plug-in*. +That means … +** … it's not loaded immediately at REAPER startup time. +It gets loaded as soon as the user adds the first ReaLearn plug-in instance (in the form of a REAPER FX) or loads a project or FX chain containing a ReaLearn instance. +** … once loaded, there can be arbitrary many instances of ReaLearn (a big difference to REAPER extensions, which can "exist" only once). +Adding more instances is rather cheap because the dynamic library is already loaded at that time. +** … plug-in data is saved per instance (as a VST chunk). +As a consequence, plug-in data is typically saved along with a specific project (but it doesn't have to because you can put ReaLearn on the monitoring FX chain as well). ** … it can _receive_ MIDI and audio data from the FX input pins (using functions and data structures defined by the VST plug-in standard). ** … it can _send_ MIDI and audio data to the FX output pins (using functions and data structures defined by the VST plug-in standard). -* It's a *native plug-in*. That means ReaLearn *is not a script*! It's full-blown native machine code that operates on eye level with REAPER. Once ReaLearn is loaded, it essentially becomes a part of REAPER itself. It runs in the same process, can open its own threads and is not sandboxed or restrained by a virtual machine (unlike Lua/EEL-based ReaScript or JSFX). That's great because it means ReaLearn is a "first-class citizen" and doesn't have any inherent disadvantage in terms of speed and possibilities. Also, it's written in a language that can leverage all of the power and performance potential that comes with running on "bare metal": link:https://www.rust-lang.org[Rust]. Rust is a non-garbage-collected system programming language, just like C or C++ but more modern. -* It's a *third-party product*. That mean's it's not made by Cockos, the developer of REAPER. It's made by link:https://www.helgoboss.org/projects/[Helgoboss] and must be installed separately. +* It's a *native plug-in*. +That means ReaLearn *is not a script*! +It's full-blown native machine code that operates on eye level with REAPER. +Once ReaLearn is loaded, it essentially becomes a part of REAPER itself. +It runs in the same process, can open its own threads and is not sandboxed or restrained by a virtual machine (unlike Lua/EEL-based ReaScript or JSFX). +That's great because it means ReaLearn is a "first-class citizen" and doesn't have any inherent disadvantage in terms of speed and possibilities. +Also, it's written in a language that can leverage all of the power and performance potential that comes with running on "bare metal": link:https://www.rust-lang.org[Rust]. +Rust is a non-garbage-collected system programming language, just like C or C++ but more modern. +* It's a *third-party product*. +That mean's it's not made by Cockos, the developer of REAPER. +It's made by link:https://www.helgoboss.org/projects/[Helgoboss] and must be installed separately. == Modules -ReaLearn is built in a modular fashion. The following diagram shows ReaLearn's most important modules (excluding 3rd-party modules): +ReaLearn is built in a modular fashion. +The following diagram shows ReaLearn's most important modules (excluding 3rd-party modules): [.text-center] -image:doc/images/modules.svg[ReaLearn modules] - -* *main:* The main module of ReaLearn which contains most of its code. We will learn more about it in the following sections. -* *api:* This contains the data structures for ReaLearn presets. Its main use case is _ReaLearn Script_, a way to build mappings with the Lua scripting language. -* *swell-ui:* A tiny custom-written GUI framework based on the Win32 API (Windows) and Cockos SWELL (macOS, Linux) respectively. SWELL makes it possible to write the GUI code only once, using a subset of the Windows-specific Win32 API, but making it work on macOS and Linux as well. Basically by translating the Win32 API calls to OS-native GUI framework calls (Cocoa on macOS, GTK on Linux). +image:doc/architecture/images/modules.svg[ReaLearn modules] + +* *main:* The main module of ReaLearn which contains most of its code. +We will learn more about it in the following sections. +* *api:* This contains the data structures for ReaLearn presets. +Its main use case is _ReaLearn Script_, a way to build mappings with the Lua scripting language. +* *swell-ui:* A tiny custom-written GUI framework based on the Win32 API (Windows) and Cockos SWELL (macOS, Linux) respectively. +SWELL makes it possible to write the GUI code only once, using a subset of the Windows-specific Win32 API, but making it work on macOS and Linux as well. +Basically by translating the Win32 API calls to OS-native GUI framework calls (Cocoa on macOS, GTK on Linux). * *reaper-rs:* Rust bindings to the REAPER API (which itself is based on C and partially C++). -* *helgoboss-learn:* A library which contains reusable and DAW-agnostic code related to MIDI/OSC-learn functionality. Some of ReaLearn's basic notions such as _Source_, _Glue_ (still called _Mode_ in most parts of the codebase) and _Target_ are defined in this DAW-neutral module. +* *helgoboss-learn:* A library which contains reusable and DAW-agnostic code related to MIDI/OSC-learn functionality. +Some of ReaLearn's basic notions such as _Source_, _Glue_ (still called _Mode_ in most parts of the codebase) and _Target_ are defined in this DAW-neutral module. * *helgoboss-midi:* A general-purpose and carefully designed library for dealing with MIDI messages according to the MIDI 1.0 specification. == Layers -The _main_ module of ReaLearn is roughly built around an architectural pattern sometimes called link:https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html[Onion Architecture]. This means it's divided into multiple "onion" layers: +The _main_ module of ReaLearn is roughly built around an architectural pattern sometimes called link:https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html[Onion Architecture]. +This means it's divided into multiple "onion" layers: [.text-center] -image:doc/images/onion-layers.svg[ReaLearn onion layers] +image:doc/architecture/images/onion-layers.svg[ReaLearn onion layers] These layers follow a simple but strict rule: @@ -51,9 +81,12 @@ Outer layers use its own code and code of inner layers, *but inner layers are no ____ -This rule prevents "Spaghetti code" between the different layers and makes sure there's a clean separation between different responsibilities. +This rule prevents "Spaghetti code" between the different layers and makes sure there's a clean separation between different responsibilities. -IMPORTANT: This rule doesn't restrict control and data flow! Both control and data can still flow in both directions. In practice they also do because e.g. data from the processing layer needs to be "sent up" to the user interface in order to be displayed! The rule is concerned with the visibility of code symbols only. +IMPORTANT: This rule doesn't restrict control and data flow! +Both control and data can still flow in both directions. +In practice they also do because e.g. data from the processing layer needs to be "sent up" to the user interface in order to be displayed! +The rule is concerned with the visibility of code symbols only. The contents and responsibilities of each layer are described in the following. @@ -61,22 +94,34 @@ The contents and responsibilities of each layer are described in the following. * Contains very generic and reusable utility code that is not specific to ReaLearn and at the same time not substantial enough to put it into a dedicated library module. * Also, this layer can be considered as the layer that contains the Rust standard library and other Rust crates that provide utility code (although those are obviously not part of ReaLearn's own codebase). -* In addition, it makes very much sense to think of the base layer as the layer that contains REAPER itself. ReaLearn is built _around_ REAPER, it's not designed to be usable without it. +* In addition, it makes very much sense to think of the base layer as the layer that contains REAPER itself. +ReaLearn is built _around_ REAPER, it's not designed to be usable without it. ** As a direct consequence, all layers within ReaLearn are allowed to use the REAPER API! -** This doesn't mean that ReaLearn couldn't be ported to other DAWs. It could, provided the other DAW is substantially extensible via native modules. On ReaLearn's side, some effort in this direction has already been done: As mentioned before, the module _helgoboss-learn_ is designed to contain those parts of ReaLearn's logic that are DAW-agnostic. +** This doesn't mean that ReaLearn couldn't be ported to other DAWs. +It could, provided the other DAW is substantially extensible via native modules. +On ReaLearn's side, some effort in this direction has already been done: As mentioned before, the module _helgoboss-learn_ is designed to contain those parts of ReaLearn's logic that are DAW-agnostic. === Processing layer -* This layer contains the essence of ReaLearn: Its processing logic. This includes the complete control and feedback logic. -* If you would take away ReaLearn's graphical user interface, its projection feature, its plug-in nature, its capability to memorize its settings (= persistence) … in short, all the stuff that is more "facade" than "central", then what's left is the processing layer. The processing layer alone would still be capable of doing ReaLearn's main job: Routing incoming MIDI or OSC messages through the mapping list and controlling the targets accordingly as well as handling feedback. +* This layer contains the essence of ReaLearn: Its processing logic. +This includes the complete control and feedback logic. +* If you would take away ReaLearn's graphical user interface, its projection feature, its plug-in nature, its capability to memorize its settings (= persistence) … in short, all the stuff that is more "facade" than "central", then what's left is the processing layer. +The processing layer alone would still be capable of doing ReaLearn's main job: Routing incoming MIDI or OSC messages through the mapping list and controlling the targets accordingly as well as handling feedback. * Because the processing layer is very independent and doesn't dictate things like user interface and persistence, It would be quite easy to factor it out into a separate module and use it in other ways, e.g. in order to build a totally different user interface on top of it! -* All the data structures in this layer are custom-tailored and optimized with one primary goal in mind: Performance. ReaLearn should do its main job very fast and efficiently! +* All the data structures in this layer are custom-tailored and optimized with one primary goal in mind: Performance. +ReaLearn should do its main job very fast and efficiently! === Management layer * This layer contains everything related to _managing_ ReaLearn's objects: Mappings, groups, parameters and all that stuff. -* All the data structures in this layer (usually called _models_) are tailored to this purpose. If you think that there's a lot of duplication between this layer and the processing layer, look twice. Yes, the data structures look similar at times, but often they are completely different. That's because they are designed for different purposes. This strict separation of concerns ensures that no compromises need to be made between performance (processing layer) and managing/GUI (management/infrastructure layers). -* Even though this layer _still_ doesn't dictate a particular user interface, it is user-interface-aware and provides functions and data structures that are typically used by user interfaces. It also allows user interfaces to register hooks in order to be notified whenever the state of ReaLearn's objects change. The management layer is built with a _reactive_ GUI in mind which reflects all changes immediately. +* All the data structures in this layer (usually called _models_) are tailored to this purpose. +If you think that there's a lot of duplication between this layer and the processing layer, look twice. +Yes, the data structures look similar at times, but often they are completely different. +That's because they are designed for different purposes. +This strict separation of concerns ensures that no compromises need to be made between performance (processing layer) and managing/GUI (management/infrastructure layers). +* Even though this layer _still_ doesn't dictate a particular user interface, it is user-interface-aware and provides functions and data structures that are typically used by user interfaces. +It also allows user interfaces to register hooks in order to be notified whenever the state of ReaLearn's objects change. +The management layer is built with a _reactive_ GUI in mind which reflects all changes immediately. === Infrastructure layer @@ -90,13 +135,18 @@ The contents and responsibilities of each layer are described in the following. ==== User interface (UI) * Contains the implementation of ReaLearn's main graphical user interface. -* It's based on the _swell-ui_ module. That means it uses platform-native user interface widgets - which gives ReaLearn the somewhat old-school but extremely professional look ;) +* It's based on the _swell-ui_ module. +That means it uses platform-native user interface widgets - which gives ReaLearn the somewhat old-school but extremely professional look ;) ==== Data * Contains data structures for the serialization/deserialization of all ReaLearn objects (mappings, groups, etc.). -* The data structures in this layer are similar to the corresponding data structures in the management layer but they serve a quite different purpose: Serialization and deserialization of ReaLearn's state. This is necessary for persistence and features such as copy&paste. -* One could wonder about the code duplication here, but again: The data structures in this layer serve different purposes than the ones in the management layer. Serialization/deserialization for persistence purposes absolutely needs to be concerned with backward compatibility, which makes these data structures very hard to change. Keeping things separate ensures that the management data structures can develop freely, without being constrained by backward compatibility considerations. Again: No compromises. +* The data structures in this layer are similar to the corresponding data structures in the management layer but they serve a quite different purpose: Serialization and deserialization of ReaLearn's state. +This is necessary for persistence and features such as copy&paste. +* One could wonder about the code duplication here, but again: The data structures in this layer serve different purposes than the ones in the management layer. +Serialization/deserialization for persistence purposes absolutely needs to be concerned with backward compatibility, which makes these data structures very hard to change. +Keeping things separate ensures that the management data structures can develop freely, without being constrained by backward compatibility considerations. +Again: No compromises. ==== API @@ -119,27 +169,27 @@ The contents and responsibilities of each layer are described in the following. === Overview [.text-center] -image:doc/images/components.svg[ReaLearn components] +image:doc/architecture/images/components.svg[ReaLearn components] === Focus: Management communication [.text-center] -image:doc/images/components-management.svg[ReaLearn components] +image:doc/architecture/images/components-management.svg[ReaLearn components] === Focus: Real-time MIDI communication (from/to FX input/output) [.text-center] -image:doc/images/components-midi-fx.svg[ReaLearn components] +image:doc/architecture/images/components-midi-fx.svg[ReaLearn components] === Focus: Real-time MIDI communication (from/to hardware device) [.text-center] -image:doc/images/components-midi-device.svg[ReaLearn components] +image:doc/architecture/images/components-midi-device.svg[ReaLearn components] === Focus: Real-time OSC communication [.text-center] -image:doc/images/components-osc.svg[ReaLearn components] +image:doc/architecture/images/components-osc.svg[ReaLearn components] == Design decisions @@ -159,7 +209,8 @@ ReaLearn supports scripting in various places: ==== Advantages of Lua -As can be seen, Lua is our main scripting language for stuff that doesn't need to run in real-time. Here's why: +As can be seen, Lua is our main scripting language for stuff that doesn't need to run in real-time. +Here's why: * Lua is easily embeddable (this is a must, and it rules out most other mainstream languages) * Lua is popular and widely-used (important, rules out exotic or new languages such as Rhai or Gluon) @@ -173,12 +224,17 @@ As can be seen, Lua is our main scripting language for stuff that doesn't need t ==== Ruled out alternatives -Some languages that were considered but ruled out. Here they are, along with the most important reasons why there were ruled out: +Some languages that were considered but ruled out. +Here they are, along with the most important reasons why there were ruled out: * JavaScript/TypeScript: no operator overloading, not possible to skip parentheses when passing function argument, also much harder to embed -** In general, I was very much in favor of JavaScript/TypeScript because it's so widespread and the tooling is perfect. But turns out Lua is actually better suited for our main use case of creating large data structures for import/export. Surprise! +** In general, I was very much in favor of JavaScript/TypeScript because it's so widespread and the tooling is perfect. +But turns out Lua is actually better suited for our main use case of creating large data structures for import/export. +Surprise! ** Assembling mappings is an example where operator overloading is really nice: `name("Scroll up") + shift_or_sustain + button("col1/stop") + feedback_disabled() + turbo() + scroll_vertically(-1)` -** Also, embedding it is very hard. Yes, there is TypeScriptToLua, but the TypeScriptToLua compiler is also written in JavaScript. We need a solution that runs 100% in ReaLearn without external pre-processing. +** Also, embedding it is very hard. +Yes, there is TypeScriptToLua, but the TypeScriptToLua compiler is also written in JavaScript. +We need a solution that runs 100% in ReaLearn without external pre-processing. * Python: too heavy-weight, also harder to embed and slower * Wren: doesn't seem to be active anymore, maybe a bit too exotic (looks exciting though) * Gluon: too exotic @@ -214,8 +270,11 @@ Pros: Cons: -- Language server can't auto-complete fields in table literals. Not at all. -- The type system is less elaborate than that of Luau. Unions are not powerful enough, e.g. two tables can't be part of a union, which also excludes tagged unions. We have a lot of tagged unions. +- Language server can't auto-complete fields in table literals. +Not at all. +- The type system is less elaborate than that of Luau. +Unions are not powerful enough, e.g. two tables can't be part of a union, which also excludes tagged unions. +We have a lot of tagged unions. - Types are required, no structural typing - Needs an additional compilation step to be loadable into the VM @@ -228,7 +287,8 @@ Pros: - Types are optional, structural typing - Can auto-complete not-yet typed fields in table literals - Works without needing another language -- Seems to allow dots in type names. Which would be nice for something like `Target.TrackVolume` instead of `Target_TrackVolume`. +- Seems to allow dots in type names. +Which would be nice for something like `Target.TrackVolume` instead of `Target_TrackVolume`. Cons: @@ -250,9 +310,11 @@ Pros: Cons: - link:https://github.com/luau-lang/luau/issues/685[Can't auto-complete not-yet typed fields in table literals] -- Type system still has its flaws, especially when it comes to intersections. On the other hand, the other candidates don't even try something as advanced as intersections. +- Type system still has its flaws, especially when it comes to intersections. +On the other hand, the other candidates don't even try something as advanced as intersections. - Not sure about using a fork -- Typing too structural? It doesn't spit out the type name anymore after assignment. +- Typing too structural? +It doesn't spit out the type name anymore after assignment. ===== Verdict diff --git a/doc/images/components-management.svg b/doc/architecture/images/components-management.svg similarity index 100% rename from doc/images/components-management.svg rename to doc/architecture/images/components-management.svg diff --git a/doc/images/components-midi-device.svg b/doc/architecture/images/components-midi-device.svg similarity index 100% rename from doc/images/components-midi-device.svg rename to doc/architecture/images/components-midi-device.svg diff --git a/doc/images/components-midi-fx.svg b/doc/architecture/images/components-midi-fx.svg similarity index 100% rename from doc/images/components-midi-fx.svg rename to doc/architecture/images/components-midi-fx.svg diff --git a/doc/images/components-osc.svg b/doc/architecture/images/components-osc.svg similarity index 100% rename from doc/images/components-osc.svg rename to doc/architecture/images/components-osc.svg diff --git a/doc/images/components.svg b/doc/architecture/images/components.svg similarity index 100% rename from doc/images/components.svg rename to doc/architecture/images/components.svg diff --git a/doc/images/logo.svg b/doc/architecture/images/logo.svg similarity index 100% rename from doc/images/logo.svg rename to doc/architecture/images/logo.svg diff --git a/doc/images/modules.svg b/doc/architecture/images/modules.svg similarity index 100% rename from doc/images/modules.svg rename to doc/architecture/images/modules.svg diff --git a/doc/images/onion-layers.svg b/doc/architecture/images/onion-layers.svg similarity index 100% rename from doc/images/onion-layers.svg rename to doc/architecture/images/onion-layers.svg diff --git a/doc/helgobox/modules/ROOT/images/images/helgobox/screenshots/app-window.png b/doc/helgobox/modules/ROOT/images/helgobox/screenshots/app-window.png similarity index 100% rename from doc/helgobox/modules/ROOT/images/images/helgobox/screenshots/app-window.png rename to doc/helgobox/modules/ROOT/images/helgobox/screenshots/app-window.png diff --git a/doc/helgobox/modules/ROOT/images/images/helgobox/screenshots/plugin-window.png b/doc/helgobox/modules/ROOT/images/helgobox/screenshots/plugin-window.png similarity index 100% rename from doc/helgobox/modules/ROOT/images/images/helgobox/screenshots/plugin-window.png rename to doc/helgobox/modules/ROOT/images/helgobox/screenshots/plugin-window.png diff --git a/doc/helgobox/modules/ROOT/pages/introduction.adoc b/doc/helgobox/modules/ROOT/pages/introduction.adoc index ecf4a687c..bb3621ab7 100644 --- a/doc/helgobox/modules/ROOT/pages/introduction.adoc +++ b/doc/helgobox/modules/ROOT/pages/introduction.adoc @@ -1,6 +1,6 @@ = Introduction -link:https://www.helgoboss.org/projects/helgobox[Helgobox] is an instrument plug-in for REAPER that unites the products link:https://www.helgoboss.org/projects/realearn[ReaLearn] and link:https://www.helgoboss.org/projects/playtime[Playtime] under one roof. +link:https://www.helgoboss.org/projects/helgobox[Helgobox] is an instrument plug-in for link:https://www.reaper.fm[REAPER] that unites the products link:https://www.helgoboss.org/projects/realearn[ReaLearn] and link:https://www.helgoboss.org/projects/playtime[Playtime] under one roof. In addition to the plug-in, it comes with the Helgobox App, a modern user interface for the Helgobox Instrument. It runs embedded in REAPER and in the future also as a separate mobile app (iOS, Android). diff --git a/doc/helgobox/modules/ROOT/pages/usage.adoc b/doc/helgobox/modules/ROOT/pages/usage.adoc index 1a9844f59..75cc4cd0e 100644 --- a/doc/helgobox/modules/ROOT/pages/usage.adoc +++ b/doc/helgobox/modules/ROOT/pages/usage.adoc @@ -13,7 +13,7 @@ Helgobox is fired up just like any other VST instrument in REAPER: By adding an Initially, you see the Helgobox instrument plug-in, which primarily provides the user interface for link:https://www.helgoboss.org/projects/realearn[ReaLearn]: .Plug-in window -image::images/helgobox/screenshots/plugin-window.png[] +image::helgobox/screenshots/plugin-window.png[] == Show the Helgobox App @@ -24,7 +24,7 @@ Each Helgobox instance can display its own App window, embedded into REAPER: . Press menu:Menu[Show App] .App window -image::images/helgobox/screenshots/app-window.png[] +image::helgobox/screenshots/app-window.png[] As an alternative, you can use the convenient btn:[Playtime] button in REAPER's main toolbar. If you don't see it, do this: diff --git a/doc/playtime/README.adoc b/doc/playtime/README.adoc new file mode 100644 index 000000000..43b57fdc6 --- /dev/null +++ b/doc/playtime/README.adoc @@ -0,0 +1,6 @@ += Playtime Reference +:experimental: + +This reference is written in AsciiDoc and follows the directory conventions of the documentation site generator link:https://antora.org/[Antora]. + +A good place to start is link:modules/ROOT/pages/introduction.adoc[]. \ No newline at end of file diff --git a/doc/playtime/antora.yml b/doc/playtime/antora.yml new file mode 100644 index 000000000..f8b0f0280 --- /dev/null +++ b/doc/playtime/antora.yml @@ -0,0 +1,12 @@ +name: playtime +title: Playtime Reference +version: ~ +nav: + - modules/ROOT/nav.adoc +start_page: introduction.adoc +asciidoc: + attributes: + # For making menu and button macros work + experimental: true + # For showing prev/next links + page-pagination: '' \ No newline at end of file diff --git a/doc/playtime/modules/ROOT/nav.adoc b/doc/playtime/modules/ROOT/nav.adoc new file mode 100644 index 000000000..32fd55e38 --- /dev/null +++ b/doc/playtime/modules/ROOT/nav.adoc @@ -0,0 +1,2 @@ +* xref:introduction.adoc[] +* xref:installation.adoc[] \ No newline at end of file diff --git a/doc/playtime/modules/ROOT/pages/installation.adoc b/doc/playtime/modules/ROOT/pages/installation.adoc new file mode 100644 index 000000000..c963fc714 --- /dev/null +++ b/doc/playtime/modules/ROOT/pages/installation.adoc @@ -0,0 +1,3 @@ += Installation + +See xref:helgobox::installation.adoc[installation instructions for Helgobox], the plug-in that contains Playtime. \ No newline at end of file diff --git a/doc/playtime/modules/ROOT/pages/introduction.adoc b/doc/playtime/modules/ROOT/pages/introduction.adoc new file mode 100644 index 000000000..5a112011e --- /dev/null +++ b/doc/playtime/modules/ROOT/pages/introduction.adoc @@ -0,0 +1,14 @@ += Introduction + +link:https://www.helgoboss.org/projects/playtime[Playtime] is a modern session view aka clip launcher for link:https://www.reaper.fm[REAPER]. +It is part of the link:https://www.helgoboss.org/projects/helgobox[Helgobox] plug-in. + +This reference provides a detailed description of Playtime's concepts and functionalities. Use it whenever you need an in-depth exploration of a specific feature or functionality in Playtime. + +[IMPORTANT] +==== + +**If you are a beginner, please use the link:https://github.com/helgoboss/helgobox/wiki/Playtime-Home[Playtime Wiki] instead!** + +This reference is targeted at users who are already familiar with the Playtime basics and want to look up specific information. The Wiki is perfect if you are just starting off. It guides you through the very basics and contains links to easily digestible video tutorials. +==== \ No newline at end of file diff --git a/doc/realearn/modules/ROOT/nav.adoc b/doc/realearn/modules/ROOT/nav.adoc index c5c85b17f..5c9af9dc7 100644 --- a/doc/realearn/modules/ROOT/nav.adoc +++ b/doc/realearn/modules/ROOT/nav.adoc @@ -1,4 +1,5 @@ * xref:introduction.adoc[] +* xref:installation.adoc[] * xref:key-concepts.adoc[] * xref:user-interface.adoc[] ** xref:user-interface/main-panel.adoc[] diff --git a/doc/realearn/modules/ROOT/pages/installation.adoc b/doc/realearn/modules/ROOT/pages/installation.adoc new file mode 100644 index 000000000..60e7dc155 --- /dev/null +++ b/doc/realearn/modules/ROOT/pages/installation.adoc @@ -0,0 +1,3 @@ += Installation + +See xref:helgobox::installation.adoc[installation instructions for Helgobox], the plug-in that contains ReaLearn. \ No newline at end of file diff --git a/doc/realearn/modules/ROOT/pages/introduction.adoc b/doc/realearn/modules/ROOT/pages/introduction.adoc index e9707de04..9945a5574 100644 --- a/doc/realearn/modules/ROOT/pages/introduction.adoc +++ b/doc/realearn/modules/ROOT/pages/introduction.adoc @@ -5,15 +5,15 @@ |Last update of relevant screenshots: |`2024-10-20 (v2.16.10)` |=== -link:https://www.helgoboss.org/projects/realearn[ReaLearn] is a versatile controller integration tool for REAPER. -It comes as a core part of the link:https://www.helgoboss.org/projects/helgobox[Helgobox] suite. +link:https://www.helgoboss.org/projects/realearn[ReaLearn] is a versatile controller integration tool for link:https://www.reaper.fm[REAPER]. +It is part of the link:https://www.helgoboss.org/projects/helgobox[Helgobox] plug-in. -This reference provides a detailed description of ReaLearn's user interface, concepts, and functionalities. Use it whenever you need an in-depth exploration of a specific feature or functionality in ReaLearn. +This reference provides a detailed description of ReaLearn's user interface, concepts and functionalities. Use it whenever you need an in-depth exploration of a specific feature or functionality in ReaLearn. [IMPORTANT] ==== **If you are a beginner, please use the link:https://github.com/helgoboss/helgobox/wiki/ReaLearn-Home[ReaLearn Wiki] instead!** -This reference is targeted at users who are already familiar with the ReaLearn basics and want to look up specific information. The Wiki is perfect if you are just starting off. It guides you through the very basics and contains links to easily digestable video tutorials. +This reference is targeted at users who are already familiar with the ReaLearn basics and want to look up specific information. The Wiki is perfect if you are just starting off. It guides you through the very basics and contains links to easily digestible video tutorials. ==== diff --git a/doc/svg-gen/index.js b/doc/svg-gen/index.js index cfe879d95..df3f4fe94 100644 --- a/doc/svg-gen/index.js +++ b/doc/svg-gen/index.js @@ -1,6 +1,7 @@ -import { createSVGWindow } from "svgdom"; +import {createSVGWindow} from "svgdom"; import svgjs from "@svgdotjs/svg.js"; -const { SVG, registerWindow } = svgjs; + +const {SVG, registerWindow} = svgjs; import * as fs from 'fs'; import * as path from 'path'; import pako from "pako"; @@ -16,24 +17,24 @@ const stylesheet = fs.readFileSync(path.resolve(script_dir, 'styles.css')); generate() async function generate() { - fs.writeFileSync('doc/images/modules.svg', await generateModulesDiagram()) - fs.writeFileSync('doc/images/onion-layers.svg', generateOnionLayersDiagram()) - fs.writeFileSync('doc/images/components.svg', await generateComponentDiagram()) - fs.writeFileSync('doc/images/components-midi-fx.svg', await generateComponentDiagram([ + fs.writeFileSync('doc/architecture/images/modules.svg', await generateModulesDiagram()) + fs.writeFileSync('doc/architecture/images/onion-layers.svg', generateOnionLayersDiagram()) + fs.writeFileSync('doc/architecture/images/components.svg', await generateComponentDiagram()) + fs.writeFileSync('doc/architecture/images/components-midi-fx.svg', await generateComponentDiagram([ 'role-realtime-general', 'role-realtime-midi-general', 'role-realtime-midi-fx' ])) - fs.writeFileSync('doc/images/components-midi-device.svg', await generateComponentDiagram([ + fs.writeFileSync('doc/architecture/images/components-midi-device.svg', await generateComponentDiagram([ 'role-realtime-general', 'role-realtime-midi-general', 'role-realtime-midi-device' ])) - fs.writeFileSync('doc/images/components-osc.svg', await generateComponentDiagram([ + fs.writeFileSync('doc/architecture/images/components-osc.svg', await generateComponentDiagram([ 'role-realtime-general', 'role-realtime-osc', ])) - fs.writeFileSync('doc/images/components-management.svg', await generateComponentDiagram([ + fs.writeFileSync('doc/architecture/images/components-management.svg', await generateComponentDiagram([ 'role-sync-data', 'role-notify', ])) diff --git a/doc/resources/midi-fighter-twister-helgoboss.mfs b/resources/controller-specific-files/djtechtools/midi-fighter-twister/midi-fighter-twister-helgoboss.mfs similarity index 100% rename from doc/resources/midi-fighter-twister-helgoboss.mfs rename to resources/controller-specific-files/djtechtools/midi-fighter-twister/midi-fighter-twister-helgoboss.mfs