From 654ea94e16c1c6b72e96f85d84eb3c7a2b172497 Mon Sep 17 00:00:00 2001 From: RobertBeekman Date: Tue, 30 Jan 2024 22:44:45 +0100 Subject: [PATCH 01/12] Swap to a basic DocFX config that hopefully doesn't break every 10 minutes --- .gitignore | 3 +- docfx/docfx_project/api/.gitignore | 5 - docfx/docfx_project/api/index.md | 26 - docfx/docfx_project/docfx.json | 53 +- docfx/docfx_project/docs/getting-started.md | 1 + docfx/docfx_project/docs/introduction.md | 1 + docfx/docfx_project/docs/toc.yml | 4 + docfx/docfx_project/index.md | 29 +- .../templates/singulinkfx/layout/_master.tmpl | 62 -- .../singulinkfx/partials/footer.tmpl.partial | 4 - .../singulinkfx/partials/head.tmpl.partial | 24 - .../singulinkfx/partials/li.tmpl.partial | 31 - .../singulinkfx/partials/logo.tmpl.partial | 6 - .../partials/namespace.tmpl.partial | 13 - .../singulinkfx/partials/navbar.tmpl.partial | 19 - .../singulinkfx/partials/scripts.tmpl.partial | 12 - .../partials/searchResults.tmpl.partial | 9 - .../singulinkfx/partials/toc.tmpl.partial | 5 - .../templates/singulinkfx/styles/config.css | 114 --- .../templates/singulinkfx/styles/discord.css | 681 ------------------ .../singulinkfx/styles/down-arrow.svg | 44 -- .../styles/jquery.twbsPagination.js | 317 -------- .../templates/singulinkfx/styles/main.css | 0 .../templates/singulinkfx/styles/main.js | 0 .../singulinkfx/styles/singulink.css | 471 ------------ .../templates/singulinkfx/styles/singulink.js | 38 - .../templates/singulinkfx/styles/url.min.js | 1 - .../templates/singulinkfx/toc.html.tmpl | 22 - docfx/docfx_project/toc.yml | 6 +- docfx/readme.md | 10 - 30 files changed, 32 insertions(+), 1979 deletions(-) delete mode 100644 docfx/docfx_project/api/.gitignore delete mode 100644 docfx/docfx_project/api/index.md create mode 100644 docfx/docfx_project/docs/getting-started.md create mode 100644 docfx/docfx_project/docs/introduction.md create mode 100644 docfx/docfx_project/docs/toc.yml delete mode 100644 docfx/docfx_project/templates/singulinkfx/layout/_master.tmpl delete mode 100644 docfx/docfx_project/templates/singulinkfx/partials/footer.tmpl.partial delete mode 100644 docfx/docfx_project/templates/singulinkfx/partials/head.tmpl.partial delete mode 100644 docfx/docfx_project/templates/singulinkfx/partials/li.tmpl.partial delete mode 100644 docfx/docfx_project/templates/singulinkfx/partials/logo.tmpl.partial delete mode 100644 docfx/docfx_project/templates/singulinkfx/partials/namespace.tmpl.partial delete mode 100644 docfx/docfx_project/templates/singulinkfx/partials/navbar.tmpl.partial delete mode 100644 docfx/docfx_project/templates/singulinkfx/partials/scripts.tmpl.partial delete mode 100644 docfx/docfx_project/templates/singulinkfx/partials/searchResults.tmpl.partial delete mode 100644 docfx/docfx_project/templates/singulinkfx/partials/toc.tmpl.partial delete mode 100644 docfx/docfx_project/templates/singulinkfx/styles/config.css delete mode 100644 docfx/docfx_project/templates/singulinkfx/styles/discord.css delete mode 100644 docfx/docfx_project/templates/singulinkfx/styles/down-arrow.svg delete mode 100644 docfx/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.js delete mode 100644 docfx/docfx_project/templates/singulinkfx/styles/main.css delete mode 100644 docfx/docfx_project/templates/singulinkfx/styles/main.js delete mode 100644 docfx/docfx_project/templates/singulinkfx/styles/singulink.css delete mode 100644 docfx/docfx_project/templates/singulinkfx/styles/singulink.js delete mode 100644 docfx/docfx_project/templates/singulinkfx/styles/url.min.js delete mode 100644 docfx/docfx_project/templates/singulinkfx/toc.html.tmpl delete mode 100644 docfx/readme.md diff --git a/.gitignore b/.gitignore index e5d811cec..0d5d84996 100644 --- a/.gitignore +++ b/.gitignore @@ -198,4 +198,5 @@ src/Artemis\.Storage/Storage\.db docfx/docfx_project/_site/ src/.idea/ -packages.lock.json \ No newline at end of file +packages.lock.json +docfx/docfx_project/api/ diff --git a/docfx/docfx_project/api/.gitignore b/docfx/docfx_project/api/.gitignore deleted file mode 100644 index e8079a3be..000000000 --- a/docfx/docfx_project/api/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -############### -# temp file # -############### -*.yml -.manifest diff --git a/docfx/docfx_project/api/index.md b/docfx/docfx_project/api/index.md deleted file mode 100644 index 0d7007d2d..000000000 --- a/docfx/docfx_project/api/index.md +++ /dev/null @@ -1,26 +0,0 @@ - -# Welcome to the **Artemis API documentation** -On this website you can browse the Artemis Core and Shared UI API. -A large part of this documentation is being generated based on code but over time the plan is to expand the documentation with written guides. - - -## Plugins -Artemis 2.0 has been developed from the ground up with plugins in mind. This means almost all functionality can be expanded. The following plugin types are currently available and fully implemented: - - [DeviceProvider](api/Artemis.Core.DeviceProviders.DeviceProvider.html) - - [LayerBrush\](api/Artemis.Core.LayerBrushes.LayerBrush-1.html) - - [PerLedLayerBrush\](api/Artemis.Core.LayerBrushes.PerLedLayerBrush-1.html) - - [LayerEffect](api/Artemis.Core.LayerEffects.LayerEffect-1.html) - - [Module](api/Artemis.Core.Modules.Module.html) - - [Module\](api/Artemis.Core.Modules.Module-1.html) - -These allow you to expand on Artemis's functionality. For quick and interactive plugin creation, use the [Visual Studio template extension](https://marketplace.visualstudio.com/items?itemName=SpoinkyNL.ArtemisTemplates). - -Example implementations of these plugins can be found on [GitHub](https://github.com/Artemis-RGB/Artemis/tree/master/src/Plugins). - -## Services -Artemis provides plugins with an API through a range of services. -All the services are available to plugins by using dependency injection in your plugin's constructor. Dependency injection is also available for the different view models plugins may provide. - -- [Core Services](api/Artemis.Core.Services.html#interfaces) -- [UI Services](api/Artemis.UI.Shared.Services.html#interfaces) - diff --git a/docfx/docfx_project/docfx.json b/docfx/docfx_project/docfx.json index 003caa407..7b5a81816 100644 --- a/docfx/docfx_project/docfx.json +++ b/docfx/docfx_project/docfx.json @@ -3,16 +3,14 @@ { "src": [ { + "src": "../../src", "files": [ - "Artemis.Core/bin/net7.0/Artemis.Core.dll", - "Artemis.UI.Shared/bin/net7.0/Artemis.UI.Shared.dll" - ], - "src": "../../src" + "**/Artemis.Core.csproj", + "**/Artemis.UI.Shared.csproj" + ] } ], "dest": "api", - "disableGitFeatures": false, - "disableDefaultFilter": false, "filter": "filterConfig.yml" } ], @@ -20,13 +18,10 @@ "content": [ { "files": [ - "api/**.yml" - ] - }, - { - "files": [ - "toc.yml", - "*.md" + "**/*.{md,yml}" + ], + "exclude": [ + "_site/**" ] } ], @@ -37,42 +32,20 @@ ] } ], - "overwrite": [ - { - "files": [ - "apidoc/**.md" - ], - "exclude": [ - "obj/**", - "_site/**" - ] - } + "output": "_site", + "template": [ + "default", + "modern" ], "globalMetadata": { "_appTitle": "Artemis API Documentation", "_appName": "Artemis", - "_appFaviconPath": "images/application.ico", - "_appLogoPath": "images/application.ico", - "_appFooter": "\r \r\r\r \r\r\r \r\r\r \r\r\r \r", "_copyrightFooter": "Content is available under the PolyForm Noncommercial License, by Artemis RGB.", "_enableSearch": true, "_disableSideFilter": false, "_enableNewTab": true, "_disableContribution": false, "_disableBreadcrumb": false - }, - "dest": "_site", - "globalMetadataFiles": [], - "fileMetadataFiles": [], - "template": [ - "default", - "templates/singulinkfx" - ], - "postProcessors": [], - "markdownEngineName": "markdig", - "noLangKeyword": false, - "keepFileLink": false, - "cleanupCacheHistory": false, - "disableGitFeatures": false + } } } \ No newline at end of file diff --git a/docfx/docfx_project/docs/getting-started.md b/docfx/docfx_project/docs/getting-started.md new file mode 100644 index 000000000..8b3a7945c --- /dev/null +++ b/docfx/docfx_project/docs/getting-started.md @@ -0,0 +1 @@ +# Getting Started \ No newline at end of file diff --git a/docfx/docfx_project/docs/introduction.md b/docfx/docfx_project/docs/introduction.md new file mode 100644 index 000000000..f6ecaa676 --- /dev/null +++ b/docfx/docfx_project/docs/introduction.md @@ -0,0 +1 @@ +# Introduction \ No newline at end of file diff --git a/docfx/docfx_project/docs/toc.yml b/docfx/docfx_project/docs/toc.yml new file mode 100644 index 000000000..d7e9ea8cb --- /dev/null +++ b/docfx/docfx_project/docs/toc.yml @@ -0,0 +1,4 @@ +- name: Introduction + href: introduction.md +- name: Getting Started + href: getting-started.md \ No newline at end of file diff --git a/docfx/docfx_project/index.md b/docfx/docfx_project/index.md index 0d7007d2d..f9859f840 100644 --- a/docfx/docfx_project/index.md +++ b/docfx/docfx_project/index.md @@ -1,26 +1,11 @@ +--- +_layout: landing +--- -# Welcome to the **Artemis API documentation** -On this website you can browse the Artemis Core and Shared UI API. -A large part of this documentation is being generated based on code but over time the plan is to expand the documentation with written guides. +# This is the **HOMEPAGE**. +Refer to [Markdown](http://daringfireball.net/projects/markdown/) for how to write markdown files. -## Plugins -Artemis 2.0 has been developed from the ground up with plugins in mind. This means almost all functionality can be expanded. The following plugin types are currently available and fully implemented: - - [DeviceProvider](api/Artemis.Core.DeviceProviders.DeviceProvider.html) - - [LayerBrush\](api/Artemis.Core.LayerBrushes.LayerBrush-1.html) - - [PerLedLayerBrush\](api/Artemis.Core.LayerBrushes.PerLedLayerBrush-1.html) - - [LayerEffect](api/Artemis.Core.LayerEffects.LayerEffect-1.html) - - [Module](api/Artemis.Core.Modules.Module.html) - - [Module\](api/Artemis.Core.Modules.Module-1.html) - -These allow you to expand on Artemis's functionality. For quick and interactive plugin creation, use the [Visual Studio template extension](https://marketplace.visualstudio.com/items?itemName=SpoinkyNL.ArtemisTemplates). - -Example implementations of these plugins can be found on [GitHub](https://github.com/Artemis-RGB/Artemis/tree/master/src/Plugins). - -## Services -Artemis provides plugins with an API through a range of services. -All the services are available to plugins by using dependency injection in your plugin's constructor. Dependency injection is also available for the different view models plugins may provide. - -- [Core Services](api/Artemis.Core.Services.html#interfaces) -- [UI Services](api/Artemis.UI.Shared.Services.html#interfaces) +## Quick Start Notes: +1. Add images to the *images* folder if the file is referencing an image. \ No newline at end of file diff --git a/docfx/docfx_project/templates/singulinkfx/layout/_master.tmpl b/docfx/docfx_project/templates/singulinkfx/layout/_master.tmpl deleted file mode 100644 index a309bf597..000000000 --- a/docfx/docfx_project/templates/singulinkfx/layout/_master.tmpl +++ /dev/null @@ -1,62 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} -{{!include(/^styles/.*/)}} -{{!include(/^fonts/.*/)}} -{{!include(favicon.ico)}} -{{!include(logo.svg)}} -{{!include(search-stopwords.json)}} - - - - {{>partials/head}} - - -
- - - - - {{>partials/logo}} -
- -
-
- -
-
- {{>partials/navbar}} -
- {{^_disableToc}} - {{>partials/toc}} - {{/_disableToc}} -
- {{>partials/footer}} -
- -
- {{#_enableSearch}} - {{>partials/searchResults}} - {{/_enableSearch}} - -
- {{^_disableBreadcrumb}} - {{>partials/breadcrumb}} - {{/_disableBreadcrumb}} - -
- {{!body}} -
-
- - {{#_copyrightFooter}} -
- {{_copyrightFooter}} -
- {{/_copyrightFooter}} -
-
- - {{>partials/scripts}} - - diff --git a/docfx/docfx_project/templates/singulinkfx/partials/footer.tmpl.partial b/docfx/docfx_project/templates/singulinkfx/partials/footer.tmpl.partial deleted file mode 100644 index dd601a975..000000000 --- a/docfx/docfx_project/templates/singulinkfx/partials/footer.tmpl.partial +++ /dev/null @@ -1,4 +0,0 @@ -
- {{{_appFooter}}} - {{^_appFooter}}DocFX + Singulink = ♥{{/_appFooter}} -
\ No newline at end of file diff --git a/docfx/docfx_project/templates/singulinkfx/partials/head.tmpl.partial b/docfx/docfx_project/templates/singulinkfx/partials/head.tmpl.partial deleted file mode 100644 index 01f8b6393..000000000 --- a/docfx/docfx_project/templates/singulinkfx/partials/head.tmpl.partial +++ /dev/null @@ -1,24 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - - - - {{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}} - - - - {{#_description}}{{/_description}} - - - - - - - - - - - {{#_noindex}}{{/_noindex}} - {{#_enableSearch}}{{/_enableSearch}} - {{#_enableNewTab}}{{/_enableNewTab}} - \ No newline at end of file diff --git a/docfx/docfx_project/templates/singulinkfx/partials/li.tmpl.partial b/docfx/docfx_project/templates/singulinkfx/partials/li.tmpl.partial deleted file mode 100644 index 2c8a3d0e7..000000000 --- a/docfx/docfx_project/templates/singulinkfx/partials/li.tmpl.partial +++ /dev/null @@ -1,31 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - -
    - {{#items}} - {{^dropdown}} -
  • - {{^leaf}} - - {{/leaf}} - {{#topicHref}} - {{name}} - {{/topicHref}} - {{^topicHref}} - {{{name}}} - {{/topicHref}} - - {{^leaf}} - {{>partials/li}} - {{/leaf}} -
  • - {{/dropdown}} - {{#dropdown}} -
  • - {{name}} -
      - {{>partials/dd-li}} -
    -
  • - {{/dropdown}} - {{/items}} -
diff --git a/docfx/docfx_project/templates/singulinkfx/partials/logo.tmpl.partial b/docfx/docfx_project/templates/singulinkfx/partials/logo.tmpl.partial deleted file mode 100644 index 738ab5b6f..000000000 --- a/docfx/docfx_project/templates/singulinkfx/partials/logo.tmpl.partial +++ /dev/null @@ -1,6 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - - {{_appName}} - {{_appName}} - \ No newline at end of file diff --git a/docfx/docfx_project/templates/singulinkfx/partials/namespace.tmpl.partial b/docfx/docfx_project/templates/singulinkfx/partials/namespace.tmpl.partial deleted file mode 100644 index 42d64e69b..000000000 --- a/docfx/docfx_project/templates/singulinkfx/partials/namespace.tmpl.partial +++ /dev/null @@ -1,13 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - -

{{>partials/title}}

-
{{{summary}}}
-
{{{conceptual}}}
-
{{{remarks}}}
-{{#children}} -

{{>partials/namespaceSubtitle}}

- {{#children}} -
-
{{{summary}}}
- {{/children}} -{{/children}} diff --git a/docfx/docfx_project/templates/singulinkfx/partials/navbar.tmpl.partial b/docfx/docfx_project/templates/singulinkfx/partials/navbar.tmpl.partial deleted file mode 100644 index cfddfd830..000000000 --- a/docfx/docfx_project/templates/singulinkfx/partials/navbar.tmpl.partial +++ /dev/null @@ -1,19 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - -
-
- {{>partials/logo}} -
- - {{#_enableSearch}} -
-
- - -
-
- {{/_enableSearch}} - -
-
-
\ No newline at end of file diff --git a/docfx/docfx_project/templates/singulinkfx/partials/scripts.tmpl.partial b/docfx/docfx_project/templates/singulinkfx/partials/scripts.tmpl.partial deleted file mode 100644 index 90fb7d576..000000000 --- a/docfx/docfx_project/templates/singulinkfx/partials/scripts.tmpl.partial +++ /dev/null @@ -1,12 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - - - - - - - - - - \ No newline at end of file diff --git a/docfx/docfx_project/templates/singulinkfx/partials/searchResults.tmpl.partial b/docfx/docfx_project/templates/singulinkfx/partials/searchResults.tmpl.partial deleted file mode 100644 index 9f08c90e3..000000000 --- a/docfx/docfx_project/templates/singulinkfx/partials/searchResults.tmpl.partial +++ /dev/null @@ -1,9 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - -
-

{{__global.searchResults}}

-
-

-
-
    -
    \ No newline at end of file diff --git a/docfx/docfx_project/templates/singulinkfx/partials/toc.tmpl.partial b/docfx/docfx_project/templates/singulinkfx/partials/toc.tmpl.partial deleted file mode 100644 index c660966b6..000000000 --- a/docfx/docfx_project/templates/singulinkfx/partials/toc.tmpl.partial +++ /dev/null @@ -1,5 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - -
    -
    -
    diff --git a/docfx/docfx_project/templates/singulinkfx/styles/config.css b/docfx/docfx_project/templates/singulinkfx/styles/config.css deleted file mode 100644 index 9f3ca697b..000000000 --- a/docfx/docfx_project/templates/singulinkfx/styles/config.css +++ /dev/null @@ -1,114 +0,0 @@ -/* Theme Configuration Options */ - -:root -{ - /* General */ - - --base-font-size: 16px; - --smalldevice-base-font-size: 14px; /* Base font size for devices < 1024px */ - - --main-bg-color: #1f1f23; - --footer-bg-color: rgba(0,0,0,.4); - --separator-color: #42474f; - - --table-strip-bg-color: #151515; - --table-header-bg-color: black; - --table-header-color: hsla(0,0%,100%,.8); - --table-header-border-color: #040405; - - /* Text */ - - --appname-color: white; - - --h1-color: white; - --h2-color: #f2f2f2; - --h3-color: #e3e3e3; - --h4-color: #ffffff; - --h5-color: #e0e0e0; - - --text-color: #e1e1e1; - --link-color: #00b0f4; - --link-hover-color: #2ec4ff; - - /* Mobile Topbar */ - - --topbar-bg-color: #18191c; - - /* Button */ - - --button-color: #747f8d; - - /* Sidebar */ - - --sidebar-width: 400px; - --sidebar-bg-color: #292B30; - - --search-color: #bdbdbd; - --search-bg-color: #1b1e21; - --search-searchicon-color: #e3e3e3; - --search-border-color: black; - - --sidebar-item-color: white; - --sidebar-active-item-color: #00b0f4; - --sidebar-level1-item-bg-color: #222429; - --sidebar-level1-item-hover-bg-color: #1D1F22; - - --toc-filter-color: #bdbdbd; - --toc-filter-bg-color: #1b1e21; - --toc-filter-filtericon-color: #e3e3e3; - --toc-filter-clearicon-color: #e68585; - --toc-filter-border-color: black; - - /* Scrollbars */ - - --scrollbar-bg-color: transparent; - --scrollbar-thumb-bg-color: rgba(0,0,0,.4); - --scrollbar-thumb-border-color: transparent; - - /* Alerts and Blocks */ - - --alert-info-border-color: rgba(114,137,218,.5); - --alert-info-bg-color: rgba(114,137,218,.1); - - --alert-warning-border-color: rgba(250,166,26,.5); - --alert-warning-bg-color: rgba(250,166,26,.1); - - --alert-danger-border-color: rgba(240,71,71,.5); - --alert-danger-bg-color: rgba(240,71,71,.1); - - --alert-tip-border-color: rgba(255,255,255,.5); - --alert-tip-bg-color: rgba(255,255,255,.1); - - --blockquote-border-color: rgba(255,255,255,.5); - --blockquote-bg-color: rgba(255,255,255,.1); - - --breadcrumb-bg-color: #2f3136; - - /* Inline Code */ - - --ref-bg-color: black; - --ref-color: #89d4f1; - - /* Code Blocks */ - - --code-bg-color: #151515; - --code-color: #d6deeb; - --code-keyword-color: #569cd6; - --code-comment-color: #57a64a; - --code-macro-color: #beb7ff; - --code-string-color: #d69d85; - --code-string-escape-color: #ffd68f; - --code-field-color: #c8c8c8; - --code-function-color: #dcdcaa; - --code-control-color: #d8a0df; - --code-class-color: #4ec9b0; - --code-number-color: #b5cea8; - --code-params-color: #9a9a9a; - --code-breakpoint-color: #8c2f2f; -} - -/* Code Block Overrides */ - -pre, legend { - --scrollbar-thumb-bg-color: #333; -} \ No newline at end of file diff --git a/docfx/docfx_project/templates/singulinkfx/styles/discord.css b/docfx/docfx_project/templates/singulinkfx/styles/discord.css deleted file mode 100644 index bb3e55a06..000000000 --- a/docfx/docfx_project/templates/singulinkfx/styles/discord.css +++ /dev/null @@ -1,681 +0,0 @@ -/* Discord Style */ - -::-webkit-scrollbar { - width: 10px; -} - -::-webkit-scrollbar-track { - background: var(--scrollbar-bg-color); -} - -::-webkit-scrollbar-thumb { - background: var(--scrollbar-thumb-bg-color); - border-color: var(--scrollbar-thumb-border-color); - border-radius: 5px; -} - -::marker { - unicode-bidi: isolate; - font-variant-numeric: tabular-nums; - text-transform: none; - text-indent: 0px !important; - text-align: start !important; - text-align-last: start !important; -} - -*, :after, :before -{ - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -html, body -{ - padding: 0; - margin: 0; - font: 15px/150% 'Roboto', sans-serif; - overflow: hidden; - color: var(--text-color); - background-color: var(--main-bg-color); - - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; -} - -img { - max-width: 100%; -} - -ul > li, ol > li { - display: list-item; -} - -h1,h2,h3,h4,h5 -{ - color: var(--link-active-color); - position: relative; -} - -h1, h2 -{ - margin-block-start: 2em; -} - -h3 -{ - margin-block-start: 1em; - font-weight: 300; - font-size: 1.5em; - color: var(--h3-color); - margin-block-start: 3em; -} - -h4 -{ - opacity: 1; - color: var(--h4-color); - font-size: large; - border-bottom: 2px solid var(--separator-color); - margin: 20px 0 0 0; -} - - -h5 { - margin-block-end: .8em; - margin-block-start: 1em; - font-size: .85em; - font-weight: 500; - color: var(--h5-color); -} - -h6 { - font-size: .75em; - margin: 0; -} - -p -{ - font-weight: 400; -} - -ul -{ - position: relative; -} - -ul, ol -{ - padding-inline-start: 3em; -} - -ul.level1 -{ - list-style-type: none; - padding-inline-start: 0; -} - -ul.level2, ul.level3 -{ - padding-inline-start: 1em; - list-style-type: none; - font-size: .9em; -} - -a -{ - color: var(--link-color); - text-decoration: none; - transition: color .25s; -} - -a:focus, a:hover -{ - color: var(--link-hover-color); - text-decoration: underline; -} - -a.anchorjs-link:hover { - text-decoration: none; -} - -a.active, a:active -{ - color: var(--link-active-color); -} - -.body-content -{ - display: flex; - flex-direction: row; - height: 100%; - overflow-x: hidden; - overflow-y: hidden; -} - -.page-title -{ - margin-block-start: 0; -} - -nav -{ - width: 300px; - transition: left .5s ease-out; - position: fixed; - left: -350px; - top: 40px; - bottom: 0; - background-color: var(--sidebar-bg-color); - overflow-y: auto; - - display: flex; - flex-direction: column; - - z-index: 1000; -} - -h1:first-child -{ - margin-block-start: 1.1em; - margin-top: 1.1em; -} - -.sidebar -{ - padding: 32px 17px 32px 32px; - flex: 1; -} - -.sidebar-item -{ - font-size: 1em; - font-weight: 400; - display: block; - padding: 4px 16px; - color: var(--sidebar-item-color); -} - -.sidebar-item.large, #navbar .sidebar-item -{ - padding: 8px 16px; -} - -a.sidebar-item:hover, a.sidebar-item:focus -{ - color: var(--link-active-color); - text-decoration: none; -} - -a.sidebar-item.active -{ - color: var(--link-active-color); -} - -ul.level1 > li > a.sidebar-item -{ - background-color: transparent; - border-radius: 4px; -} - -#toc ul.level1 > li > a.sidebar-item.active -{ - background-color: var(--link-active-bg-color); -} - -.sidebar-item-separator -{ - height: 2px; - width: 100%; - background-color: var(--separator-color); - margin: 2em 0; - opacity: .8; -} - -span.sidebar-item -{ - font-weight: 700; - text-transform: uppercase; - font-size: .8em; - color: var(--text-color); - margin-block-start: 1.25em; -} - -.main-panel -{ - background-color: var(--main-bg-color); - flex: 1; - overflow-y: auto; - padding: 20px 40px; -} - -.top-navbar -{ - display: flex; - flex-direction: row; - align-items: center; - padding: 0 40px; - height: 40px; - background-color: var(--topbar-bg-color); -} - -.burger-icon -{ - margin-right: 1em; - color: var(--button-color); -} - -.burger-icon:hover, .burger-icon:focus -{ - color: var(--link-active-color); -} - -.burger-icon.active, .burger-icon:active -{ - color: var(--link-active-color); -} - -.brand -{ - display: flex; - align-items: center; - justify-content: start; -} - -.logomark -{ - height: 28px; -} - -.brand-title -{ - padding: 0 .5em; - font-size: .9em; - color: var(--link-active-color); -} - -.footer -{ - background-color: var(--footer-bg-color); - padding: 20px; - margin: 0 20px 20px 20px; - border-radius: 8px; - color: var(--link-active-color); -} - -.footer > h4 -{ - margin-block-start: 0; -} - -.blackout -{ - display: block; - visibility: hidden; - position: absolute; - z-index: 100; - top: 40px; - bottom: 0; - left: 0; - right: 0; - background-color: var(--footer-bg-color); -} - -@keyframes showThat { - 0% { opacity: 0; visibility: hidden; } - 1% { opacity: 0; visibility: visible; } - 100% { opacity: 1; visibility: visible;} -} - -@keyframes hideThat { - 0% { opacity: 1; visibility: visible; } - 99% { opacity: 0; visibility: visible; } - 100% { opacity: 0; visibility: hidden;} -} - -.showThat -{ - animation: showThat .5s forwards; -} - -.hideThat -{ - animation: hideThat .5s forwards; -} - - - -@media (min-width: 1024px) -{ - nav - { - position: relative; - left: 0!important; - top: 0; - bottom: 0; - } - - .top-navbar - { - display: none; - } - - .blackout - { - display: none; - } -} - -/* Table */ - -.table-responsive -{ - overflow-x: auto; - margin-bottom: 64px; -} - -table -{ - background-color: var(--code-bg-color); - border-collapse: collapse; - width: 100%; - table-layout: auto; -} - -table.table-striped tbody tr:nth-child(2n) -{ - background-color: var(--table-strip-bg-color); -} - -table thead -{ - background: var(--table-header-bg-color); -} - -table th -{ - color: var(--table-header-color); - text-transform: uppercase; - font-size: 12px; - line-height: 15px; - border-bottom: 1px solid var(--table-header-border-color); - padding: 8px; -} - -.table-condensed th { - text-align: left; -} - -table td -{ - padding: 8px; - font-weight: 300; -} - -table td > p -{ - margin: 0; -} - -/* Alerts */ -.alert { - border-radius: 4px; - padding: 8px; - margin: 25px 0; -} - -.alert > h5 -{ - display: none; - margin: 0; -} - -.alert > p -{ - margin: 0; - font-weight: 300; - font-size: 13px; -} - -.alert.alert-info -{ - border: 2px solid var(--alert-info-border-color); - background: var(--alert-info-bg-color); -} - -.alert.alert-warning -{ - border: 2px solid var(--alert-warning-border-color); - background: var(--alert-warning-bg-color); -} - -.alert.alert-danger -{ - border: 2px solid var(--alert-danger-border-color); - background: var(--alert-danger-bg-color); -} - -.TIP.alert.alert-info -{ - border: 2px solid var(--alert-tip-border-color); - background: var(--alert-tip-bg-color); -} - -blockquote { - margin: 8px 0; - border-left: 4px solid var(--blockquote-border-color); - padding: 8px; - background: var(--blockquote-bg-color); - border-radius: 4px; -} - -blockquote > p { - margin: 0; - font-style: italic; - font-size: 13px; -} - - -/* Breadcrumb */ - -#breadcrumb -{ - padding: 8px 16px; - background: var(--breadcrumb-bg-color); - border-radius: 4px; - margin-bottom: 30px; -} - -#breadcrumb:empty -{ - display: none; -} - -ul.breadcrumb -{ - display: flex; - flex-direction: row; - margin: 0; -} - -ul.breadcrumb > li { - margin-right: 6px; -} - -ul.breadcrumb > li::before -{ - content: "/"; - margin-right: 5px; -} - -ul.breadcrumb > li:first-child::before -{ - content: ""; - margin: 0; -} - - -/* Code */ - -legend, pre -{ - display: block; - background-color: var(--code-bg-color); - padding: 16px; - border-radius: 4px; -} - -code -{ - background-color: var(--code-bg-color); - padding: 2px 4px; - border-radius: 4px; -} - -.hljs -{ - background: transparent; -} - -/* DocFX related */ - -.small { - font-size: .9em; -} - -.pull-right -{ - float: right; -} - -.hide -{ - display: none; -} - -@media (max-width: 1023.98px) -{ - .mobile-hide - { - display: none; - } -} - -li -{ - display: block; - position: relative; -} - -.expand-stub -{ - cursor: pointer; - position: absolute; - width: 20px; - height: 20px; - left: -10px; -} - -ul.level1 > li > .expand-stub -{ - display: none; -} - -.toc .nav > li > .expand-stub::before, .toc .nav > li.active > .expand-stub::before -{ - content: " "; - position: absolute; - transform: rotate(-90deg); - width: 10px; - height: 10px; - top: 5px; - left: 5px; - background-repeat: no-repeat; - background: url(down-arrow.svg); -} - -.toc .nav > li.active > .expand-stub::before, .toc .nav > li.in > .expand-stub::before, .toc .nav > li.in.active > .expand-stub::before, .toc .nav > li.filtered > .expand-stub::before -{ - transform: none; -} - -li > ul -{ - display: none; -} - -li.in > ul -{ - display: block; -} - -ul.level2 > li > a.sidebar-item, -ul.level3 > li > a.sidebar-item -{ - font-weight: 500; - font-size: .95em; - padding: 0; - margin: 2px 16px; -} - -ul.level2 > li > a.sidebar-item -{ - color: var(--sidebar-item-2nd-color); -} - -ul.level3 > li > a.sidebar-item -{ - color: var(--sidebar-item-3rd-color); -} - -ul.level2 > li > a.sidebar-item:hover, -ul.level2 > li > a.sidebar-item:focus, -ul.level3 > li > a.sidebar-item:hover, -ul.level3 > li > a.sidebar-item:focus -{ - color: var(--link-active-color); - text-decoration: underline; -} - -ul.level2 > li > a.sidebar-item.active, -ul.level3 > li > a.sidebar-item.active -{ - color: var(--link-active-color); -} - -.inheritance .level0:before, -.inheritance .level1:before, -.inheritance .level2:before, -.inheritance .level3:before, -.inheritance .level4:before, -.inheritance .level5:before { - content: '↳'; - margin-right: 5px; -} - -.inheritance .level0 { - margin-left: 0em; -} - -.inheritance .level1 { - margin-left: 1em; -} - -.inheritance .level2 { - margin-left: 2em; -} - -.inheritance .level3 { - margin-left: 3em; -} - -.inheritance .level4 { - margin-left: 4em; -} - -.inheritance .level5 { - margin-left: 5em; -} \ No newline at end of file diff --git a/docfx/docfx_project/templates/singulinkfx/styles/down-arrow.svg b/docfx/docfx_project/templates/singulinkfx/styles/down-arrow.svg deleted file mode 100644 index e086126a2..000000000 --- a/docfx/docfx_project/templates/singulinkfx/styles/down-arrow.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docfx/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.js b/docfx/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.js deleted file mode 100644 index 332c01c62..000000000 --- a/docfx/docfx_project/templates/singulinkfx/styles/jquery.twbsPagination.js +++ /dev/null @@ -1,317 +0,0 @@ -/*! - * jQuery pagination plugin v1.4.1 - * http://esimakin.github.io/twbs-pagination/ - * - * Copyright 2014-2016, Eugene Simakin - * Released under Apache 2.0 license - * http://apache.org/licenses/LICENSE-2.0.html - */ -(function ($, window, document, undefined) { - - 'use strict'; - - var old = $.fn.twbsPagination; - - // PROTOTYPE AND CONSTRUCTOR - - var TwbsPagination = function (element, options) { - this.$element = $(element); - this.options = $.extend({}, $.fn.twbsPagination.defaults, options); - - if (this.options.startPage < 1 || this.options.startPage > this.options.totalPages) { - throw new Error('Start page option is incorrect'); - } - - this.options.totalPages = parseInt(this.options.totalPages); - if (isNaN(this.options.totalPages)) { - throw new Error('Total pages option is not correct!'); - } - - this.options.visiblePages = parseInt(this.options.visiblePages); - if (isNaN(this.options.visiblePages)) { - throw new Error('Visible pages option is not correct!'); - } - - if (this.options.onPageClick instanceof Function) { - this.$element.first().on('page', this.options.onPageClick); - } - - // hide if only one page exists - if (this.options.hideOnlyOnePage && this.options.totalPages == 1) { - this.$element.trigger('page', 1); - return this; - } - - if (this.options.totalPages < this.options.visiblePages) { - this.options.visiblePages = this.options.totalPages; - } - - if (this.options.href) { - this.options.startPage = this.getPageFromQueryString(); - if (!this.options.startPage) { - this.options.startPage = 1; - } - } - - var tagName = (typeof this.$element.prop === 'function') ? - this.$element.prop('tagName') : this.$element.attr('tagName'); - - if (tagName === 'UL') { - this.$listContainer = this.$element; - } else { - this.$listContainer = $('
      '); - } - - this.$listContainer.addClass(this.options.paginationClass); - - if (tagName !== 'UL') { - this.$element.append(this.$listContainer); - } - - if (this.options.initiateStartPageClick) { - this.show(this.options.startPage); - } else { - this.render(this.getPages(this.options.startPage)); - this.setupEvents(); - } - - return this; - }; - - TwbsPagination.prototype = { - - constructor: TwbsPagination, - - destroy: function () { - this.$element.empty(); - this.$element.removeData('twbs-pagination'); - this.$element.off('page'); - - return this; - }, - - show: function (page) { - if (page < 1 || page > this.options.totalPages) { - throw new Error('Page is incorrect.'); - } - this.currentPage = page; - - this.render(this.getPages(page)); - this.setupEvents(); - - this.$element.trigger('page', page); - - return this; - }, - - buildListItems: function (pages) { - var listItems = []; - - if (this.options.first) { - listItems.push(this.buildItem('first', 1)); - } - - if (this.options.prev) { - var prev = pages.currentPage > 1 ? pages.currentPage - 1 : this.options.loop ? this.options.totalPages : 1; - listItems.push(this.buildItem('prev', prev)); - } - - for (var i = 0; i < pages.numeric.length; i++) { - listItems.push(this.buildItem('page', pages.numeric[i])); - } - - if (this.options.next) { - var next = pages.currentPage < this.options.totalPages ? pages.currentPage + 1 : this.options.loop ? 1 : this.options.totalPages; - listItems.push(this.buildItem('next', next)); - } - - if (this.options.last) { - listItems.push(this.buildItem('last', this.options.totalPages)); - } - - return listItems; - }, - - buildItem: function (type, page) { - var $itemContainer = $('
    • '), - $itemContent = $(''), - itemText = this.options[type] ? this.makeText(this.options[type], page) : page; - - $itemContainer.addClass(this.options[type + 'Class']); - $itemContainer.data('page', page); - $itemContainer.data('page-type', type); - $itemContainer.append($itemContent.attr('href', this.makeHref(page)).addClass(this.options.anchorClass).html(itemText)); - - return $itemContainer; - }, - - getPages: function (currentPage) { - var pages = []; - - var half = Math.floor(this.options.visiblePages / 2); - var start = currentPage - half + 1 - this.options.visiblePages % 2; - var end = currentPage + half; - - // handle boundary case - if (start <= 0) { - start = 1; - end = this.options.visiblePages; - } - if (end > this.options.totalPages) { - start = this.options.totalPages - this.options.visiblePages + 1; - end = this.options.totalPages; - } - - var itPage = start; - while (itPage <= end) { - pages.push(itPage); - itPage++; - } - - return {"currentPage": currentPage, "numeric": pages}; - }, - - render: function (pages) { - var _this = this; - this.$listContainer.children().remove(); - var items = this.buildListItems(pages); - jQuery.each(items, function(key, item){ - _this.$listContainer.append(item); - }); - - this.$listContainer.children().each(function () { - var $this = $(this), - pageType = $this.data('page-type'); - - switch (pageType) { - case 'page': - if ($this.data('page') === pages.currentPage) { - $this.addClass(_this.options.activeClass); - } - break; - case 'first': - $this.toggleClass(_this.options.disabledClass, pages.currentPage === 1); - break; - case 'last': - $this.toggleClass(_this.options.disabledClass, pages.currentPage === _this.options.totalPages); - break; - case 'prev': - $this.toggleClass(_this.options.disabledClass, !_this.options.loop && pages.currentPage === 1); - break; - case 'next': - $this.toggleClass(_this.options.disabledClass, - !_this.options.loop && pages.currentPage === _this.options.totalPages); - break; - default: - break; - } - - }); - }, - - setupEvents: function () { - var _this = this; - this.$listContainer.off('click').on('click', 'li', function (evt) { - var $this = $(this); - if ($this.hasClass(_this.options.disabledClass) || $this.hasClass(_this.options.activeClass)) { - return false; - } - // Prevent click event if href is not set. - !_this.options.href && evt.preventDefault(); - _this.show(parseInt($this.data('page'))); - }); - }, - - makeHref: function (page) { - return this.options.href ? this.generateQueryString(page) : "#"; - }, - - makeText: function (text, page) { - return text.replace(this.options.pageVariable, page) - .replace(this.options.totalPagesVariable, this.options.totalPages) - }, - getPageFromQueryString: function (searchStr) { - var search = this.getSearchString(searchStr), - regex = new RegExp(this.options.pageVariable + '(=([^&#]*)|&|#|$)'), - page = regex.exec(search); - if (!page || !page[2]) { - return null; - } - page = decodeURIComponent(page[2]); - page = parseInt(page); - if (isNaN(page)) { - return null; - } - return page; - }, - generateQueryString: function (pageNumber, searchStr) { - var search = this.getSearchString(searchStr), - regex = new RegExp(this.options.pageVariable + '=*[^&#]*'); - if (!search) return ''; - return '?' + search.replace(regex, this.options.pageVariable + '=' + pageNumber); - - }, - getSearchString: function (searchStr) { - var search = searchStr || window.location.search; - if (search === '') { - return null; - } - if (search.indexOf('?') === 0) search = search.substr(1); - return search; - } - - }; - - // PLUGIN DEFINITION - - $.fn.twbsPagination = function (option) { - var args = Array.prototype.slice.call(arguments, 1); - var methodReturn; - - var $this = $(this); - var data = $this.data('twbs-pagination'); - var options = typeof option === 'object' ? option : {}; - - if (!data) $this.data('twbs-pagination', (data = new TwbsPagination(this, options) )); - if (typeof option === 'string') methodReturn = data[ option ].apply(data, args); - - return ( methodReturn === undefined ) ? $this : methodReturn; - }; - - $.fn.twbsPagination.defaults = { - totalPages: 1, - startPage: 1, - visiblePages: 5, - initiateStartPageClick: true, - hideOnlyOnePage: false, - href: false, - pageVariable: '{{page}}', - totalPagesVariable: '{{total_pages}}', - page: null, - first: 'First', - prev: 'Previous', - next: 'Next', - last: 'Last', - loop: false, - onPageClick: null, - paginationClass: 'pagination', - nextClass: 'page-item next', - prevClass: 'page-item prev', - lastClass: 'page-item last', - firstClass: 'page-item first', - pageClass: 'page-item', - activeClass: 'active', - disabledClass: 'disabled', - anchorClass: 'page-link' - }; - - $.fn.twbsPagination.Constructor = TwbsPagination; - - $.fn.twbsPagination.noConflict = function () { - $.fn.twbsPagination = old; - return this; - }; - - $.fn.twbsPagination.version = "1.4.1"; - -})(window.jQuery, window, document); diff --git a/docfx/docfx_project/templates/singulinkfx/styles/main.css b/docfx/docfx_project/templates/singulinkfx/styles/main.css deleted file mode 100644 index e69de29bb..000000000 diff --git a/docfx/docfx_project/templates/singulinkfx/styles/main.js b/docfx/docfx_project/templates/singulinkfx/styles/main.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/docfx/docfx_project/templates/singulinkfx/styles/singulink.css b/docfx/docfx_project/templates/singulinkfx/styles/singulink.css deleted file mode 100644 index b7200ca68..000000000 --- a/docfx/docfx_project/templates/singulinkfx/styles/singulink.css +++ /dev/null @@ -1,471 +0,0 @@ -body { - font-size: var(--base-font-size); -} - -@media (max-width: 1024px) { - body { - font-size: var(--smalldevice-base-font-size); - } -} - -/* Headings */ - -h1, h2, h3, h4, h5 { - line-height: initial; -} - -h1, h1:first-child { - font-size: 2.25em; - letter-spacing: 0.5px; - color: var(--h1-color); - margin-block-start: 1em; - margin-block-end: -0.05em; -} - -.article h1 { - margin-block-end: -0.2em; -} - -h2 { - font-size: 2.1em; - color: var(--h2-color); -} - -.article h2 { - margin-block-start: 1.3em; - padding-bottom: 6px; - border-bottom: 1px solid var(--separator-color); -} - -h3 { - font-size: 1.95em; - font-weight: 500; - margin-block-start: 1.7em; -} - -.article h3 { - font-size: 1.85em; - font-weight: 500; - margin-block-start: 1.2em; - margin-block-end: 0.9em; -} - -h4 { - font-size: 1.8em; - font-weight: 400; - margin-block-start: 2em; - padding-bottom: 10px; -} - -.article h4 { - font-size: 1.5em; - font-weight: 300; - margin-block-start: 1em; - margin-block-end: 1em; - padding-bottom: 0; - border-bottom: none; -} - -h5 { - font-size: 1.1em; -} - -.article h5 { - font-size: 1.13em; - font-weight: 400; - text-decoration: underline; - margin-block-start: 1.5em; - margin-block-end: 1.0em; -} - -a.brand:hover -{ - text-decoration: none; -} - -a.brand .brand-title { - font-size: 1.4em; - font-weight: 500; - letter-spacing: 0.5px; - color: var(--appname-color); - margin-top: 1px; - padding: 0 0 0 0.4em; -} - -@media (min-width: 1024px) { - a.brand .brand-title { - font-size: 1.55em; - } -} - - -a.brand .logomark { - height: 35px; -} - -/* Top bar */ - -.top-navbar { - height: 60px; - padding: 0 0 0 10px; -} - -.burger-icon { - margin-right: 10px; -} - -/* Side Bar */ - -.sidebar { - padding: 25px 17px 32px 17px; -} - -.blackout { - top: 60px; -} - -@media (max-width: 1023.98px) { - .navbar-nav { - margin-top: 0; - } -} - -nav { - width: 94%; - max-width: var(--sidebar-width); - left: calc(var(--sidebar-width) * -1); -} - -@media (max-width: 1023.98px) { - nav { - top: 60px; - } -} - -nav ul { - list-style-type: none; -} - -nav .nav a, nav .nav a:hover { - text-decoration: none; - cursor: pointer; - display: block; -} - -nav a.sidebar-item { - padding: 4px 0 4px 10px; - cursor: pointer; -} - -nav a:focus, nav a.sidebar-item:hover, nav a.sidebar-item:focus { - text-decoration: underline; -} - -nav a, nav a:hover, nav a:focus { - color: var(--sidebar-item-color) !important; -} - -nav a.active, nav a.active:hover, nav a.active:focus { - color: var(--sidebar-active-item-color) !important; -} - -.sidebar-item-separator { - margin: 20px 0; -} - -#toc ul li a { - padding: 0 0 0 10px; -} - -.search { - background: var(--search-bg-color); - border: 1px solid var(--search-border-color); - border-radius: 5px; - position: relative; - margin-block-start: 25px; -} - -@media (max-width: 1023.98px) { - .search { - margin-block-start: 0; - margin-block-end: 15px; - } -} - -.search > input { - font-size: 0.95em; - color: var(--search-color); - border: 0; - background: none; - padding: 11px 30px 10px 37px; - width: 100%; -} - -.search > input:focus { - outline: 0; -} - -.search > .search-icon { - font-size: 1.2em; - color: var(--search-searchicon-color); - position: absolute; - top: 9px; - left: 9px; -} - -.toc-filter { - background: var(--toc-filter-bg-color); - border: 1px solid var(--toc-filter-border-color); - border-radius: 5px; - position: relative; -} - -.toc-filter > input { - font-size: 0.95em; - color: var(--toc-filter-color); - border: 0; - background: none; - padding: 11px 30px 10px 37px; - width: 100%; -} - -.toc-filter > input:focus { - outline: 0; -} - -.toc-filter > .filter-icon { - font-size: 1.2em; - color: var(--toc-filter-filtericon-color); - position: absolute; - top: 9px; - left: 9px; -} - -.toc-filter > .clear-icon { - color: var(--toc-filter-clearicon-color); - position: absolute; - top: 9px; - right: 9px; - cursor: pointer; -} - -.toc .nav > li > .expand-stub::before, .toc .nav > li.active > .expand-stub::before -{ - width: 8px; - height: 8px; - top: 6px; - left: 6px; -} - -#toc ul.level2 -{ - margin-bottom: 20px; -} - -#toc ul.level1 > li > a { - font-weight: 500; - margin-bottom: 10px; - padding: 5px 10px; -} - -#toc ul.level1 > li > a, #toc ul.level1 > li > a.active { - background-color: var(--sidebar-level1-item-bg-color) !important; - border-radius: 2px; -} - -#toc ul.level1 > li > a:hover, #toc ul.level1 > li > a.active:hover, -#toc ul.level1 > li > a:focus, #toc ul.level1 > li > a.active:focus { - background-color: var(--sidebar-level1-item-hover-bg-color) !important; - text-decoration: none; -} - -ul.level2 { - padding-inline-start: 0.7em; -} - -ul.level2 .expand-stub { - top: 1px; -} - -ul.level2 > li > a, ul.level2 > li > a.sidebar-item { - font-weight: 400; - color: var(--sidebar-item-color); - margin: 4px 0 4px; -} - -ul.level3 { - padding-inline-start: 1em; -} - -ul.level3 > li > a, ul.level3 > li > a.sidebar-item { - font-size: 1.05em; - color: var(--sidebar-item-color); - margin: 4px 0; -} - -ul.level4 { - padding-inline-start: 0; - margin-bottom: 12px; -} - -ul.level4 > li > a, ul.level4 > li > a.sidebar-item { - font-size: 1.05em; - color: var(--sidebar-item-color); - margin: 5px 0 5px 10px; -} - -/* Breadcrumbs */ - -.subnav.navbar { - margin: 0 -15px; -} - -#breadcrumb { - overflow: scroll; - margin-bottom: 0; -} - -#breadcrumb::-webkit-scrollbar { - display: none; -} - -#breadcrumb a { - white-space: nowrap; -} - -#breadcrumb wbr { - display: none; -} - -/* Search Results */ - -#search-results h1 { - margin-block-start: 0.5em; -} - -#search-results .item-title { - font-size: 1.3em; - margin-top: 1.5em; -} - -#search-results .item-href { - font-size: 0.85em; -} - -#search-results .item-brief { - margin-top: 0.7em; -} - -#search-results ul.pagination { - text-align: center; - padding: 10px 0 0 0; - margin-block-start: 40px; - border-top: 1px solid var(--separator-color); -} - -#search-results ul.pagination > li { - display: inline-block; - margin: 0 10px; -} - -#search-results ul.pagination > li.disabled a, #search-results ul.pagination > li.disabled a:hover { - color: var(--text-color); - cursor: txt; - text-decoration: none; -} - -/* Content */ - -.main-panel { - margin-bottom: 60px; - padding: 20px; -} - -@media (min-width: 1024px) { - .main-panel { - margin-bottom: 0; - padding: 20px 40px; - } -} - -.pull-right { - margin-top: 70px; - /* Fix unclickable links */ - position: relative; - z-index: 1; -} - -.divider { - margin-left: 4px; -} - -article ul li, article ol li { - margin-bottom: 10px; -} - -legend, pre { - padding: 6px; -} - -.hljs { - color: var(--code-color); -} - -.hljs::-webkit-scrollbar { - height: 6px; -} - -.hljs-keyword, .hljs-title, .hljs-built_in { - font-style: normal; -} - -p .xref, code { - background-color: var(--ref-bg-color); - color: var(--ref-color); - padding: 2px 3px; - font-family: monospace; - font-size: 0.95em; - border-radius: 6px; -} - -span.parametername { - font-family: monospace; -} - -.table { - width: auto; -} - -.table-responsive { - margin-bottom: 0; -} - -table th { - font-size: 14px; - padding: 9px 10px; -} - -table td p { - font-weight: 300; -} - -table td { - padding: 6px 10px; -} - -.footer { - text-align: center; - color: var(--text-color); - padding: 10px; -} - -.footer a:hover, .footer a:focus { - text-decoration: underline; -} - -.copyright-footer { - font-size: 0.85em; - font-weight: bold; - text-align: center; - margin-block-start: 30px; -} \ No newline at end of file diff --git a/docfx/docfx_project/templates/singulinkfx/styles/singulink.js b/docfx/docfx_project/templates/singulinkfx/styles/singulink.js deleted file mode 100644 index c2c0b4c45..000000000 --- a/docfx/docfx_project/templates/singulinkfx/styles/singulink.js +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information. - -function toggleMenu() { - - var sidebar = document.getElementById("sidebar"); - var blackout = document.getElementById("blackout"); - - if (sidebar.style.left === "0px") - { - sidebar.style.left = "-" + sidebar.offsetWidth + "px"; - blackout.classList.remove("showThat"); - blackout.classList.add("hideThat"); - } - else - { - sidebar.style.left = "0px"; - blackout.classList.remove("hideThat"); - blackout.classList.add("showThat"); - } -} - -$(function() { - $('table').each(function(a, tbl) { - var currentTableRows = $(tbl).find('tbody tr').length; - $(tbl).find('th').each(function(i) { - var remove = 0; - var currentTable = $(this).parents('table'); - - var tds = currentTable.find('tr td:nth-child(' + (i + 1) + ')'); - tds.each(function(j) { if ($(this).text().trim() === '') remove++; }); - - if (remove == currentTableRows) { - $(this).hide(); - tds.hide(); - } - }); - }); -}); \ No newline at end of file diff --git a/docfx/docfx_project/templates/singulinkfx/styles/url.min.js b/docfx/docfx_project/templates/singulinkfx/styles/url.min.js deleted file mode 100644 index 8057e0aa0..000000000 --- a/docfx/docfx_project/templates/singulinkfx/styles/url.min.js +++ /dev/null @@ -1 +0,0 @@ -/*! url - v1.8.6 - 2013-11-22 */window.url=function(){function a(a){return!isNaN(parseFloat(a))&&isFinite(a)}return function(b,c){var d=c||window.location.toString();if(!b)return d;b=b.toString(),"//"===d.substring(0,2)?d="http:"+d:1===d.split("://").length&&(d="http://"+d),c=d.split("/");var e={auth:""},f=c[2].split("@");1===f.length?f=f[0].split(":"):(e.auth=f[0],f=f[1].split(":")),e.protocol=c[0],e.hostname=f[0],e.port=f[1]||("https"===e.protocol.split(":")[0].toLowerCase()?"443":"80"),e.pathname=(c.length>3?"/":"")+c.slice(3,c.length).join("/").split("?")[0].split("#")[0];var g=e.pathname;"/"===g.charAt(g.length-1)&&(g=g.substring(0,g.length-1));var h=e.hostname,i=h.split("."),j=g.split("/");if("hostname"===b)return h;if("domain"===b)return/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/.test(h)?h:i.slice(-2).join(".");if("sub"===b)return i.slice(0,i.length-2).join(".");if("port"===b)return e.port;if("protocol"===b)return e.protocol.split(":")[0];if("auth"===b)return e.auth;if("user"===b)return e.auth.split(":")[0];if("pass"===b)return e.auth.split(":")[1]||"";if("path"===b)return e.pathname;if("."===b.charAt(0)){if(b=b.substring(1),a(b))return b=parseInt(b,10),i[0>b?i.length+b:b-1]||""}else{if(a(b))return b=parseInt(b,10),j[0>b?j.length+b:b]||"";if("file"===b)return j.slice(-1)[0];if("filename"===b)return j.slice(-1)[0].split(".")[0];if("fileext"===b)return j.slice(-1)[0].split(".")[1]||"";if("?"===b.charAt(0)||"#"===b.charAt(0)){var k=d,l=null;if("?"===b.charAt(0)?k=(k.split("?")[1]||"").split("#")[0]:"#"===b.charAt(0)&&(k=k.split("#")[1]||""),!b.charAt(1))return k;b=b.substring(1),k=k.split("&");for(var m=0,n=k.length;n>m;m++)if(l=k[m].split("="),l[0]===b)return l[1]||"";return null}}return""}}(),"undefined"!=typeof jQuery&&jQuery.extend({url:function(a,b){return window.url(a,b)}}); \ No newline at end of file diff --git a/docfx/docfx_project/templates/singulinkfx/toc.html.tmpl b/docfx/docfx_project/templates/singulinkfx/toc.html.tmpl deleted file mode 100644 index 6549e62e7..000000000 --- a/docfx/docfx_project/templates/singulinkfx/toc.html.tmpl +++ /dev/null @@ -1,22 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - -
      -
      - {{^_disableSideFilter}} -
      -
      - - - -
      -
      - {{/_disableSideFilter}} -
      -
      - {{^leaf}} - {{>partials/li}} - {{/leaf}} -
      -
      -
      -
      \ No newline at end of file diff --git a/docfx/docfx_project/toc.yml b/docfx/docfx_project/toc.yml index 842c6b36f..061acc65f 100644 --- a/docfx/docfx_project/toc.yml +++ b/docfx/docfx_project/toc.yml @@ -1,2 +1,4 @@ -- name: API Documentation - href: api/ +- name: Docs + href: docs/ +- name: API + href: api/ \ No newline at end of file diff --git a/docfx/readme.md b/docfx/readme.md deleted file mode 100644 index 212a96e67..000000000 --- a/docfx/readme.md +++ /dev/null @@ -1,10 +0,0 @@ -To generate the [Artemis API docs](https://artemis-rgb.com/docs/) we use [DocFX](https://dotnet.github.io/docfx/). - -To build locally run the following commands from this folder. - -#### Want to build? Follow these instructions (Windows) -1. Ensure you can build the Artemis solution as per the [main build instructions](https://github.com/Artemis-RGB/Artemis#want-to-build-follow-these-instructions) -2. Install DocFX (with Chocolatey: `choco install docfx`) -3. Open PowerShell in `\docfx` (the same folder as this readme file) -4. Run `docfx .\docfx_project\docfx.json` to build static files - Run `docfx .\docfx_project\docfx.json --serve` to serve locally From 78d3b58f99f100be3a71a25cb753f8d3cb36b9f0 Mon Sep 17 00:00:00 2001 From: RobertBeekman Date: Tue, 20 Feb 2024 12:06:21 +0100 Subject: [PATCH 02/12] Upgrade .NET 8 and packages Include Qodana :D --- .github/workflows/qodana_code_quality.yml | 20 +++++++++++++ src/Artemis.Core/Artemis.Core.csproj | 2 +- src/Artemis.Storage/Artemis.Storage.csproj | 4 +-- src/Artemis.UI.Linux/Artemis.UI.Linux.csproj | 2 +- src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj | 2 +- .../Artemis.UI.Shared.csproj | 12 ++++---- .../Artemis.UI.Windows.csproj | 6 ++-- src/Artemis.UI/Artemis.UI.csproj | 6 ++-- .../Artemis.VisualScripting.csproj | 2 +- .../Artemis.WebClient.Updating.csproj | 6 ++-- .../Artemis.WebClient.Workshop.csproj | 6 ++-- src/qodana.yaml | 29 +++++++++++++++++++ 12 files changed, 73 insertions(+), 24 deletions(-) create mode 100644 .github/workflows/qodana_code_quality.yml create mode 100644 src/qodana.yaml diff --git a/.github/workflows/qodana_code_quality.yml b/.github/workflows/qodana_code_quality.yml new file mode 100644 index 000000000..482098d02 --- /dev/null +++ b/.github/workflows/qodana_code_quality.yml @@ -0,0 +1,20 @@ +name: Qodana +on: + workflow_dispatch: + pull_request: + push: + branches: + - master + - development + +jobs: + qodana: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: 'Qodana Scan' + uses: JetBrains/qodana-action@v2023.3 + env: + QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} \ No newline at end of file diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index 86d6f2a97..6a96956a5 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -1,6 +1,6 @@ - net7.0 + net8.0 false false Artemis.Core diff --git a/src/Artemis.Storage/Artemis.Storage.csproj b/src/Artemis.Storage/Artemis.Storage.csproj index 679f1c3c7..d682d5570 100644 --- a/src/Artemis.Storage/Artemis.Storage.csproj +++ b/src/Artemis.Storage/Artemis.Storage.csproj @@ -1,12 +1,12 @@  - net7.0 + net8.0 false x64 - + \ No newline at end of file diff --git a/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj b/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj index c346e5027..c41b62a40 100644 --- a/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj +++ b/src/Artemis.UI.Linux/Artemis.UI.Linux.csproj @@ -1,7 +1,7 @@ WinExe - net7.0 + net8.0 enable x64 x64 diff --git a/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj b/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj index b5cc49ac7..d762afde1 100644 --- a/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj +++ b/src/Artemis.UI.MacOS/Artemis.UI.MacOS.csproj @@ -1,7 +1,7 @@  WinExe - net7.0 + net8.0 enable x64 x64 diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index 1be9809f0..67242b85a 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -1,7 +1,7 @@  Library - net7.0 + net8.0 enable bin\ x64 @@ -10,16 +10,16 @@ - + - - - + + + - + diff --git a/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj b/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj index b0d0e9593..b9abf03e3 100644 --- a/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj +++ b/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj @@ -1,7 +1,7 @@ WinExe - net7.0-windows10.0.17763.0 + net8.0-windows10.0.17763.0 enable x64 bin @@ -21,11 +21,11 @@ - + - + diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index ec42bd185..88b39600b 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -1,7 +1,7 @@ Library - net7.0 + net8.0 enable bin/ x64 @@ -19,11 +19,11 @@ - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj index 1e5aea19c..90b14e4fa 100644 --- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj +++ b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj @@ -1,6 +1,6 @@  - net7.0 + net8.0 enable enable x64 diff --git a/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj b/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj index 732b2c721..23da69ca1 100644 --- a/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj +++ b/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj @@ -1,6 +1,6 @@ - net7.0 + net8.0 enable enable x64 @@ -9,8 +9,8 @@ - - + + diff --git a/src/Artemis.WebClient.Workshop/Artemis.WebClient.Workshop.csproj b/src/Artemis.WebClient.Workshop/Artemis.WebClient.Workshop.csproj index b9931c626..840e6d736 100644 --- a/src/Artemis.WebClient.Workshop/Artemis.WebClient.Workshop.csproj +++ b/src/Artemis.WebClient.Workshop/Artemis.WebClient.Workshop.csproj @@ -1,6 +1,6 @@ - net7.0 + net8.0 enable enable x64 @@ -10,8 +10,8 @@ - - + + diff --git a/src/qodana.yaml b/src/qodana.yaml new file mode 100644 index 000000000..f2bd5156e --- /dev/null +++ b/src/qodana.yaml @@ -0,0 +1,29 @@ +#-------------------------------------------------------------------------------# +# Qodana analysis is configured by qodana.yaml file # +# https://www.jetbrains.com/help/qodana/qodana-yaml.html # +#-------------------------------------------------------------------------------# +version: "1.0" + +#Specify IDE code to run analysis without container (Applied in CI/CD pipeline) +ide: QDNET + +#Specify inspection profile for code analysis +profile: + name: qodana.starter + +#Enable inspections +#include: +# - name: + +#Disable inspections +#exclude: +# - name: +# paths: +# - + +#Execute shell command before Qodana execution (Applied in CI/CD pipeline) +#bootstrap: sh ./prepare-qodana.sh + +#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline) +#plugins: +# - id: #(plugin id can be found at https://plugins.jetbrains.com) From 1ed13d8b68b9d573dea0f2b5e3d700363a18ed0a Mon Sep 17 00:00:00 2001 From: RobertBeekman Date: Tue, 20 Feb 2024 12:19:29 +0100 Subject: [PATCH 03/12] Remove Qodana for now --- .github/workflows/qodana_code_quality.yml | 20 ---------------- src/qodana.yaml | 29 ----------------------- 2 files changed, 49 deletions(-) delete mode 100644 .github/workflows/qodana_code_quality.yml delete mode 100644 src/qodana.yaml diff --git a/.github/workflows/qodana_code_quality.yml b/.github/workflows/qodana_code_quality.yml deleted file mode 100644 index 482098d02..000000000 --- a/.github/workflows/qodana_code_quality.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Qodana -on: - workflow_dispatch: - pull_request: - push: - branches: - - master - - development - -jobs: - qodana: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: 'Qodana Scan' - uses: JetBrains/qodana-action@v2023.3 - env: - QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} \ No newline at end of file diff --git a/src/qodana.yaml b/src/qodana.yaml deleted file mode 100644 index f2bd5156e..000000000 --- a/src/qodana.yaml +++ /dev/null @@ -1,29 +0,0 @@ -#-------------------------------------------------------------------------------# -# Qodana analysis is configured by qodana.yaml file # -# https://www.jetbrains.com/help/qodana/qodana-yaml.html # -#-------------------------------------------------------------------------------# -version: "1.0" - -#Specify IDE code to run analysis without container (Applied in CI/CD pipeline) -ide: QDNET - -#Specify inspection profile for code analysis -profile: - name: qodana.starter - -#Enable inspections -#include: -# - name: - -#Disable inspections -#exclude: -# - name: -# paths: -# - - -#Execute shell command before Qodana execution (Applied in CI/CD pipeline) -#bootstrap: sh ./prepare-qodana.sh - -#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline) -#plugins: -# - id: #(plugin id can be found at https://plugins.jetbrains.com) From f51aa3ca06bfb248ca8f410e8e102b3f12739688 Mon Sep 17 00:00:00 2001 From: RobertBeekman Date: Tue, 20 Feb 2024 12:58:24 +0100 Subject: [PATCH 04/12] Bump RGB.NET --- src/Artemis.Core/Artemis.Core.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index 6a96956a5..8581e4835 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -43,9 +43,9 @@ - - - + + + From 2d00a64a7d151d04379dda694cafc28e6954fefb Mon Sep 17 00:00:00 2001 From: RobertBeekman Date: Tue, 20 Feb 2024 17:08:25 +0100 Subject: [PATCH 05/12] Finish config --- docfx/docfx_project/artemis-template/public/main.css | 4 ++++ docfx/docfx_project/docfx.json | 8 ++++++-- docfx/docfx_project/filterConfig.yml | 4 ++-- docfx/docfx_project/index.md | 10 +++------- docfx/docfx_project/toc.yml | 4 +--- docfx/{docfx_project => }/docs/getting-started.md | 0 docfx/{docfx_project => }/docs/introduction.md | 0 docfx/{docfx_project => }/docs/toc.yml | 0 8 files changed, 16 insertions(+), 14 deletions(-) create mode 100644 docfx/docfx_project/artemis-template/public/main.css rename docfx/{docfx_project => }/docs/getting-started.md (100%) rename docfx/{docfx_project => }/docs/introduction.md (100%) rename docfx/{docfx_project => }/docs/toc.yml (100%) diff --git a/docfx/docfx_project/artemis-template/public/main.css b/docfx/docfx_project/artemis-template/public/main.css new file mode 100644 index 000000000..625bcc189 --- /dev/null +++ b/docfx/docfx_project/artemis-template/public/main.css @@ -0,0 +1,4 @@ +#logo { + height: 40px; + margin-right: 10px; +} \ No newline at end of file diff --git a/docfx/docfx_project/docfx.json b/docfx/docfx_project/docfx.json index 7b5a81816..e1d18f44b 100644 --- a/docfx/docfx_project/docfx.json +++ b/docfx/docfx_project/docfx.json @@ -11,7 +11,8 @@ } ], "dest": "api", - "filter": "filterConfig.yml" + "filter": "filterConfig.yml", + "namespaceLayout": "nested" } ], "build": { @@ -35,11 +36,14 @@ "output": "_site", "template": [ "default", - "modern" + "modern", + "artemis-template" ], "globalMetadata": { "_appTitle": "Artemis API Documentation", "_appName": "Artemis", + "_appLogoPath": "images/application.ico", + "_appFaviconPath": "images/application.ico", "_copyrightFooter": "Content is available under the PolyForm Noncommercial License, by Artemis RGB.", "_enableSearch": true, "_disableSideFilter": false, diff --git a/docfx/docfx_project/filterConfig.yml b/docfx/docfx_project/filterConfig.yml index d56cc1bd4..a8c6eb018 100644 --- a/docfx/docfx_project/filterConfig.yml +++ b/docfx/docfx_project/filterConfig.yml @@ -24,5 +24,5 @@ apiRules: uidRegex: ^Artemis\.UI\.Shared\.Properties type: Type - exclude: - uidRegex: ^Artemis\.Core\.TypeExtensions\.IsNumber - type: Method \ No newline at end of file + uidRegex: ^Artemis\.Core\.TypeExtensions + type: Type \ No newline at end of file diff --git a/docfx/docfx_project/index.md b/docfx/docfx_project/index.md index f9859f840..641c4d1a6 100644 --- a/docfx/docfx_project/index.md +++ b/docfx/docfx_project/index.md @@ -2,10 +2,6 @@ _layout: landing --- -# This is the **HOMEPAGE**. - -Refer to [Markdown](http://daringfireball.net/projects/markdown/) for how to write markdown files. - -## Quick Start Notes: - -1. Add images to the *images* folder if the file is referencing an image. \ No newline at end of file +# Artemis Technical Documentation +Welcome to the technical docs of Artemis. This page contains all the public types available when writing Artemis plugins. +For more details, please refer to the [Artemis wiki](https://wiki.artemis-rgb.com/en/guides/developer). \ No newline at end of file diff --git a/docfx/docfx_project/toc.yml b/docfx/docfx_project/toc.yml index 061acc65f..aba634266 100644 --- a/docfx/docfx_project/toc.yml +++ b/docfx/docfx_project/toc.yml @@ -1,4 +1,2 @@ -- name: Docs - href: docs/ -- name: API +- name: Plugin API href: api/ \ No newline at end of file diff --git a/docfx/docfx_project/docs/getting-started.md b/docfx/docs/getting-started.md similarity index 100% rename from docfx/docfx_project/docs/getting-started.md rename to docfx/docs/getting-started.md diff --git a/docfx/docfx_project/docs/introduction.md b/docfx/docs/introduction.md similarity index 100% rename from docfx/docfx_project/docs/introduction.md rename to docfx/docs/introduction.md diff --git a/docfx/docfx_project/docs/toc.yml b/docfx/docs/toc.yml similarity index 100% rename from docfx/docfx_project/docs/toc.yml rename to docfx/docs/toc.yml From f88459fddd829de6731949b5c0c5769f8f7dad18 Mon Sep 17 00:00:00 2001 From: Diogo Trindade Date: Mon, 15 Jan 2024 19:13:36 +0000 Subject: [PATCH 06/12] Centralized package management --- src/Artemis.Core/Artemis.Core.csproj | 28 ++++----- src/Artemis.Storage/Artemis.Storage.csproj | 6 +- .../Artemis.UI.Shared.csproj | 22 +++---- .../Artemis.UI.Windows.csproj | 13 ++--- src/Artemis.UI/Artemis.UI.csproj | 22 +++---- .../Artemis.VisualScripting.csproj | 4 +- .../Artemis.WebClient.Updating.csproj | 8 +-- .../Artemis.WebClient.Workshop.csproj | 10 ++-- src/Artemis.sln | 1 + src/Directory.Packages.props | 57 +++++++++++++++++++ 10 files changed, 114 insertions(+), 57 deletions(-) create mode 100644 src/Directory.Packages.props diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj index 8581e4835..e81dc0d64 100644 --- a/src/Artemis.Core/Artemis.Core.csproj +++ b/src/Artemis.Core/Artemis.Core.csproj @@ -36,20 +36,20 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/src/Artemis.Storage/Artemis.Storage.csproj b/src/Artemis.Storage/Artemis.Storage.csproj index d682d5570..db87925b6 100644 --- a/src/Artemis.Storage/Artemis.Storage.csproj +++ b/src/Artemis.Storage/Artemis.Storage.csproj @@ -1,4 +1,4 @@ - + net8.0 false @@ -6,7 +6,7 @@ - - + + \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj index 67242b85a..bf6734a2a 100644 --- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj +++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj @@ -1,4 +1,4 @@ - + Library net8.0 @@ -10,17 +10,17 @@ - + - - - - - - - - - + + + + + + + + + diff --git a/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj b/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj index b9abf03e3..52a121156 100644 --- a/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj +++ b/src/Artemis.UI.Windows/Artemis.UI.Windows.csproj @@ -21,13 +21,12 @@ - - - - - - - + + + + + + diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 88b39600b..5c38ecfe1 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -16,20 +16,20 @@ - - - - - - - - - + + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj index 90b14e4fa..91a940ad9 100644 --- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj +++ b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj @@ -1,4 +1,4 @@ - + net8.0 enable @@ -7,7 +7,7 @@ - + diff --git a/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj b/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj index 23da69ca1..f5d00c0f4 100644 --- a/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj +++ b/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj @@ -7,10 +7,10 @@ - - - - + + + + diff --git a/src/Artemis.WebClient.Workshop/Artemis.WebClient.Workshop.csproj b/src/Artemis.WebClient.Workshop/Artemis.WebClient.Workshop.csproj index 840e6d736..3e348ce4e 100644 --- a/src/Artemis.WebClient.Workshop/Artemis.WebClient.Workshop.csproj +++ b/src/Artemis.WebClient.Workshop/Artemis.WebClient.Workshop.csproj @@ -7,11 +7,11 @@ - - - - - + + + + + diff --git a/src/Artemis.sln b/src/Artemis.sln index cd0039bd1..8c9de95cc 100644 --- a/src/Artemis.sln +++ b/src/Artemis.sln @@ -27,6 +27,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject Artemis.sln.DotSettings = Artemis.sln.DotSettings Artemis.sln.DotSettings.user = Artemis.sln.DotSettings.user + Directory.Packages.props = Directory.Packages.props EndProjectSection EndProject Global diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props new file mode 100644 index 000000000..6345a6c15 --- /dev/null +++ b/src/Directory.Packages.props @@ -0,0 +1,57 @@ + + + true + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 39d7d8132f93e81d580c4fba99666bce3efd9788 Mon Sep 17 00:00:00 2001 From: RobertBeekman Date: Thu, 22 Feb 2024 19:42:09 +0100 Subject: [PATCH 07/12] Core - Added node provider plugin feature type Visual Scripting - Removed all nodes --- .../Plugins/Nodes/NodeProvider.cs | 76 ++++++++ src/Artemis.Core/Services/NodeService.cs | 96 +--------- src/Artemis.Core/Stores/NodeTypeStore.cs | 21 +-- .../Registrations/NodeTypeRegistration.cs | 26 +-- .../VisualScripting/Interfaces/INode.cs | 5 + src/Artemis.Core/VisualScripting/NodeData.cs | 31 +++- .../VisualScripting/NodeScript.cs | 4 +- .../VisualScripting/Nodes/Node.cs | 5 +- .../Nodes/NodeTStorageTViewModel.cs | 2 +- .../Entities/Profile/Nodes/NodeEntity.cs | 4 +- .../Migrations/M0021GradientNodes.cs | 2 +- .../Repositories/PluginRepository.cs | 1 - .../Services/DataModelUIService.cs | 12 +- .../Interfaces/IDataModelUIService.cs | 10 + .../Services/NodeEditor/Commands/AddNode.cs | 1 + .../NodeEditor/Commands/DeleteNode.cs | 1 + .../NodeEditor/Commands/DuplicateNode.cs | 1 + src/Artemis.UI/Artemis.UI.csproj | 1 - src/Artemis.UI/ArtemisBootstrapper.cs | 3 - .../Screens/VisualScripting/NodeViewModel.cs | 57 ++++-- .../Interfaces/IRegistrationService.cs | 1 - .../Services/RegistrationService.cs | 29 +-- .../Artemis.VisualScripting.csproj | 17 -- .../Converters/JsonConverter.cs | 25 --- .../Converters/NumericConverter.cs | 27 --- .../DryIoc/ContainerExtensions.cs | 41 ----- .../Nodes/Branching/BooleanBranchNode.cs | 59 ------ .../Nodes/Branching/EnumSwitchNode.cs | 100 ---------- .../Nodes/Color/BrightenSKColorNode.cs | 26 --- .../Nodes/Color/ColorGradientFromPinsNode.cs | 102 ----------- .../Nodes/Color/ColorGradientNode.cs | 108 ----------- .../Nodes/Color/DarkenSKColorNode.cs | 26 --- .../Nodes/Color/DesaturateSKColorNode.cs | 26 --- .../Nodes/Color/GradientBuilderNode.cs | 50 ----- .../Nodes/Color/HslSKColorNode.cs | 31 ---- .../Nodes/Color/HsvSKColorNode.cs | 31 ---- .../Nodes/Color/InvertSKColorNode.cs | 27 --- .../Nodes/Color/LerpSKColorNode.cs | 57 ------ .../Nodes/Color/RampSKColorNode.cs | 42 ----- .../Nodes/Color/RgbSKColorNode.cs | 37 ---- .../Nodes/Color/RotateHueSkColorNode.cs | 26 --- .../Nodes/Color/SaturateSkColorNode.cs | 26 --- .../Screens/ColorGradientNodeCustomView.axaml | 15 -- .../ColorGradientNodeCustomView.axaml.cs | 23 --- .../ColorGradientNodeCustomViewModel.cs | 28 --- .../Screens/RampSKColorNodeCustomView.axaml | 16 -- .../RampSKColorNodeCustomView.axaml.cs | 23 --- .../Screens/RampSKColorNodeCustomViewModel.cs | 28 --- .../Nodes/Color/SkColorHsl.cs | 36 ---- .../Nodes/Color/SkColorHsv.cs | 36 ---- .../Nodes/Color/SortedGradient.cs | 57 ------ .../Nodes/Color/SumSKColorsNode.cs | 45 ----- .../Nodes/Conversion/ConvertToNumericNode.cs | 48 ----- .../Nodes/Conversion/ConvertToStringNode.cs | 34 ---- .../DataModel/DataModelEventCycleNode.cs | 171 ------------------ .../Nodes/DataModel/DataModelEventNode.cs | 164 ----------------- .../Nodes/DataModel/DataModelNode.cs | 88 --------- .../DataModelEventCycleNodeCustomView.axaml | 18 -- ...DataModelEventCycleNodeCustomView.axaml.cs | 13 -- .../DataModelEventCycleNodeCustomViewModel.cs | 104 ----------- .../DataModelEventNodeCustomView.axaml | 19 -- .../DataModelEventNodeCustomView.axaml.cs | 13 -- .../DataModelEventNodeCustomViewModel.cs | 111 ------------ .../Screens/DataModelNodeCustomView.axaml | 17 -- .../Screens/DataModelNodeCustomView.axaml.cs | 13 -- .../Screens/DataModelNodeCustomViewModel.cs | 108 ----------- ...eLayerPropertyNodeSelectedLayerProperty.cs | 45 ----- ...LayerPropertyNodeSelectedProfileElement.cs | 54 ------ .../Nodes/External/LayerPropertyNode.cs | 154 ---------------- .../Screens/LayerPropertyNodeCustomView.axaml | 24 --- .../LayerPropertyNodeCustomView.axaml.cs | 13 -- .../LayerPropertyNodeCustomViewModel.cs | 93 ---------- .../Nodes/Input/HotkeyEnableDisableNode.cs | 74 -------- .../Input/HotkeyEnableDisableNodeEntity.cs | 18 -- .../Nodes/Input/HotkeyPressNode.cs | 69 ------- .../Nodes/Input/HotkeyToggleNode.cs | 69 ------- .../Nodes/Input/PressedKeyPositionNode.cs | 73 -------- .../Input/PressedKeyPositionNodeEntity.cs | 29 --- .../HotkeyEnableDisableNodeCustomView.axaml | 16 -- ...HotkeyEnableDisableNodeCustomView.axaml.cs | 19 -- .../HotkeyEnableDisableNodeCustomViewModel.cs | 65 ------- .../Screens/HotkeyPressNodeCustomView.axaml | 11 -- .../HotkeyPressNodeCustomView.axaml.cs | 19 -- .../Screens/HotkeyPressNodeCustomViewModel.cs | 55 ------ .../Screens/HotkeyToggleNodeCustomView.axaml | 11 -- .../HotkeyToggleNodeCustomView.axaml.cs | 19 -- .../HotkeyToggleNodeCustomViewModel.cs | 55 ------ .../PressedKeyPositionNodeCustomView.axaml | 29 --- .../PressedKeyPositionNodeCustomView.axaml.cs | 13 -- .../PressedKeyPositionNodeCustomViewModel.cs | 94 ---------- .../Nodes/List/ListOperatorEntity.cs | 9 - .../Nodes/List/ListOperatorNode.cs | 46 ----- .../Nodes/List/ListOperatorPredicateNode.cs | 106 ----------- .../List/ListOperatorPredicateStartNode.cs | 27 --- .../Screens/ListOperatorNodeCustomView.axaml | 11 -- .../ListOperatorNodeCustomView.axaml.cs | 13 -- .../ListOperatorNodeCustomViewModel.cs | 27 --- .../ListOperatorPredicateNodeCustomView.axaml | 14 -- ...stOperatorPredicateNodeCustomView.axaml.cs | 13 -- ...istOperatorPredicateNodeCustomViewModel.cs | 75 -------- .../Nodes/Mathematics/Clamp.cs | 38 ---- .../Nodes/Mathematics/CounterNode.cs | 31 ---- .../Nodes/Mathematics/LerpNode.cs | 44 ----- .../Nodes/Mathematics/MathExpressionNode.cs | 119 ------------ .../Nodes/Mathematics/MaxNode.cs | 34 ---- .../Nodes/Mathematics/MinNode.cs | 34 ---- .../Nodes/Mathematics/NormalizeNode.cs | 30 --- .../Nodes/Mathematics/NumericEasingNode.cs | 29 --- .../Mathematics/PinsVariablesContainer.cs | 48 ----- .../Nodes/Mathematics/RangeNode.cs | 47 ----- .../Nodes/Mathematics/RoundNode.cs | 26 --- .../Nodes/Mathematics/Saturate.cs | 34 ---- .../MathExpressionNodeCustomView.axaml | 14 -- .../MathExpressionNodeCustomView.axaml.cs | 19 -- .../MathExpressionNodeCustomViewModel.cs | 62 ------- .../Nodes/Mathematics/SubtractNode.cs | 34 ---- .../Nodes/Mathematics/SumNode.cs | 34 ---- .../Nodes/Operators/AndNode.cs | 33 ---- .../Nodes/Operators/EnumEqualsNode.cs | 26 --- .../Nodes/Operators/EqualsNode.cs | 43 ----- .../Nodes/Operators/GreaterThanNode.cs | 56 ------ .../Nodes/Operators/LessThanNode.cs | 56 ------ .../Nodes/Operators/NegateNode.cs | 33 ---- .../Nodes/Operators/OrNode.cs | 33 ---- .../Screens/EnumEqualsNodeCustomView.axaml | 26 --- .../Screens/EnumEqualsNodeCustomView.axaml.cs | 13 -- .../Screens/EnumEqualsNodeCustomViewModel.cs | 95 ---------- .../Nodes/Operators/XorNode.cs | 33 ---- .../Nodes/Static/DisplayValueNode.cs | 19 -- .../Nodes/Static/RandomNumericValueNode.cs | 31 ---- .../Screens/DisplayValueNodeCustomView.axaml | 54 ------ .../DisplayValueNodeCustomView.axaml.cs | 13 -- .../DisplayValueNodeCustomViewModel.cs | 45 ----- .../StaticBooleanValueNodeCustomView.axaml | 13 -- .../StaticBooleanValueNodeCustomView.axaml.cs | 13 -- .../StaticBooleanValueNodeCustomViewModel.cs | 27 --- .../StaticNumericValueNodeCustomView.axaml | 22 --- .../StaticNumericValueNodeCustomView.axaml.cs | 13 -- .../StaticNumericValueNodeCustomViewModel.cs | 27 --- .../StaticSKColorValueNodeCustomView.axaml | 30 --- .../StaticSKColorValueNodeCustomView.axaml.cs | 24 --- .../StaticSKColorValueNodeCustomViewModel.cs | 51 ------ .../StaticStringValueNodeCustomView.axaml | 15 -- .../StaticStringValueNodeCustomView.axaml.cs | 13 -- .../Screens/StaticValueNodeViewModels.cs | 27 --- .../Nodes/Static/StaticBooleanValueNode.cs | 33 ---- .../Nodes/Static/StaticNumericValueNode.cs | 33 ---- .../Nodes/Static/StaticSKColorValueNode.cs | 35 ---- .../Nodes/Static/StaticStringValueNode.cs | 33 ---- .../Nodes/Text/StringContainsNode.cs | 31 ---- .../Nodes/Text/StringFormatNode.cs | 38 ---- .../Nodes/Text/StringLengthNode.cs | 23 --- .../Nodes/Text/StringNullOrEmptyNode.cs | 24 --- .../Nodes/Text/StringRegexMatchNode.cs | 58 ------ .../Nodes/Timing/DelayNode.cs | 116 ------------ .../Nodes/Timing/EdgeNode.cs | 40 ---- .../Nodes/Timing/FlipFlopNode.cs | 44 ----- .../Nodes/Timing/LatchNode.cs | 112 ------------ .../Nodes/Timing/SequencerNode.cs | 135 -------------- .../Transition/ColorGradientTransitionNode.cs | 71 -------- .../Nodes/Transition/EasingFunctionNode.cs | 20 -- .../Nodes/Transition/NumericTransitionNode.cs | 68 ------- .../Nodes/Transition/SKColorTransitionNode.cs | 66 ------- .../EasingFunctionNodeCustomView.axaml | 10 - .../EasingFunctionNodeCustomView.axaml.cs | 13 -- .../EasingFunctionNodeCustomViewModel.cs | 36 ---- .../Screens/EasingFunctionView.axaml | 19 -- .../Screens/EasingFunctionView.axaml.cs | 13 -- .../Screens/EasingFunctionViewModel.cs | 26 --- src/Artemis.sln | 6 - 170 files changed, 193 insertions(+), 6434 deletions(-) create mode 100644 src/Artemis.Core/Plugins/Nodes/NodeProvider.cs delete mode 100644 src/Artemis.VisualScripting/Artemis.VisualScripting.csproj delete mode 100644 src/Artemis.VisualScripting/Converters/JsonConverter.cs delete mode 100644 src/Artemis.VisualScripting/Converters/NumericConverter.cs delete mode 100644 src/Artemis.VisualScripting/DryIoc/ContainerExtensions.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Branching/BooleanBranchNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Branching/EnumSwitchNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/BrightenSKColorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/ColorGradientFromPinsNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/ColorGradientNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/DarkenSKColorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/DesaturateSKColorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/GradientBuilderNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/HslSKColorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/HsvSKColorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/InvertSKColorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/LerpSKColorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/RampSKColorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/RgbSKColorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/RotateHueSkColorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/SaturateSkColorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/SkColorHsl.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/SkColorHsv.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/SortedGradient.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Color/SumSKColorsNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Conversion/ConvertToNumericNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Conversion/ConvertToStringNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/DataModel/DataModelEventCycleNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/DataModel/DataModelEventNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/DataModel/DataModelNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/External/Commands/UpdateLayerPropertyNodeSelectedLayerProperty.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/External/Commands/UpdateLayerPropertyNodeSelectedProfileElement.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/External/LayerPropertyNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/HotkeyEnableDisableNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/HotkeyEnableDisableNodeEntity.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/HotkeyPressNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/HotkeyToggleNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/PressedKeyPositionNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/PressedKeyPositionNodeEntity.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyToggleNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyToggleNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyToggleNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/List/ListOperatorEntity.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/List/ListOperatorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/List/ListOperatorPredicateNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/List/ListOperatorPredicateStartNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorPredicateNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorPredicateNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorPredicateNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/Clamp.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/CounterNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/LerpNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/MathExpressionNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/MaxNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/MinNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/NormalizeNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/NumericEasingNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/PinsVariablesContainer.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/RangeNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/RoundNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/Saturate.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/SubtractNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Mathematics/SumNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Operators/AndNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Operators/EnumEqualsNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Operators/EqualsNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Operators/GreaterThanNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Operators/LessThanNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Operators/NegateNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Operators/OrNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Operators/XorNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/DisplayValueNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/RandomNumericValueNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/StaticNumericValueNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/StaticNumericValueNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/StaticNumericValueNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/StaticStringValueNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/StaticStringValueNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/Screens/StaticValueNodeViewModels.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/StaticBooleanValueNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/StaticNumericValueNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/StaticSKColorValueNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Static/StaticStringValueNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Text/StringContainsNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Text/StringFormatNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Text/StringLengthNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Text/StringNullOrEmptyNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Text/StringRegexMatchNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Timing/DelayNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Timing/EdgeNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Timing/FlipFlopNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Timing/LatchNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Timing/SequencerNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Transition/ColorGradientTransitionNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Transition/EasingFunctionNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Transition/NumericTransitionNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Transition/SKColorTransitionNode.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomViewModel.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionView.axaml delete mode 100644 src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionView.axaml.cs delete mode 100644 src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionViewModel.cs diff --git a/src/Artemis.Core/Plugins/Nodes/NodeProvider.cs b/src/Artemis.Core/Plugins/Nodes/NodeProvider.cs new file mode 100644 index 000000000..64acd5612 --- /dev/null +++ b/src/Artemis.Core/Plugins/Nodes/NodeProvider.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Reflection; +using SkiaSharp; + +namespace Artemis.Core.Nodes; + +/// +/// Allows you to register one or more s usable by node scripts. +/// +public abstract class NodeProvider : PluginFeature +{ + private readonly List _nodeDescriptors; + + /// + /// Creates a new instance of the class. + /// + public NodeProvider() + { + _nodeDescriptors = new List(); + NodeDescriptors = new ReadOnlyCollection(_nodeDescriptors); + Disabled += OnDisabled; + } + + /// + /// A read-only collection of all nodes added with + /// + public ReadOnlyCollection NodeDescriptors { get; set; } + + /// + /// Adds a node descriptor for a given node, so that it appears in the UI. + /// Note: You do not need to manually remove these on disable + /// + /// The type of the node you wish to register + protected void RegisterNodeType() where T : INode + { + RegisterNodeType(typeof(T)); + } + + /// + /// Adds a node descriptor for a given node, so that it appears in the UI. + /// Note: You do not need to manually remove these on disable + /// + /// The type of the node you wish to register + protected void RegisterNodeType(Type nodeType) + { + if (!IsEnabled) + throw new ArtemisPluginFeatureException(this, "Can only add a node descriptor when the plugin is enabled"); + if (nodeType == null) + throw new ArgumentNullException(nameof(nodeType)); + if (!nodeType.IsAssignableTo(typeof(INode))) + throw new ArgumentException("Node has to be a base type of the Node-Type.", nameof(nodeType)); + + NodeAttribute? nodeAttribute = nodeType.GetCustomAttribute(); + string name = nodeAttribute?.Name ?? nodeType.Name; + string description = nodeAttribute?.Description ?? string.Empty; + string category = nodeAttribute?.Category ?? string.Empty; + string helpUrl = nodeAttribute?.HelpUrl ?? string.Empty; + + NodeData nodeData = new(this, nodeType, name, description, category, helpUrl, nodeAttribute?.InputType, nodeAttribute?.OutputType); + _nodeDescriptors.Add(nodeData); + NodeTypeStore.Add(nodeData); + } + + protected TypeColorRegistration RegisterTypeColor(SKColor color) + { + return NodeTypeStore.AddColor(typeof(T), color, this); + } + + private void OnDisabled(object? sender, EventArgs e) + { + // The store will clean up the registrations by itself, the plugin feature just needs to clear its own list + _nodeDescriptors.Clear(); + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Services/NodeService.cs b/src/Artemis.Core/Services/NodeService.cs index 7cae6709b..96a0b617b 100644 --- a/src/Artemis.Core/Services/NodeService.cs +++ b/src/Artemis.Core/Services/NodeService.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Security.Cryptography; using System.Text; using Artemis.Storage.Entities.Profile.Nodes; -using DryIoc; using Newtonsoft.Json; using SkiaSharp; @@ -13,31 +11,8 @@ namespace Artemis.Core.Services; internal class NodeService : INodeService { - #region Constants - - private static readonly Type TypeNode = typeof(INode); - - #endregion - - private readonly IContainer _container; - - #region Constructors - - public NodeService(IContainer container) - { - _container = container; - } - - #endregion - - #region Properties & Fields - public IEnumerable AvailableNodes => NodeTypeStore.GetAll(); - #endregion - - #region Methods - /// public List GetRegisteredTypes() { @@ -53,7 +28,7 @@ internal class NodeService : INodeService // Objects represent an input that can take any type, these are hardcoded white if (type == typeof(object)) - return new TypeColorRegistration(type, new SKColor(255, 255, 255, 255), Constants.CorePlugin); + return new TypeColorRegistration(type, new SKColor(255, 255, 255, 255), Constants.CorePluginFeature); // Come up with a random color based on the type name that should be the same each time MD5 md5Hasher = MD5.Create(); @@ -61,32 +36,7 @@ internal class NodeService : INodeService int hash = BitConverter.ToInt32(hashed, 0); SKColor baseColor = SKColor.FromHsl(hash % 255, 50 + hash % 50, 50); - return new TypeColorRegistration(type, baseColor, Constants.CorePlugin); - } - - public NodeTypeRegistration RegisterNodeType(Plugin plugin, Type nodeType) - { - if (plugin == null) throw new ArgumentNullException(nameof(plugin)); - if (nodeType == null) throw new ArgumentNullException(nameof(nodeType)); - - if (!TypeNode.IsAssignableFrom(nodeType)) throw new ArgumentException("Node has to be a base type of the Node-Type.", nameof(nodeType)); - - NodeAttribute? nodeAttribute = nodeType.GetCustomAttribute(); - string name = nodeAttribute?.Name ?? nodeType.Name; - string description = nodeAttribute?.Description ?? string.Empty; - string category = nodeAttribute?.Category ?? string.Empty; - string helpUrl = nodeAttribute?.HelpUrl ?? string.Empty; - - NodeData nodeData = new(plugin, nodeType, name, description, category, helpUrl, nodeAttribute?.InputType, nodeAttribute?.OutputType, (s, e) => CreateNode(s, e, nodeType)); - return NodeTypeStore.Add(nodeData); - } - - public TypeColorRegistration RegisterTypeColor(Plugin plugin, Type type, SKColor color) - { - if (plugin == null) throw new ArgumentNullException(nameof(plugin)); - if (type == null) throw new ArgumentNullException(nameof(type)); - - return NodeTypeStore.AddColor(type, color, plugin); + return new TypeColorRegistration(type, baseColor, Constants.CorePluginFeature); } public string ExportScript(NodeScript nodeScript) @@ -103,33 +53,6 @@ internal class NodeService : INodeService target.LoadFromEntity(entity); } - - private INode CreateNode(INodeScript script, NodeEntity? entity, Type nodeType) - { - INode node = _container.Resolve(nodeType) as INode ?? throw new InvalidOperationException($"Node {nodeType} is not an INode"); - if (node is Node concreteNode) - concreteNode.Container = _container; - - if (entity != null) - { - node.X = entity.X; - node.Y = entity.Y; - try - { - if (node is Node nodeImplementation) - nodeImplementation.DeserializeStorage(entity.Storage); - } - catch - { - // ignored - } - } - - node.TryInitialize(script); - return node; - } - - #endregion } /// @@ -153,21 +76,6 @@ public interface INodeService : IArtemisService /// TypeColorRegistration GetTypeColorRegistration(Type type); - /// - /// Registers a node of the provided - /// - /// The plugin the node belongs to - /// The type of node to initialize - NodeTypeRegistration RegisterNodeType(Plugin plugin, Type nodeType); - - /// - /// Registers a type with a provided color for use in the node editor - /// - /// The plugin making the registration - /// The type to associate the color with - /// The color to display - TypeColorRegistration RegisterTypeColor(Plugin plugin, Type type, SKColor color); - /// /// Exports the provided node script to JSON. /// diff --git a/src/Artemis.Core/Stores/NodeTypeStore.cs b/src/Artemis.Core/Stores/NodeTypeStore.cs index 052cac84c..05c31519b 100644 --- a/src/Artemis.Core/Stores/NodeTypeStore.cs +++ b/src/Artemis.Core/Stores/NodeTypeStore.cs @@ -13,16 +13,13 @@ internal class NodeTypeStore public static NodeTypeRegistration Add(NodeData nodeData) { - if (nodeData.Plugin == null) - throw new ArtemisCoreException("Cannot add a data binding modifier type that is not associated with a plugin"); - NodeTypeRegistration typeRegistration; lock (Registrations) { if (Registrations.Any(r => r.NodeData == nodeData)) throw new ArtemisCoreException($"Data binding modifier type store already contains modifier '{nodeData.Name}'"); - typeRegistration = new NodeTypeRegistration(nodeData, nodeData.Plugin) {IsInStore = true}; + typeRegistration = new NodeTypeRegistration(nodeData, nodeData.Provider) {IsInStore = true}; Registrations.Add(typeRegistration); } @@ -60,24 +57,12 @@ internal class NodeTypeStore } } - public static Plugin? GetPlugin(INode node) - { - Type nodeType = node.GetType(); - lock (Registrations) - { - return Registrations.FirstOrDefault(r => r.NodeData.Type == nodeType)?.Plugin; - } - } - - public static TypeColorRegistration AddColor(Type type, SKColor color, Plugin plugin) + public static TypeColorRegistration AddColor(Type type, SKColor color, PluginFeature pluginFeature) { TypeColorRegistration typeColorRegistration; lock (ColorRegistrations) { - if (ColorRegistrations.Any(r => r.Type == type)) - throw new ArtemisCoreException($"Node color store already contains a color for '{type.Name}'"); - - typeColorRegistration = new TypeColorRegistration(type, color, plugin) {IsInStore = true}; + typeColorRegistration = new TypeColorRegistration(type, color, pluginFeature) {IsInStore = true}; ColorRegistrations.Add(typeColorRegistration); } diff --git a/src/Artemis.Core/Stores/Registrations/NodeTypeRegistration.cs b/src/Artemis.Core/Stores/Registrations/NodeTypeRegistration.cs index 659eb3503..bc5064c63 100644 --- a/src/Artemis.Core/Stores/Registrations/NodeTypeRegistration.cs +++ b/src/Artemis.Core/Stores/Registrations/NodeTypeRegistration.cs @@ -9,12 +9,12 @@ namespace Artemis.Core; /// public class NodeTypeRegistration { - internal NodeTypeRegistration(NodeData nodeData, Plugin plugin) + internal NodeTypeRegistration(NodeData nodeData, PluginFeature pluginFeature) { NodeData = nodeData; - Plugin = plugin; + PluginFeature = pluginFeature; - Plugin.Disabled += OnDisabled; + PluginFeature.Disabled += OnDisabled; } /// @@ -23,9 +23,9 @@ public class NodeTypeRegistration public NodeData NodeData { get; } /// - /// Gets the plugin the node is associated with + /// Gets the plugin feature the node is associated with /// - public Plugin Plugin { get; } + public PluginFeature PluginFeature { get; } /// /// Gets a boolean indicating whether the registration is in the internal Core store @@ -39,12 +39,12 @@ public class NodeTypeRegistration /// if the entity matches this registration; otherwise . public bool MatchesEntity(NodeEntity entity) { - return Plugin.Guid == entity.PluginId && NodeData.Type.Name == entity.Type; + return PluginFeature.Id == entity.ProviderId && NodeData.Type.Name == entity.Type; } private void OnDisabled(object? sender, EventArgs e) { - Plugin.Disabled -= OnDisabled; + PluginFeature.Disabled -= OnDisabled; if (IsInStore) NodeTypeStore.Remove(this); } @@ -55,13 +55,13 @@ public class NodeTypeRegistration /// public class TypeColorRegistration { - internal TypeColorRegistration(Type type, SKColor color, Plugin plugin) + internal TypeColorRegistration(Type type, SKColor color, PluginFeature pluginFeature) { Type = type; Color = color; - Plugin = plugin; + PluginFeature = pluginFeature; - Plugin.Disabled += OnDisabled; + PluginFeature.Disabled += OnDisabled; } /// @@ -80,9 +80,9 @@ public class TypeColorRegistration public SKColor DarkenedColor => Color.Darken(0.35f); /// - /// Gets the plugin type color is associated with + /// Gets the plugin feature this type color is associated with /// - public Plugin Plugin { get; } + public PluginFeature PluginFeature { get; } /// /// Gets a boolean indicating whether the registration is in the internal Core store @@ -91,7 +91,7 @@ public class TypeColorRegistration private void OnDisabled(object? sender, EventArgs e) { - Plugin.Disabled -= OnDisabled; + PluginFeature.Disabled -= OnDisabled; if (IsInStore) NodeTypeStore.RemoveColor(this); } diff --git a/src/Artemis.Core/VisualScripting/Interfaces/INode.cs b/src/Artemis.Core/VisualScripting/Interfaces/INode.cs index 3bc2521fb..abe7ecedd 100644 --- a/src/Artemis.Core/VisualScripting/Interfaces/INode.cs +++ b/src/Artemis.Core/VisualScripting/Interfaces/INode.cs @@ -14,6 +14,11 @@ public interface INode : INotifyPropertyChanged, IBreakableModel /// Gets or sets the ID of the node. /// Guid Id { get; set; } + + /// + /// Gets + /// + NodeData? NodeData { get; set; } /// /// Gets the name of the node diff --git a/src/Artemis.Core/VisualScripting/NodeData.cs b/src/Artemis.Core/VisualScripting/NodeData.cs index 5b0c678e2..05359dba0 100644 --- a/src/Artemis.Core/VisualScripting/NodeData.cs +++ b/src/Artemis.Core/VisualScripting/NodeData.cs @@ -1,4 +1,5 @@ using System; +using Artemis.Core.Nodes; using Artemis.Storage.Entities.Profile.Nodes; namespace Artemis.Core; @@ -10,9 +11,9 @@ public class NodeData { #region Constructors - internal NodeData(Plugin plugin, Type type, string name, string description, string category, string helpUrl, Type? inputType, Type? outputType, Func create) + internal NodeData(NodeProvider provider, Type type, string name, string description, string category, string helpUrl, Type? inputType, Type? outputType) { - Plugin = plugin; + Provider = provider; Type = type; Name = name; Description = description; @@ -20,7 +21,6 @@ public class NodeData HelpUrl = helpUrl; InputType = inputType; OutputType = outputType; - _create = create; } #endregion @@ -35,14 +35,31 @@ public class NodeData /// The returning node of type public INode CreateNode(INodeScript script, NodeEntity? entity) { - INode node = _create(script, entity); + INode node = (INode) Provider.Plugin.Resolve(Type); + node.NodeData = this; if (string.IsNullOrWhiteSpace(node.Name)) node.Name = Name; if (string.IsNullOrWhiteSpace(node.Description)) node.Description = Description; if (string.IsNullOrWhiteSpace(node.HelpUrl)) node.HelpUrl = HelpUrl; + + if (entity != null) + { + node.X = entity.X; + node.Y = entity.Y; + try + { + if (node is Node nodeImplementation) + nodeImplementation.DeserializeStorage(entity.Storage); + } + catch + { + // ignored + } + } + node.TryInitialize(script); return node; } @@ -91,11 +108,11 @@ public class NodeData } #region Properties & Fields - + /// - /// Gets the plugin that provided this node data + /// Gets the node provider that provided this node data /// - public Plugin Plugin { get; } + public NodeProvider Provider { get; } /// /// Gets the type of this data represents diff --git a/src/Artemis.Core/VisualScripting/NodeScript.cs b/src/Artemis.Core/VisualScripting/NodeScript.cs index 7672f3504..e8ccddd4a 100644 --- a/src/Artemis.Core/VisualScripting/NodeScript.cs +++ b/src/Artemis.Core/VisualScripting/NodeScript.cs @@ -161,6 +161,7 @@ public abstract class NodeScript : CorePropertyChanged, INodeScript { foreach (INode node in _nodes) { + // ReSharper disable once SuspiciousTypeConversion.Global - Provided by plugins if (node is IDisposable disposable) disposable.Dispose(); } @@ -181,6 +182,7 @@ public abstract class NodeScript : CorePropertyChanged, INodeScript foreach (INode removeNode in removeNodes) { RemoveNode(removeNode); + // ReSharper disable once SuspiciousTypeConversion.Global - Provided by plugins if (removeNode is IDisposable disposable) disposable.Dispose(); } @@ -312,7 +314,7 @@ public abstract class NodeScript : CorePropertyChanged, INodeScript NodeEntity nodeEntity = new() { Id = node.Id, - PluginId = NodeTypeStore.GetPlugin(node)?.Guid ?? Constants.CorePlugin.Guid, + ProviderId = node.NodeData?.Provider.Id ?? Constants.CorePluginFeature.Id, Type = node.GetType().Name, X = node.X, Y = node.Y, diff --git a/src/Artemis.Core/VisualScripting/Nodes/Node.cs b/src/Artemis.Core/VisualScripting/Nodes/Node.cs index 5ff7dd254..3780e6e07 100644 --- a/src/Artemis.Core/VisualScripting/Nodes/Node.cs +++ b/src/Artemis.Core/VisualScripting/Nodes/Node.cs @@ -41,6 +41,9 @@ public abstract class Node : BreakableModel, INode set => SetAndNotify(ref _id, value); } + /// + public NodeData NodeData { get; set; } + private string _name; /// @@ -104,8 +107,6 @@ public abstract class Node : BreakableModel, INode /// public override string BrokenDisplayName => Name; - internal IContainer Container { get; set; } = null!; - #endregion #region Construtors diff --git a/src/Artemis.Core/VisualScripting/Nodes/NodeTStorageTViewModel.cs b/src/Artemis.Core/VisualScripting/Nodes/NodeTStorageTViewModel.cs index 98965c154..2b84a619e 100644 --- a/src/Artemis.Core/VisualScripting/Nodes/NodeTStorageTViewModel.cs +++ b/src/Artemis.Core/VisualScripting/Nodes/NodeTStorageTViewModel.cs @@ -25,7 +25,7 @@ public abstract class Node : Node, ICustomViewMo /// public virtual TViewModel GetViewModel(NodeScript nodeScript) { - return Container.Resolve(args: new object[] {this, nodeScript}); + return NodeData.Provider.Plugin.Container.Resolve(args: new object[] {this, nodeScript}); } /// diff --git a/src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs b/src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs index 5683e5c0f..63d98770b 100644 --- a/src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs @@ -15,7 +15,7 @@ public class NodeEntity { Id = nodeEntity.Id; Type = nodeEntity.Type; - PluginId = nodeEntity.PluginId; + ProviderId = nodeEntity.ProviderId; Name = nodeEntity.Name; Description = nodeEntity.Description; @@ -29,7 +29,7 @@ public class NodeEntity public Guid Id { get; set; } public string Type { get; set; } - public Guid PluginId { get; set; } + public string ProviderId { get; set; } public string Name { get; set; } public string Description { get; set; } diff --git a/src/Artemis.Storage/Migrations/M0021GradientNodes.cs b/src/Artemis.Storage/Migrations/M0021GradientNodes.cs index dba1e8956..cfb735f1c 100644 --- a/src/Artemis.Storage/Migrations/M0021GradientNodes.cs +++ b/src/Artemis.Storage/Migrations/M0021GradientNodes.cs @@ -22,7 +22,7 @@ public class M0021GradientNodes : IStorageMigration { Id = Guid.NewGuid(), Type = "ColorGradientNode", - PluginId = Guid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff"), + ProviderId = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78", Name = "Color Gradient", Description = "Outputs a color gradient with the given colors", X = exitNode.X, diff --git a/src/Artemis.Storage/Repositories/PluginRepository.cs b/src/Artemis.Storage/Repositories/PluginRepository.cs index 6d659af47..c11673597 100644 --- a/src/Artemis.Storage/Repositories/PluginRepository.cs +++ b/src/Artemis.Storage/Repositories/PluginRepository.cs @@ -29,7 +29,6 @@ internal class PluginRepository : IPluginRepository public void SavePlugin(PluginEntity pluginEntity) { _repository.Upsert(pluginEntity); - _repository.Database.Checkpoint(); } public void AddSetting(PluginSettingEntity pluginSettingEntity) diff --git a/src/Artemis.UI.Shared/Services/DataModelUIService.cs b/src/Artemis.UI.Shared/Services/DataModelUIService.cs index f7fe353f6..fc8569711 100644 --- a/src/Artemis.UI.Shared/Services/DataModelUIService.cs +++ b/src/Artemis.UI.Shared/Services/DataModelUIService.cs @@ -18,16 +18,20 @@ internal class DataModelUIService : IDataModelUIService private readonly IContainer _container; private readonly List _registeredDataModelDisplays; private readonly List _registeredDataModelEditors; + private readonly PluginSetting _showFullPaths; + private readonly PluginSetting _showDataModelValues; - public DataModelUIService(IDataModelService dataModelService, IContainer container) + public DataModelUIService(IDataModelService dataModelService, IContainer container, ISettingsService settingsService) { _dataModelService = dataModelService; _container = container; _registeredDataModelEditors = new List(); _registeredDataModelDisplays = new List(); - + RegisteredDataModelEditors = new ReadOnlyCollection(_registeredDataModelEditors); RegisteredDataModelDisplays = new ReadOnlyCollection(_registeredDataModelDisplays); + ShowFullPaths = settingsService.GetSetting("ProfileEditor.ShowFullPaths", true); + ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false); } private DataModelInputViewModel InstantiateDataModelInputViewModel(DataModelVisualizationRegistration registration, DataModelPropertyAttribute? description, object? initialValue) @@ -43,7 +47,9 @@ internal class DataModelUIService : IDataModelUIService public IReadOnlyCollection RegisteredDataModelEditors { get; } public IReadOnlyCollection RegisteredDataModelDisplays { get; } - + public PluginSetting ShowFullPaths { get; } + public PluginSetting ShowDataModelValues { get; } + public DataModelPropertiesViewModel GetMainDataModelVisualization() { DataModelPropertiesViewModel viewModel = new(null, null, null); diff --git a/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs b/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs index a91766a44..b70c5e8af 100644 --- a/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs +++ b/src/Artemis.UI.Shared/Services/Interfaces/IDataModelUIService.cs @@ -104,4 +104,14 @@ public interface IDataModelUIService : IArtemisSharedUIService /// A function to call whenever the input was updated (submitted or not) /// The most appropriate input view model for the provided DataModelInputViewModel? GetDataModelInputViewModel(Type propertyType, DataModelPropertyAttribute? description, object? initialValue, Action updateCallback); + + /// + /// Gets a boolean indicating whether or not to show full paths when displaying data model paths. + /// + PluginSetting ShowFullPaths { get; } + + /// + /// Gets a boolean indicating whether or not to show values when displaying data model paths. + /// + PluginSetting ShowDataModelValues { get; } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Services/NodeEditor/Commands/AddNode.cs b/src/Artemis.UI.Shared/Services/NodeEditor/Commands/AddNode.cs index 3d6033784..c3bff92f1 100644 --- a/src/Artemis.UI.Shared/Services/NodeEditor/Commands/AddNode.cs +++ b/src/Artemis.UI.Shared/Services/NodeEditor/Commands/AddNode.cs @@ -27,6 +27,7 @@ public class AddNode : INodeEditorCommand, IDisposable /// public void Dispose() { + // ReSharper disable once SuspiciousTypeConversion.Global - Provided by plugins if (_isRemoved && _node is IDisposable disposableNode) disposableNode.Dispose(); } diff --git a/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DeleteNode.cs b/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DeleteNode.cs index 944c81e81..d40664d58 100644 --- a/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DeleteNode.cs +++ b/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DeleteNode.cs @@ -29,6 +29,7 @@ public class DeleteNode : INodeEditorCommand, IDisposable /// public void Dispose() { + // ReSharper disable once SuspiciousTypeConversion.Global - Provided by plugins if (_isRemoved && _node is IDisposable disposableNode) disposableNode.Dispose(); } diff --git a/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DuplicateNode.cs b/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DuplicateNode.cs index 62340d3a6..b872e069e 100644 --- a/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DuplicateNode.cs +++ b/src/Artemis.UI.Shared/Services/NodeEditor/Commands/DuplicateNode.cs @@ -87,6 +87,7 @@ public class DuplicateNode : INodeEditorCommand, IDisposable /// public void Dispose() { + // ReSharper disable once SuspiciousTypeConversion.Global - Provided by plugins if (!_executed && _copy is IDisposable disposableNode) disposableNode.Dispose(); } diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 88b39600b..582b75799 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -10,7 +10,6 @@ - diff --git a/src/Artemis.UI/ArtemisBootstrapper.cs b/src/Artemis.UI/ArtemisBootstrapper.cs index f869bb8e3..1da2a10ec 100644 --- a/src/Artemis.UI/ArtemisBootstrapper.cs +++ b/src/Artemis.UI/ArtemisBootstrapper.cs @@ -10,10 +10,8 @@ using Artemis.UI.Screens.Root; using Artemis.UI.Shared.DataModelPicker; using Artemis.UI.Shared.DryIoc; using Artemis.UI.Shared.Services; -using Artemis.VisualScripting.DryIoc; using Artemis.WebClient.Updating.DryIoc; using Artemis.WebClient.Workshop.DryIoc; -using Artemis.WebClient.Workshop.Services; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; @@ -49,7 +47,6 @@ public static class ArtemisBootstrapper _container.RegisterSharedUI(); _container.RegisterUpdatingClient(); _container.RegisterWorkshopClient(); - _container.RegisterNoStringEvaluating(); configureServices?.Invoke(_container); _container.UseDryIocDependencyResolver(); diff --git a/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs b/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs index 722bfbf26..db39dd1f2 100644 --- a/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs +++ b/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs @@ -18,11 +18,13 @@ using DynamicData; using DynamicData.Binding; using PropertyChanged.SourceGenerator; using ReactiveUI; +using Serilog; namespace Artemis.UI.Screens.VisualScripting; public partial class NodeViewModel : ActivatableViewModelBase { + private readonly ILogger _logger; private readonly INodeEditorService _nodeEditorService; private readonly IWindowService _windowService; private ObservableAsPropertyHelper? _hasInputPins; @@ -39,8 +41,9 @@ public partial class NodeViewModel : ActivatableViewModelBase [Notify] private bool _displayCustomViewModelBelow; [Notify] private VerticalAlignment _customViewModelVerticalAlignment; - public NodeViewModel(NodeScriptViewModel nodeScriptViewModel, INode node, INodeVmFactory nodeVmFactory, INodeEditorService nodeEditorService, IWindowService windowService) + public NodeViewModel(NodeScriptViewModel nodeScriptViewModel, INode node, ILogger logger, INodeVmFactory nodeVmFactory, INodeEditorService nodeEditorService, IWindowService windowService) { + _logger = logger; _nodeEditorService = nodeEditorService; _windowService = windowService; NodeScriptViewModel = nodeScriptViewModel; @@ -137,28 +140,42 @@ public partial class NodeViewModel : ActivatableViewModelBase }); // Set up the custom node VM if needed - if (Node is ICustomViewModelNode customViewModelNode) - { - CustomNodeViewModel = customViewModelNode.GetCustomViewModel(nodeScriptViewModel.NodeScript); - if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.AbovePins) - DisplayCustomViewModelAbove = true; - else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BelowPins) - DisplayCustomViewModelBelow = true; - else - { - DisplayCustomViewModelBetween = true; - - if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop) - CustomViewModelVerticalAlignment = VerticalAlignment.Top; - else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop) - CustomViewModelVerticalAlignment = VerticalAlignment.Center; - else - CustomViewModelVerticalAlignment = VerticalAlignment.Bottom; - } - } + SetupCustomNodeViewModel(); + }); } + private void SetupCustomNodeViewModel() + { + if (Node is not ICustomViewModelNode customViewModelNode) + return; + + try + { + CustomNodeViewModel = customViewModelNode.GetCustomViewModel(NodeScriptViewModel.NodeScript); + } + catch (Exception e) + { + _logger.Error(e, "Failed to instantiate custom node view model"); + } + + if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.AbovePins) + DisplayCustomViewModelAbove = true; + else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BelowPins) + DisplayCustomViewModelBelow = true; + else + { + DisplayCustomViewModelBetween = true; + + if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop) + CustomViewModelVerticalAlignment = VerticalAlignment.Top; + else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop) + CustomViewModelVerticalAlignment = VerticalAlignment.Center; + else + CustomViewModelVerticalAlignment = VerticalAlignment.Bottom; + } + } + public bool IsStaticNode => _isStaticNode?.Value ?? true; public bool HasInputPins => _hasInputPins?.Value ?? false; public bool HasOutputPins => _hasOutputPins?.Value ?? false; diff --git a/src/Artemis.UI/Services/Interfaces/IRegistrationService.cs b/src/Artemis.UI/Services/Interfaces/IRegistrationService.cs index d77128fc3..08da9c640 100644 --- a/src/Artemis.UI/Services/Interfaces/IRegistrationService.cs +++ b/src/Artemis.UI/Services/Interfaces/IRegistrationService.cs @@ -6,5 +6,4 @@ public interface IRegistrationService : IArtemisUIService void RegisterBuiltInDataModelInputs(); void RegisterBuiltInPropertyEditors(); void RegisterControllers(); - void RegisterBuiltInNodeTypes(); } \ No newline at end of file diff --git a/src/Artemis.UI/Services/RegistrationService.cs b/src/Artemis.UI/Services/RegistrationService.cs index 32288e8c3..0a4447cda 100644 --- a/src/Artemis.UI/Services/RegistrationService.cs +++ b/src/Artemis.UI/Services/RegistrationService.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections; -using System.Linq; -using System.Reflection; +using System.Linq; using Artemis.Core; using Artemis.Core.Services; using Artemis.UI.Controllers; @@ -13,10 +10,8 @@ using Artemis.UI.Shared.Routing; using Artemis.UI.Shared.Services; using Artemis.UI.Shared.Services.ProfileEditor; using Artemis.UI.Shared.Services.PropertyInput; -using Artemis.VisualScripting.Nodes.Mathematics; using Avalonia; using DryIoc; -using SkiaSharp; namespace Artemis.UI.Services; @@ -26,7 +21,6 @@ public class RegistrationService : IRegistrationService private readonly IInputService _inputService; private readonly IContainer _container; private readonly IRouter _router; - private readonly INodeService _nodeService; private readonly IPropertyInputService _propertyInputService; private readonly IWebServerService _webServerService; private bool _registeredBuiltInPropertyEditors; @@ -36,7 +30,6 @@ public class RegistrationService : IRegistrationService IInputService inputService, IPropertyInputService propertyInputService, IProfileEditorService profileEditorService, - INodeService nodeService, IDataModelUIService dataModelUIService, IWebServerService webServerService, IDeviceLayoutService deviceLayoutService // here to make sure it is instantiated @@ -46,13 +39,11 @@ public class RegistrationService : IRegistrationService _router = router; _inputService = inputService; _propertyInputService = propertyInputService; - _nodeService = nodeService; _dataModelUIService = dataModelUIService; _webServerService = webServerService; CreateCursorResources(); RegisterRoutes(); - RegisterBuiltInNodeTypes(); RegisterControllers(); } @@ -105,22 +96,4 @@ public class RegistrationService : IRegistrationService { _webServerService.AddController(Constants.CorePlugin.Features.First().Instance!); } - - public void RegisterBuiltInNodeTypes() - { - _nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(bool), new SKColor(0xFFCD3232)); - _nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(string), new SKColor(0xFFFFD700)); - _nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(Numeric), new SKColor(0xFF32CD32)); - _nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(float), new SKColor(0xFFFF7C00)); - _nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(SKColor), new SKColor(0xFFAD3EED)); - _nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(IList), new SKColor(0xFFED3E61)); - _nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(Enum), new SKColor(0xFF1E90FF)); - _nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(ColorGradient), new SKColor(0xFF00B2A9)); - - foreach (Type nodeType in typeof(SumNumericsNode).Assembly.GetTypes().Where(t => typeof(INode).IsAssignableFrom(t) && t.IsPublic && !t.IsAbstract && !t.IsInterface)) - { - if (nodeType.GetCustomAttribute(typeof(NodeAttribute)) != null) - _nodeService.RegisterNodeType(Constants.CorePlugin, nodeType); - } - } } \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj b/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj deleted file mode 100644 index 90b14e4fa..000000000 --- a/src/Artemis.VisualScripting/Artemis.VisualScripting.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - net8.0 - enable - enable - x64 - - - - - - - - - - - diff --git a/src/Artemis.VisualScripting/Converters/JsonConverter.cs b/src/Artemis.VisualScripting/Converters/JsonConverter.cs deleted file mode 100644 index c23e257a6..000000000 --- a/src/Artemis.VisualScripting/Converters/JsonConverter.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Globalization; -using Artemis.Core; -using Avalonia.Data.Converters; -using Newtonsoft.Json; - -namespace Artemis.VisualScripting.Converters; - -/// -/// Converts input into . -/// -public class JsonConverter : IValueConverter -{ - /// - public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) - { - return JsonConvert.SerializeObject(value, Formatting.Indented); - } - - /// - public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) - { - string? json = value?.ToString(); - return json == null ? null : JsonConvert.DeserializeObject(json, targetType); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Converters/NumericConverter.cs b/src/Artemis.VisualScripting/Converters/NumericConverter.cs deleted file mode 100644 index 397b0564c..000000000 --- a/src/Artemis.VisualScripting/Converters/NumericConverter.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Globalization; -using Artemis.Core; -using Avalonia.Data.Converters; - -namespace Artemis.VisualScripting.Converters; - -/// -/// Converts input into . -/// -public class NumericConverter : IValueConverter -{ - /// - public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) - { - if (value is not Numeric numeric) - return value; - - object result = Numeric.IsTypeCompatible(targetType) ? numeric.ToType(targetType, NumberFormatInfo.InvariantInfo) : value; - return result; - } - - /// - public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) - { - return new Numeric(value); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/DryIoc/ContainerExtensions.cs b/src/Artemis.VisualScripting/DryIoc/ContainerExtensions.cs deleted file mode 100644 index ca4c9845c..000000000 --- a/src/Artemis.VisualScripting/DryIoc/ContainerExtensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -using DryIoc; -using Microsoft.Extensions.ObjectPool; -using NoStringEvaluating; -using NoStringEvaluating.Contract; -using NoStringEvaluating.Models.Values; -using NoStringEvaluating.Services.Cache; -using NoStringEvaluating.Services.Checking; -using NoStringEvaluating.Services.Parsing; -using NoStringEvaluating.Services.Parsing.NodeReaders; - -namespace Artemis.VisualScripting.DryIoc; - -/// -/// Provides an extension method to register services onto a DryIoc . -/// -public static class ContainerExtensions -{ - /// - /// Registers NoStringEvaluating services into the container. - /// - /// The builder building the current container - public static void RegisterNoStringEvaluating(this IContainer container) - { - // Pooling - container.RegisterInstance(ObjectPool.Create>()); - container.RegisterInstance(ObjectPool.Create>()); - container.RegisterInstance(ObjectPool.Create()); - - // Parser - container.Register(Reuse.Singleton); - container.Register(Reuse.Singleton); - container.Register(Reuse.Singleton); - - // Checker - container.Register(Reuse.Singleton); - - // Evaluator - container.Register(Reuse.Singleton); - container.Register(Reuse.Singleton); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Branching/BooleanBranchNode.cs b/src/Artemis.VisualScripting/Nodes/Branching/BooleanBranchNode.cs deleted file mode 100644 index b07aea8cf..000000000 --- a/src/Artemis.VisualScripting/Nodes/Branching/BooleanBranchNode.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Artemis.Core; -using Artemis.Core.Events; - -namespace Artemis.VisualScripting.Nodes.Branching; - -[Node("Branch", "Forwards one of two values depending on an input boolean", "Branching", InputType = typeof(object), OutputType = typeof(object))] -public class BooleanBranchNode : Node -{ - public BooleanBranchNode() - { - BooleanInput = CreateInputPin(); - TrueInput = CreateInputPin(typeof(object), "True"); - FalseInput = CreateInputPin(typeof(object), "False"); - - Output = CreateOutputPin(typeof(object)); - - TrueInput.PinConnected += InputPinConnected; - FalseInput.PinConnected += InputPinConnected; - TrueInput.PinDisconnected += InputPinDisconnected; - FalseInput.PinDisconnected += InputPinDisconnected; - } - - public InputPin BooleanInput { get; set; } - public InputPin TrueInput { get; set; } - public InputPin FalseInput { get; set; } - - public OutputPin Output { get; set; } - - #region Overrides of Node - - /// - public override void Evaluate() - { - Output.Value = BooleanInput.Value ? TrueInput.Value : FalseInput.Value; - } - - #endregion - - private void InputPinConnected(object? sender, SingleValueEventArgs e) - { - if (TrueInput.ConnectedTo.Any()) - ChangeType(TrueInput.ConnectedTo.First().Type); - else if (FalseInput.ConnectedTo.Any()) - ChangeType(FalseInput.ConnectedTo.First().Type); - } - - private void InputPinDisconnected(object? sender, SingleValueEventArgs e) - { - if (!TrueInput.ConnectedTo.Any() && !FalseInput.ConnectedTo.Any()) - ChangeType(typeof(object)); - } - - private void ChangeType(Type type) - { - TrueInput.ChangeType(type); - FalseInput.ChangeType(type); - Output.ChangeType(type); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Branching/EnumSwitchNode.cs b/src/Artemis.VisualScripting/Nodes/Branching/EnumSwitchNode.cs deleted file mode 100644 index eb3803290..000000000 --- a/src/Artemis.VisualScripting/Nodes/Branching/EnumSwitchNode.cs +++ /dev/null @@ -1,100 +0,0 @@ -using Artemis.Core; -using Artemis.Core.Events; -using Humanizer; - -namespace Artemis.VisualScripting.Nodes.Branching; - -[Node("Switch (Enum)", "Outputs the input that corresponds to the switch value", "Operators", InputType = typeof(Enum), OutputType = typeof(object))] -public class EnumSwitchNode : Node -{ - private readonly Dictionary _inputPins; - - public EnumSwitchNode() - { - _inputPins = new Dictionary(); - - Output = CreateOutputPin(typeof(object), "Result"); - SwitchValue = CreateInputPin("Switch"); - - SwitchValue.PinConnected += OnSwitchPinConnected; - SwitchValue.PinDisconnected += OnSwitchPinDisconnected; - } - - public OutputPin Output { get; } - public InputPin SwitchValue { get; } - - public override void Evaluate() - { - if (SwitchValue.Value is null) - { - Output.Value = null; - return; - } - - if (!_inputPins.TryGetValue(SwitchValue.Value, out InputPin? pin)) - { - Output.Value = null; - return; - } - - if (pin.ConnectedTo.Count == 0) - { - Output.Value = null; - return; - } - - Output.Value = pin.Value; - } - - private void OnInputPinDisconnected(object? sender, SingleValueEventArgs e) - { - // if this is the last pin to disconnect, reset the type. - if (_inputPins.Values.All(i => i.ConnectedTo.Count == 0)) - ChangeType(typeof(object)); - } - - private void OnInputPinConnected(object? sender, SingleValueEventArgs e) - { - // change the type of our inputs and output - // depending on the first node the user connects to - ChangeType(e.Value.Type); - } - - private void OnSwitchPinConnected(object? sender, SingleValueEventArgs e) - { - if (SwitchValue.ConnectedTo.Count == 0) - return; - - Type enumType = SwitchValue.ConnectedTo[0].Type; - if (!enumType.IsEnum) - return; - - foreach (Enum enumValue in Enum.GetValues(enumType).Cast()) - { - InputPin pin = CreateOrAddInputPin(typeof(object), enumValue.Humanize(LetterCasing.Sentence)); - pin.PinConnected += OnInputPinConnected; - pin.PinDisconnected += OnInputPinDisconnected; - _inputPins[enumValue] = pin; - } - } - - private void OnSwitchPinDisconnected(object? sender, SingleValueEventArgs e) - { - foreach (InputPin input in _inputPins.Values) - { - input.PinConnected -= OnInputPinConnected; - input.PinDisconnected -= OnInputPinDisconnected; - RemovePin(input); - } - - _inputPins.Clear(); - ChangeType(typeof(object)); - } - - private void ChangeType(Type type) - { - foreach (InputPin input in _inputPins.Values) - input.ChangeType(type); - Output.ChangeType(type); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/BrightenSKColorNode.cs b/src/Artemis.VisualScripting/Nodes/Color/BrightenSKColorNode.cs deleted file mode 100644 index e5adaad4e..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/BrightenSKColorNode.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Brighten Color", "Brightens a color by a specified amount in percent", "Color", InputType = typeof(SKColor), OutputType = typeof(SKColor))] -public class BrightenSKColorNode : Node -{ - public BrightenSKColorNode() - { - Input = CreateInputPin("Color"); - Percentage = CreateInputPin("%"); - Output = CreateOutputPin(); - } - - public InputPin Input { get; } - public InputPin Percentage { get; } - public OutputPin Output { get; set; } - - public override void Evaluate() - { - Input.Value.ToHsl(out float h, out float s, out float l); - l += l * (Percentage.Value / 100f); - Output.Value = SKColor.FromHsl(h, s, l); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/ColorGradientFromPinsNode.cs b/src/Artemis.VisualScripting/Nodes/Color/ColorGradientFromPinsNode.cs deleted file mode 100644 index 5467aecb7..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/ColorGradientFromPinsNode.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Artemis.Core; -using Artemis.Core.Events; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Color Gradient (Advanced)", "Outputs a Color Gradient from colors and positions", "Color", OutputType = typeof(ColorGradient))] -public class ColorGradientFromPinsNode : Node -{ - public OutputPin Gradient { get; set; } - public InputPinCollection Colors { get; set; } - public InputPinCollection Positions { get; set; } - - public ColorGradientFromPinsNode() - { - Colors = CreateInputPinCollection("Colors", 0); - Positions = CreateInputPinCollection("Positions", 0); - Gradient = CreateOutputPin("Gradient"); - - Colors.PinAdded += OnPinAdded; - Colors.PinRemoved += OnPinRemoved; - Positions.PinAdded += OnPinAdded; - Positions.PinRemoved += OnPinRemoved; - } - - private void OnPinRemoved(object? sender, SingleValueEventArgs e) - { - int colorsCount = Colors.Count(); - int positionsCount = Positions.Count(); - if (colorsCount == positionsCount) - return; - - while (colorsCount > positionsCount) - { - IPin pinToRemove = Colors.Last(); - Colors.Remove(pinToRemove); - - --colorsCount; - } - - while (positionsCount > colorsCount) - { - IPin pinToRemove = Positions.Last(); - Positions.Remove(pinToRemove); - --positionsCount; - } - - RenamePins(); - } - - private void OnPinAdded(object? sender, SingleValueEventArgs e) - { - int colorsCount = Colors.Count(); - int positionsCount = Positions.Count(); - if (colorsCount == positionsCount) - return; - - while (colorsCount < positionsCount) - { - Colors.Add(Colors.CreatePin()); - - ++colorsCount; - } - - while (positionsCount < colorsCount) - { - Positions.Add(Positions.CreatePin()); - - ++positionsCount; - } - - RenamePins(); - } - - private void RenamePins() - { - int colors = 0; - foreach (IPin item in Colors) - { - item.Name = $"Color #{++colors}"; - } - - int positions = 0; - foreach (IPin item in Positions) - { - item.Name = $"Position #{++positions}"; - } - } - - public override void Evaluate() - { - List stops = new List(); - InputPin[] colors = Colors.Pins.ToArray(); - InputPin[] positions = Positions.Pins.ToArray(); - for (int i = 0; i < colors.Length; i++) - { - stops.Add(new ColorGradientStop(colors[i].Value, positions[i].Value)); - } - - Gradient.Value = new ColorGradient(stops); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/ColorGradientNode.cs b/src/Artemis.VisualScripting/Nodes/Color/ColorGradientNode.cs deleted file mode 100644 index 18dc15f54..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/ColorGradientNode.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System.Collections.Specialized; -using Artemis.Core; -using Artemis.VisualScripting.Nodes.Color.Screens; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Color Gradient (Simple)", "Outputs a color gradient with the given colors", "Color", OutputType = typeof(ColorGradient))] -public class ColorGradientNode : Node -{ - private readonly List _inputPins; - - public ColorGradientNode() - { - _inputPins = new List(); - - Gradient = ColorGradient.GetUnicornBarf(); - Output = CreateOutputPin(); - ViewModelPosition = CustomNodeViewModelPosition.AbovePins; - } - - public ColorGradient Gradient { get; private set; } - public OutputPin Output { get; } - - public override void Initialize(INodeScript script) - { - UpdateGradient(); - ComputeInputPins(); - - // Not expecting storage to get modified, but lets just make sure - StorageModified += OnStorageModified; - } - - public override void Evaluate() - { - ColorGradientStop[] stops = Gradient.ToArray(); - - if (_inputPins.Count != stops.Length) - return; - - for (int i = 0; i < _inputPins.Count; i++) - { - // if nothing is connected, leave the stop alone. - if (_inputPins[i].ConnectedTo.Count == 0) - continue; - - // if the pin has a connection, update the stop. - if (_inputPins[i].PinValue is SKColor color) - stops[i].Color = color; - } - - Output.Value = Gradient; - } - - private void DisconnectAllInputPins() - { - foreach (InputPin item in _inputPins) - item.DisconnectAll(); - } - - private void UpdateGradient() - { - Gradient.CollectionChanged -= OnGradientCollectionChanged; - if (Storage != null) - Gradient = Storage; - else - Storage = Gradient; - Gradient.CollectionChanged += OnGradientCollectionChanged; - } - - private void ComputeInputPins() - { - int newAmount = Gradient.Count; - if (newAmount == _inputPins.Count) - return; - - while (newAmount > _inputPins.Count) - _inputPins.Add(CreateOrAddInputPin(typeof(SKColor), string.Empty)); - - while (newAmount < _inputPins.Count) - { - InputPin pin = _inputPins.Last(); - RemovePin(pin); - _inputPins.Remove(pin); - } - - int index = 0; - foreach (InputPin item in _inputPins) - item.Name = $"Color #{++index}"; - } - - private void OnStorageModified(object? sender, EventArgs e) - { - UpdateGradient(); - ComputeInputPins(); - } - - private void OnGradientCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) - { - // if the user reorders the gradient, let it slide and do nothing. - // of course, the user might want to change the input pins since they will no longer line up. - if (e.Action == NotifyCollectionChangedAction.Move) - return; - - // DisconnectAllInputPins(); - ComputeInputPins(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/DarkenSKColorNode.cs b/src/Artemis.VisualScripting/Nodes/Color/DarkenSKColorNode.cs deleted file mode 100644 index 5b4983e40..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/DarkenSKColorNode.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Darken Color", "Darkens a color by a specified amount in percent", "Color", InputType = typeof(SKColor), OutputType = typeof(SKColor))] -public class DarkenSKColorNode : Node -{ - public DarkenSKColorNode() - { - Input = CreateInputPin("Color"); - Percentage = CreateInputPin("%"); - Output = CreateOutputPin(); - } - - public InputPin Input { get; } - public InputPin Percentage { get; } - public OutputPin Output { get; set; } - - public override void Evaluate() - { - Input.Value.ToHsl(out float h, out float s, out float l); - l -= l * (Percentage.Value / 100f); - Output.Value = SKColor.FromHsl(h, s, l); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/DesaturateSKColorNode.cs b/src/Artemis.VisualScripting/Nodes/Color/DesaturateSKColorNode.cs deleted file mode 100644 index f02e9b6f6..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/DesaturateSKColorNode.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Desaturate Color", "Desaturates a color by a specified amount in percent", "Color", InputType = typeof(SKColor), OutputType = typeof(SKColor))] -public class DesaturateSKColorNode : Node -{ - public DesaturateSKColorNode() - { - Input = CreateInputPin("Color"); - Percentage = CreateInputPin("%"); - Output = CreateOutputPin(); - } - - public InputPin Input { get; } - public InputPin Percentage { get; } - public OutputPin Output { get; set; } - - public override void Evaluate() - { - Input.Value.ToHsl(out float h, out float s, out float l); - s -= s * (Percentage.Value / 100f); - Output.Value = SKColor.FromHsl(h, Math.Clamp(s, 0f, 100f), l); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/GradientBuilderNode.cs b/src/Artemis.VisualScripting/Nodes/Color/GradientBuilderNode.cs deleted file mode 100644 index 26ff8067f..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/GradientBuilderNode.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color -{ - [Node("Gradient Builder", "Generates a gradient based on some values", "Color", OutputType = typeof(ColorGradient), HelpUrl = "https://krazydad.com/tutorials/makecolors.php")] - public class GradientBuilderNode : Node - { - public OutputPin Output { get; } - - public InputPin Frequency1 { get; } - public InputPin Frequency2 { get; } - public InputPin Frequency3 { get; } - public InputPin Phase1 { get; } - public InputPin Phase2 { get; } - public InputPin Phase3 { get; } - public InputPin Center { get; } - public InputPin Width { get; } - public InputPin Length { get; } - - public GradientBuilderNode() - { - Output = CreateOutputPin(); - Frequency1 = CreateInputPin("Frequency 1"); - Frequency2 = CreateInputPin("Frequency 2"); - Frequency3 = CreateInputPin("Frequency 3"); - Phase1 = CreateInputPin("Phase 1"); - Phase2 = CreateInputPin("Phase 2"); - Phase3 = CreateInputPin("Phase 3"); - Center = CreateInputPin("Center"); - Width = CreateInputPin("Width"); - Length = CreateInputPin("Length"); - } - - public override void Evaluate() - { - ColorGradient gradient = new ColorGradient(); - - for (int i = 0; i < Length.Value; i++) - { - Numeric r = Math.Sin(Frequency1.Value * i + Phase1.Value) * Width.Value + Center.Value; - Numeric g = Math.Sin(Frequency2.Value * i + Phase2.Value) * Width.Value + Center.Value; - Numeric b = Math.Sin(Frequency3.Value * i + Phase3.Value) * Width.Value + Center.Value; - gradient.Add(new ColorGradientStop(new SKColor((byte)r, (byte)g, (byte)b), i / Length.Value)); - } - - Output.Value = gradient; - } - } -} diff --git a/src/Artemis.VisualScripting/Nodes/Color/HslSKColorNode.cs b/src/Artemis.VisualScripting/Nodes/Color/HslSKColorNode.cs deleted file mode 100644 index 15ce66d84..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/HslSKColorNode.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("HSL Color", "Creates a color from hue, saturation and lightness numbers", "Color", InputType = typeof(Numeric), OutputType = typeof(SKColor))] -public class HslSKColorNode : Node -{ - public HslSKColorNode() - { - H = CreateInputPin("H"); - S = CreateInputPin("S"); - L = CreateInputPin("L"); - Output = CreateOutputPin(); - } - - public InputPin H { get; set; } - public InputPin S { get; set; } - public InputPin L { get; set; } - public OutputPin Output { get; } - - #region Overrides of Node - - /// - public override void Evaluate() - { - Output.Value = SKColor.FromHsl(H.Value, S.Value, L.Value); - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/HsvSKColorNode.cs b/src/Artemis.VisualScripting/Nodes/Color/HsvSKColorNode.cs deleted file mode 100644 index 2544ccec2..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/HsvSKColorNode.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("HSV Color", "Creates a color from hue, saturation and value numbers", "Color", InputType = typeof(Numeric), OutputType = typeof(SKColor))] -public class HsvSKColorNode : Node -{ - public HsvSKColorNode() - { - H = CreateInputPin("H"); - S = CreateInputPin("S"); - V = CreateInputPin("V"); - Output = CreateOutputPin(); - } - - public InputPin H { get; set; } - public InputPin S { get; set; } - public InputPin V { get; set; } - public OutputPin Output { get; } - - #region Overrides of Node - - /// - public override void Evaluate() - { - Output.Value = SKColor.FromHsv(H.Value, S.Value, V.Value); - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/InvertSKColorNode.cs b/src/Artemis.VisualScripting/Nodes/Color/InvertSKColorNode.cs deleted file mode 100644 index b194b8a01..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/InvertSKColorNode.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Invert Color", "Inverts a color by a specified amount in percent", "Color", InputType = typeof(SKColor), OutputType = typeof(SKColor))] -public class InvertSKColorNode : Node -{ - public InvertSKColorNode() - { - Input = CreateInputPin(); - Output = CreateOutputPin(); - } - - public InputPin Input { get; } - public OutputPin Output { get; set; } - - public override void Evaluate() - { - Output.Value = new SKColor( - (byte) (255 - Input.Value.Red), - (byte) (255 - Input.Value.Green), - (byte) (255 - Input.Value.Blue), - Input.Value.Alpha - ); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/LerpSKColorNode.cs b/src/Artemis.VisualScripting/Nodes/Color/LerpSKColorNode.cs deleted file mode 100644 index 7bf45e08d..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/LerpSKColorNode.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Artemis.Core; -using RGB.NET.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Lerp (Color)", "Interpolates linear between the two colors A and B", "Color", InputType = typeof(SKColor), OutputType = typeof(SKColor))] -public class LerpSKColorNode : Node -{ - #region Properties & Fields - - public InputPin A { get; } - public InputPin B { get; } - public InputPin T { get; } - - public OutputPin Result { get; } - - #endregion - - #region Constructors - - public LerpSKColorNode() - { - Name = "Lerp"; - A = CreateInputPin("A"); - B = CreateInputPin("B"); - T = CreateInputPin("T"); - - Result = CreateOutputPin(); - } - - #endregion - - #region Methods - - /// - public override void Evaluate() - { - SKColor a = A.Value; - SKColor b = B.Value; - float t = ((float)T.Value).Clamp(0f, 1f); - - float aAlpha = a.Alpha.GetPercentageFromByteValue(); - float aRed = a.Red.GetPercentageFromByteValue(); - float aGreen = a.Green.GetPercentageFromByteValue(); - float aBlue = a.Blue.GetPercentageFromByteValue(); - - float alpha = ((b.Alpha.GetPercentageFromByteValue() - aAlpha) * t) + aAlpha; - float red = ((b.Red.GetPercentageFromByteValue() - aRed) * t) + aRed; - float green = ((b.Green.GetPercentageFromByteValue() - aGreen) * t) + aGreen; - float blue = ((b.Blue.GetPercentageFromByteValue() - aBlue) * t) + aBlue; - - Result.Value = new SKColor(red.GetByteValueFromPercentage(), green.GetByteValueFromPercentage(), blue.GetByteValueFromPercentage(), alpha.GetByteValueFromPercentage()); - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/RampSKColorNode.cs b/src/Artemis.VisualScripting/Nodes/Color/RampSKColorNode.cs deleted file mode 100644 index c70e1489d..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/RampSKColorNode.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Artemis.Core; -using Artemis.VisualScripting.Nodes.Color.Screens; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Color Ramp", "Maps values to colors with the use of a gradient.", "Color", InputType = typeof(Numeric), OutputType = typeof(SKColor))] -public class RampSKColorNode : Node -{ - #region Constructors - - public RampSKColorNode() - { - Input = CreateInputPin(); - Output = CreateOutputPin(); - Storage = ColorGradient.GetUnicornBarf(); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - // Wrap the input between 0 and 1 - // 1 % 1 = 0, 2 % 1 = 0 etc. but we want that to be 1 but 0 should stay 0, call me stupid but this works and makes sense - float value = Input.Value % 1; - if (value == 0 && Input.Value != 0) - value = 1; - - Output.Value = Storage?.GetColor(value) ?? SKColor.Empty; - } - - #endregion - - #region Properties & Fields - - public InputPin Input { get; } - public OutputPin Output { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/RgbSKColorNode.cs b/src/Artemis.VisualScripting/Nodes/Color/RgbSKColorNode.cs deleted file mode 100644 index 7d3bd63b7..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/RgbSKColorNode.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("RGB Color", "Creates a color from red, green and blue values", "Color", InputType = typeof(Numeric), OutputType = typeof(SKColor))] -public class RgbSKColorNode : Node -{ - #region Properties & Fields - - public InputPin R { get; set; } - public InputPin G { get; set; } - public InputPin B { get; set; } - public OutputPin Output { get; } - - #endregion - - #region Constructors - - public RgbSKColorNode() - { - R = CreateInputPin("R"); - G = CreateInputPin("G"); - B = CreateInputPin("B"); - - Output = CreateOutputPin(); - } - - #endregion - - #region Methods - - /// - public override void Evaluate() => Output.Value = new SKColor(R.Value, G.Value, B.Value); - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/RotateHueSkColorNode.cs b/src/Artemis.VisualScripting/Nodes/Color/RotateHueSkColorNode.cs deleted file mode 100644 index 4325724b0..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/RotateHueSkColorNode.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Rotate Color Hue", "Rotates the hue of a color by a specified amount in degrees", "Color", InputType = typeof(SKColor), OutputType = typeof(SKColor))] -public class RotateHueSKColorNode : Node -{ - public RotateHueSKColorNode() - { - Input = CreateInputPin("Color"); - Amount = CreateInputPin("Amount"); - Output = CreateOutputPin(); - } - - public InputPin Input { get; } - public InputPin Amount { get; } - public OutputPin Output { get; set; } - - public override void Evaluate() - { - Input.Value.ToHsl(out float h, out float s, out float l); - h += Amount.Value; - Output.Value = SKColor.FromHsl(h % 360, s, l); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/SaturateSkColorNode.cs b/src/Artemis.VisualScripting/Nodes/Color/SaturateSkColorNode.cs deleted file mode 100644 index 1c8922262..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/SaturateSkColorNode.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Saturate Color", "Saturates a color by a specified amount in percent", "Color", InputType = typeof(SKColor), OutputType = typeof(SKColor))] -public class SaturateSKColorNode : Node -{ - public SaturateSKColorNode() - { - Input = CreateInputPin("Color"); - Percentage = CreateInputPin("%"); - Output = CreateOutputPin(); - } - - public InputPin Input { get; } - public InputPin Percentage { get; } - public OutputPin Output { get; set; } - - public override void Evaluate() - { - Input.Value.ToHsl(out float h, out float s, out float l); - s += s * (Percentage.Value / 100f); - Output.Value = SKColor.FromHsl(h, Math.Clamp(s, 0f, 100f), l); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomView.axaml deleted file mode 100644 index 404c13af2..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomView.axaml +++ /dev/null @@ -1,15 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomView.axaml.cs deleted file mode 100644 index ec578cde5..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomView.axaml.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Artemis.UI.Shared.Controls.GradientPicker; -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Color.Screens; - -public partial class ColorGradientNodeCustomView : ReactiveUserControl -{ - public ColorGradientNodeCustomView() - { - InitializeComponent(); - } - - - private void GradientPickerButton_OnFlyoutOpened(GradientPickerButton sender, EventArgs args) - { - } - - private void GradientPickerButton_OnFlyoutClosed(GradientPickerButton sender, EventArgs args) - { - ViewModel?.StoreGradient(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomViewModel.cs deleted file mode 100644 index 1b586f24a..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/Screens/ColorGradientNodeCustomViewModel.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; - -namespace Artemis.VisualScripting.Nodes.Color.Screens; - -public class ColorGradientNodeCustomViewModel : CustomNodeViewModel -{ - private readonly ColorGradientNode _node; - private readonly INodeEditorService _nodeEditorService; - - /// - public ColorGradientNodeCustomViewModel(ColorGradientNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - - Gradient = _node.Gradient; - } - - public ColorGradient Gradient { get; } - - public void StoreGradient() - { - _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, Gradient)); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomView.axaml deleted file mode 100644 index 4d05928ed..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomView.axaml +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomView.axaml.cs deleted file mode 100644 index d70520a1d..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomView.axaml.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Artemis.UI.Shared.Controls.GradientPicker; -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Color.Screens; - -public partial class RampSKColorNodeCustomView : ReactiveUserControl -{ - public RampSKColorNodeCustomView() - { - InitializeComponent(); - } - - - private void GradientPickerButton_OnFlyoutOpened(GradientPickerButton sender, EventArgs args) - { - } - - private void GradientPickerButton_OnFlyoutClosed(GradientPickerButton sender, EventArgs args) - { - ViewModel?.StoreGradient(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomViewModel.cs deleted file mode 100644 index cbd1a9539..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/Screens/RampSKColorNodeCustomViewModel.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; - -namespace Artemis.VisualScripting.Nodes.Color.Screens; - -public class RampSKColorNodeCustomViewModel : CustomNodeViewModel -{ - private readonly RampSKColorNode _node; - private readonly INodeEditorService _nodeEditorService; - - /// - public RampSKColorNodeCustomViewModel(RampSKColorNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - - Gradient = _node.Storage ?? new ColorGradient(); - } - - public ColorGradient Gradient { get; } - - public void StoreGradient() - { - _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, Gradient)); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/SkColorHsl.cs b/src/Artemis.VisualScripting/Nodes/Color/SkColorHsl.cs deleted file mode 100644 index aaa1c6e26..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/SkColorHsl.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Color to HSL", "Outputs H, S and L values from a color", "Color", InputType = typeof(SKColor), OutputType = typeof(Numeric))] -public class SkColorHsl : Node -{ - - public SkColorHsl() - { - Input = CreateInputPin(); - H = CreateOutputPin("H"); - S = CreateOutputPin("S"); - L = CreateOutputPin("L"); - } - - public InputPin Input { get; } - public OutputPin H { get; } - public OutputPin S { get; } - public OutputPin L { get; } - - #region Overrides of Node - - /// - public override void Evaluate() - { - Input.Value.ToHsl(out float h, out float s, out float l); - - H.Value = h; - S.Value = s; - L.Value = l; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/SkColorHsv.cs b/src/Artemis.VisualScripting/Nodes/Color/SkColorHsv.cs deleted file mode 100644 index a0e448cf4..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/SkColorHsv.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Color to HSV", "Outputs H, S and L values from a color", "Color", InputType = typeof(SKColor), OutputType = typeof(Numeric))] -public class SkColorHsv : Node -{ - - public SkColorHsv() - { - Input = CreateInputPin(); - H = CreateOutputPin("H"); - S = CreateOutputPin("S"); - V = CreateOutputPin("V"); - } - - public InputPin Input { get; } - public OutputPin H { get; } - public OutputPin S { get; } - public OutputPin V { get; } - - #region Overrides of Node - - /// - public override void Evaluate() - { - Input.Value.ToHsv(out float h, out float s, out float v); - - H.Value = h; - S.Value = s; - V.Value = v; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Color/SortedGradient.cs b/src/Artemis.VisualScripting/Nodes/Color/SortedGradient.cs deleted file mode 100644 index 00cdd61d0..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/SortedGradient.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Artemis.Core; -using Artemis.Core.ColorScience; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color -{ - [Node("Sorted Gradient", "Generates a sorted gradient from the given colors", "Color", InputType = typeof(SKColor), OutputType = typeof(ColorGradient))] - public class SortedGradientNode : Node - { - private int lastComputedColorGroup; - public InputPinCollection Inputs { get; } - public OutputPin Output { get; } - - public SortedGradientNode() - { - Inputs = CreateInputPinCollection(); - Output = CreateOutputPin(); - lastComputedColorGroup = 0; - } - - public override void Evaluate() - { - int newHash = GetInputColorHash(); - if (newHash == lastComputedColorGroup) - return; - - SKColor[] colors = Inputs.Values.ToArray(); - - if (colors.Length == 0) - { - Output.Value = null; - return; - } - - ColorSorter.Sort(colors, SKColors.Black); - - ColorGradient gradient = new(); - for (int i = 0; i < colors.Length; i++) - { - gradient.Add(new ColorGradientStop(colors[i], (float)i / (colors.Length - 1))); - } - - Output.Value = gradient; - lastComputedColorGroup = newHash; - } - - private int GetInputColorHash() - { - int hash = 0; - - foreach (SKColor color in Inputs.Values) - hash = HashCode.Combine(hash, color.GetHashCode()); - - return hash; - } - } -} diff --git a/src/Artemis.VisualScripting/Nodes/Color/SumSKColorsNode.cs b/src/Artemis.VisualScripting/Nodes/Color/SumSKColorsNode.cs deleted file mode 100644 index 49b86ed14..000000000 --- a/src/Artemis.VisualScripting/Nodes/Color/SumSKColorsNode.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Color; - -[Node("Sum (Color)", "Sums the connected color values.", "Color", InputType = typeof(SKColor), OutputType = typeof(SKColor))] -public class SumSKColorsNode : Node -{ - #region Constructors - - public SumSKColorsNode() - { - Name = "Sum"; - Values = CreateInputPinCollection("Values", 2); - Sum = CreateOutputPin("Sum"); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - SKColor result = SKColor.Empty; - - bool first = true; - foreach (SKColor current in Values.Values) - { - result = first ? current : result.Sum(current); - first = false; - } - - Sum.Value = result; - } - - #endregion - - #region Properties & Fields - - public InputPinCollection Values { get; } - - public OutputPin Sum { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Conversion/ConvertToNumericNode.cs b/src/Artemis.VisualScripting/Nodes/Conversion/ConvertToNumericNode.cs deleted file mode 100644 index 0dcfb6e1b..000000000 --- a/src/Artemis.VisualScripting/Nodes/Conversion/ConvertToNumericNode.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Conversion; - -[Node("To Numeric", "Converts the input to a numeric.", "Conversion", InputType = typeof(object), OutputType = typeof(Numeric))] -public class ConvertToNumericNode : Node -{ - #region Constructors - - public ConvertToNumericNode() - { - Input = CreateInputPin(); - Output = CreateOutputPin(); - } - - #endregion - - #region Properties & Fields - - public InputPin Input { get; } - - public OutputPin Output { get; } - - #endregion - - #region Methods - - public override void Evaluate() - { - Output.Value = Input.Value switch - { - int input => new Numeric(input), - double input => new Numeric(input), - float input => new Numeric(input), - byte input => new Numeric(input), - bool input => new Numeric(input ? 1 : 0), - _ => TryParse(Input.Value) - }; - } - - private Numeric TryParse(object? input) - { - Numeric.TryParse(input?.ToString(), out Numeric value); - return value; - } - - #endregion -} diff --git a/src/Artemis.VisualScripting/Nodes/Conversion/ConvertToStringNode.cs b/src/Artemis.VisualScripting/Nodes/Conversion/ConvertToStringNode.cs deleted file mode 100644 index d54d5ab7a..000000000 --- a/src/Artemis.VisualScripting/Nodes/Conversion/ConvertToStringNode.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Conversion; - -[Node("To Text", "Converts the input to text.", "Conversion", InputType = typeof(object), OutputType = typeof(string))] -public class ConvertToStringNode : Node -{ - #region Constructors - - public ConvertToStringNode() - { - Input = CreateInputPin(); - String = CreateOutputPin(); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - String.Value = Input.Value?.ToString(); - } - - #endregion - - #region Properties & Fields - - public InputPin Input { get; } - - public OutputPin String { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/DataModelEventCycleNode.cs b/src/Artemis.VisualScripting/Nodes/DataModel/DataModelEventCycleNode.cs deleted file mode 100644 index 6ab264a77..000000000 --- a/src/Artemis.VisualScripting/Nodes/DataModel/DataModelEventCycleNode.cs +++ /dev/null @@ -1,171 +0,0 @@ -using Artemis.Core; -using Artemis.Core.Events; -using Artemis.Storage.Entities.Profile; -using Artemis.VisualScripting.Nodes.DataModel.Screens; - -namespace Artemis.VisualScripting.Nodes.DataModel; - -[Node("Data Model-Event Value Cycle", "Cycles through provided values each time the select event fires.", "Data Model", OutputType = typeof(object))] -public class DataModelEventCycleNode : Node, IDisposable -{ - private int _currentIndex; - private Type _currentType; - private DataModelPath? _dataModelPath; - private IDataModelEvent? _subscribedEvent; - private object? _lastPathValue; - private bool _updating; - - public DataModelEventCycleNode() - { - _currentType = typeof(object); - - CycleValues = CreateInputPinCollection(typeof(object), "", 0); - Output = CreateOutputPin(typeof(object)); - - CycleValues.PinAdded += OnCycleValuesOnPinAdded; - CycleValues.PinRemoved += OnCycleValuesOnPinRemoved; - CycleValues.Add(CycleValues.CreatePin()); - - // Monitor storage for changes - StorageModified += (_, _) => UpdateDataModelPath(); - } - - public INodeScript? Script { get; set; } - - public InputPinCollection CycleValues { get; } - public OutputPin Output { get; } - - public override void Initialize(INodeScript script) - { - Script = script; - - if (Storage != null) - UpdateDataModelPath(); - } - - public override void Evaluate() - { - object? pathValue = _dataModelPath?.GetValue(); - if (pathValue is not IDataModelEvent && EvaluateValue(pathValue)) - Cycle(); - - object? outputValue = CycleValues.ElementAt(_currentIndex).PinValue; - if (Output.Type.IsInstanceOfType(outputValue)) - Output.Value = outputValue; - else if (Output.Type.IsValueType) - Output.Value = Output.Type.GetDefault()!; - } - - private bool EvaluateValue(object? pathValue) - { - if (Equals(pathValue, _lastPathValue)) - return false; - - _lastPathValue = pathValue; - return true; - } - - private void Cycle() - { - _currentIndex++; - - if (_currentIndex >= CycleValues.Count()) - _currentIndex = 0; - } - - private void UpdateDataModelPath() - { - DataModelPath? old = _dataModelPath; - - if (_subscribedEvent != null) - { - _subscribedEvent.EventTriggered -= OnEventTriggered; - _subscribedEvent = null; - } - - _dataModelPath = Storage != null ? new DataModelPath(Storage) : null; - - if (_dataModelPath?.GetValue() is IDataModelEvent newEvent) - { - _subscribedEvent = newEvent; - _subscribedEvent.EventTriggered += OnEventTriggered; - } - - old?.Dispose(); - } - - private void ChangeCurrentType(Type type) - { - CycleValues.ChangeType(type); - Output.ChangeType(type); - - _currentType = type; - } - - private void OnEventTriggered(object? sender, EventArgs e) - { - Cycle(); - } - - private void OnCycleValuesOnPinAdded(object? sender, SingleValueEventArgs e) - { - e.Value.PinConnected += OnPinConnected; - e.Value.PinDisconnected += OnPinDisconnected; - } - - private void OnCycleValuesOnPinRemoved(object? sender, SingleValueEventArgs e) - { - e.Value.PinConnected -= OnPinConnected; - e.Value.PinDisconnected -= OnPinDisconnected; - } - - private void OnPinDisconnected(object? sender, SingleValueEventArgs e) - { - if (_updating) - return; - - try - { - // If there's still a connected pin, stick to the current type - if (CycleValues.Any(v => v.ConnectedTo.Any())) - return; - - ChangeCurrentType(typeof(object)); - } - finally - { - _updating = false; - } - } - - private void OnPinConnected(object? sender, SingleValueEventArgs e) - { - if (_updating) - return; - - try - { - _updating = true; - - // No need to change anything if the types haven't changed - if (_currentType != e.Value.Type) - ChangeCurrentType(e.Value.Type); - } - finally - { - _updating = false; - } - } - - /// - public void Dispose() - { - if (_subscribedEvent != null) - { - _subscribedEvent.EventTriggered -= OnEventTriggered; - _subscribedEvent = null; - } - - _dataModelPath?.Dispose(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/DataModelEventNode.cs b/src/Artemis.VisualScripting/Nodes/DataModel/DataModelEventNode.cs deleted file mode 100644 index 1893e5cc5..000000000 --- a/src/Artemis.VisualScripting/Nodes/DataModel/DataModelEventNode.cs +++ /dev/null @@ -1,164 +0,0 @@ -using Artemis.Core; -using Artemis.Storage.Entities.Profile; -using Artemis.VisualScripting.Nodes.DataModel.Screens; - -namespace Artemis.VisualScripting.Nodes.DataModel; - -[Node("Data Model-Event", "Outputs the latest values of a data model event.", "Data Model", OutputType = typeof(object))] -public class DataModelEventNode : Node, IDisposable -{ - private readonly ObjectOutputPins _objectOutputPins; - private IDataModelEvent? _dataModelEvent; - private DataModelPath? _dataModelPath; - private DateTime _lastTrigger; - private object? _lastValue; - private OutputPin? _newValuePin; - private OutputPin? _oldValuePin; - private int _valueChangeCount; - - public DataModelEventNode() - { - _objectOutputPins = new ObjectOutputPins(this); - - TimeSinceLastTrigger = CreateOutputPin("Time since trigger"); - TriggerCount = CreateOutputPin("Trigger count"); - - // Monitor storage for changes - StorageModified += (_, _) => UpdateDataModelPath(); - } - - public INodeScript? Script { get; set; } - public OutputPin TimeSinceLastTrigger { get; } - public OutputPin TriggerCount { get; } - - public override void Initialize(INodeScript script) - { - Script = script; - - if (Storage == null) - return; - - UpdateDataModelPath(); - } - - public override void Evaluate() - { - object? pathValue = _dataModelPath?.GetValue(); - - // If the path is a data model event, evaluate the event - if (pathValue is IDataModelEvent dataModelEvent) - { - TimeSinceLastTrigger.Value = dataModelEvent.TimeSinceLastTrigger.TotalMilliseconds; - TriggerCount.Value = dataModelEvent.TriggerCount; - - _objectOutputPins.SetCurrentValue(dataModelEvent.LastEventArgumentsUntyped); - } - // If the path is a regular value, evaluate the current value - else if (_oldValuePin != null && _newValuePin != null) - { - if (_newValuePin.IsNumeric) - pathValue = new Numeric(pathValue); - - if (Equals(_lastValue, pathValue)) - { - TimeSinceLastTrigger.Value = (DateTime.Now - _lastTrigger).TotalMilliseconds; - return; - } - - _valueChangeCount++; - _lastTrigger = DateTime.Now; - - _oldValuePin.Value = _lastValue; - _newValuePin.Value = pathValue; - - _lastValue = pathValue; - - TimeSinceLastTrigger.Value = 0; - TriggerCount.Value = _valueChangeCount; - } - } - - private void UpdateDataModelPath() - { - DataModelPath? old = _dataModelPath; - _dataModelPath = Storage != null ? new DataModelPath(Storage) : null; - if (_dataModelPath != null) - _dataModelPath.PathValidated += DataModelPathOnPathValidated; - - if (old != null) - { - old.PathValidated -= DataModelPathOnPathValidated; - old.Dispose(); - } - - UpdateOutputPins(); - } - - private void UpdateOutputPins() - { - object? pathValue = _dataModelPath?.GetValue(); - - if (pathValue is IDataModelEvent dataModelEvent) - CreateEventPins(dataModelEvent); - else - CreateValuePins(); - } - - private void CreateEventPins(IDataModelEvent dataModelEvent) - { - if (_dataModelEvent == dataModelEvent) - return; - - ClearPins(); - _dataModelEvent = dataModelEvent; - _objectOutputPins.ChangeType(dataModelEvent.ArgumentsType); - } - - private void CreateValuePins() - { - ClearPins(); - - Type? propertyType = _dataModelPath?.GetPropertyType(); - if (propertyType == null) - return; - - if (Numeric.IsTypeCompatible(propertyType)) - propertyType = typeof(Numeric); - - _oldValuePin = CreateOrAddOutputPin(propertyType, "Old value"); - _newValuePin = CreateOrAddOutputPin(propertyType, "New value"); - _lastValue = null; - _valueChangeCount = 0; - } - - private void ClearPins() - { - // Clear the output pins by changing the type to null - _objectOutputPins.ChangeType(null); - - if (_oldValuePin != null) - { - RemovePin(_oldValuePin); - _oldValuePin = null; - } - - if (_newValuePin != null) - { - RemovePin(_newValuePin); - _newValuePin = null; - } - } - - private void DataModelPathOnPathValidated(object? sender, EventArgs e) - { - // Update the output pin now that the type is known and attempt to restore the connection that was likely missing - UpdateOutputPins(); - Script?.LoadConnections(); - } - - /// - public void Dispose() - { - _dataModelPath?.Dispose(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/DataModelNode.cs b/src/Artemis.VisualScripting/Nodes/DataModel/DataModelNode.cs deleted file mode 100644 index 1488796e9..000000000 --- a/src/Artemis.VisualScripting/Nodes/DataModel/DataModelNode.cs +++ /dev/null @@ -1,88 +0,0 @@ -using Artemis.Core; -using Artemis.Storage.Entities.Profile; -using Artemis.VisualScripting.Nodes.DataModel.Screens; - -namespace Artemis.VisualScripting.Nodes.DataModel; - -[Node("Data Model-Value", "Outputs a selectable data model value.", "Data Model", OutputType = typeof(object))] -public class DataModelNode : Node, IDisposable -{ - private DataModelPath? _dataModelPath; - - public DataModelNode() - { - Output = CreateOutputPin(typeof(object)); - StorageModified += (_, _) => UpdateDataModelPath(); - } - - public INodeScript? Script { get; private set; } - public OutputPin Output { get; } - - public override void Initialize(INodeScript script) - { - Script = script; - - if (Storage == null) - return; - - UpdateDataModelPath(); - } - - public override void Evaluate() - { - if (_dataModelPath == null || !_dataModelPath.IsValid) - return; - - object? pathValue = _dataModelPath.GetValue(); - if (pathValue == null) - { - if (!Output.Type.IsValueType) - Output.Value = null; - } - else - { - Output.Value = Output.IsNumeric ? new Numeric(pathValue) : pathValue; - } - } - - public void UpdateOutputPin() - { - Type? type = _dataModelPath?.GetPropertyType(); - if (type == null) - type = typeof(object); - else if (Numeric.IsTypeCompatible(type)) - type = typeof(Numeric); - - if (Output.Type != type) - Output.ChangeType(type); - } - - private void UpdateDataModelPath() - { - DataModelPath? old = _dataModelPath; - _dataModelPath = Storage != null ? new DataModelPath(Storage) : null; - if (_dataModelPath != null) - _dataModelPath.PathValidated += DataModelPathOnPathValidated; - - if (old != null) - { - old.PathValidated -= DataModelPathOnPathValidated; - old.Dispose(); - } - - UpdateOutputPin(); - } - - private void DataModelPathOnPathValidated(object? sender, EventArgs e) - { - // Update the output pin now that the type is known and attempt to restore the connection that was likely missing - UpdateOutputPin(); - Script?.LoadConnections(); - } - - /// - public void Dispose() - { - _dataModelPath?.Dispose(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomView.axaml deleted file mode 100644 index f98ebc0d9..000000000 --- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomView.axaml +++ /dev/null @@ -1,18 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomView.axaml.cs deleted file mode 100644 index 39c27cb08..000000000 --- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.DataModel.Screens; - -public partial class DataModelEventCycleNodeCustomView : ReactiveUserControl -{ - public DataModelEventCycleNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomViewModel.cs deleted file mode 100644 index 20247322b..000000000 --- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventCycleNodeCustomViewModel.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System.Collections.ObjectModel; -using System.Reactive.Disposables; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.Core.Services; -using Artemis.Storage.Entities.Profile; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.DataModel.Screens; - -public class DataModelEventCycleNodeCustomViewModel : CustomNodeViewModel -{ - private readonly DataModelEventCycleNode _cycleNode; - private readonly INodeEditorService _nodeEditorService; - private DataModelPath? _dataModelPath; - private ObservableCollection? _modules; - private bool _updating; - - public DataModelEventCycleNodeCustomViewModel(DataModelEventCycleNode cycleNode, INodeScript script, ISettingsService settingsService, INodeEditorService nodeEditorService) : base(cycleNode, script) - { - _cycleNode = cycleNode; - _nodeEditorService = nodeEditorService; - - ShowFullPaths = settingsService.GetSetting("ProfileEditor.ShowFullPaths", true); - ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false); - Modules = new ObservableCollection(); - - this.WhenActivated(d => - { - // Set up extra modules - if (_cycleNode.Script?.Context is Profile scriptProfile && scriptProfile.Configuration.Module != null) - Modules = new ObservableCollection {scriptProfile.Configuration.Module}; - else if (_cycleNode.Script?.Context is ProfileConfiguration profileConfiguration && profileConfiguration.Module != null) - Modules = new ObservableCollection {profileConfiguration.Module}; - - // Subscribe to node changes - _cycleNode.WhenAnyValue(n => n.Storage).Subscribe(UpdateDataModelPath).DisposeWith(d); - this.WhenAnyValue(vm => vm.DataModelPath).WhereNotNull().Subscribe(ApplyDataModelPath).DisposeWith(d); - - Disposable.Create(() => - { - _dataModelPath?.Dispose(); - _dataModelPath = null; - }).DisposeWith(d); - }); - } - - public PluginSetting ShowFullPaths { get; } - public PluginSetting ShowDataModelValues { get; } - - public ObservableCollection? Modules - { - get => _modules; - set => this.RaiseAndSetIfChanged(ref _modules, value); - } - - public DataModelPath? DataModelPath - { - get => _dataModelPath; - set => this.RaiseAndSetIfChanged(ref _dataModelPath, value); - } - - private void UpdateDataModelPath(DataModelPathEntity? entity) - { - try - { - if (_updating) - return; - - _updating = true; - - DataModelPath? old = DataModelPath; - DataModelPath = entity != null ? new DataModelPath(entity) : null; - old?.Dispose(); - } - finally - { - _updating = false; - } - } - - private void ApplyDataModelPath(DataModelPath path) - { - try - { - if (_updating) - return; - if (path.Path == _cycleNode.Storage?.Path) - return; - - _updating = true; - - path.Save(); - _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_cycleNode, path?.Entity, "event")); - } - finally - { - _updating = false; - } - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml deleted file mode 100644 index a73713e3c..000000000 --- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml +++ /dev/null @@ -1,19 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml.cs deleted file mode 100644 index 62653fdb8..000000000 --- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.DataModel.Screens; - -public partial class DataModelEventNodeCustomView : ReactiveUserControl -{ - public DataModelEventNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomViewModel.cs deleted file mode 100644 index 3238ba287..000000000 --- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelEventNodeCustomViewModel.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System.Collections.ObjectModel; -using System.Reactive.Disposables; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.Core.Services; -using Artemis.Storage.Entities.Profile; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.DataModel.Screens; - -public class DataModelEventNodeCustomViewModel : CustomNodeViewModel -{ - private readonly DataModelEventNode _node; - private readonly INodeEditorService _nodeEditorService; - private DataModelPath? _dataModelPath; - private ObservableCollection? _modules; - private bool _updating; - - public DataModelEventNodeCustomViewModel(DataModelEventNode node, INodeScript script, ISettingsService settingsService, INodeEditorService nodeEditorService, INodeService nodeService) - : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - - ShowFullPaths = settingsService.GetSetting("ProfileEditor.ShowFullPaths", true); - ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false); - Modules = new ObservableCollection(); - - List nodePinTypes = nodeService.GetRegisteredTypes(); - nodePinTypes.AddRange(Constants.NumberTypes); - nodePinTypes.Add(typeof(IDataModelEvent)); - NodePinTypes = new ObservableCollection(nodePinTypes); - - this.WhenActivated(d => - { - // Set up extra modules - if (_node.Script?.Context is Profile scriptProfile && scriptProfile.Configuration.Module != null) - Modules = new ObservableCollection {scriptProfile.Configuration.Module}; - else if (_node.Script?.Context is ProfileConfiguration profileConfiguration && profileConfiguration.Module != null) - Modules = new ObservableCollection {profileConfiguration.Module}; - - // Subscribe to node changes - _node.WhenAnyValue(n => n.Storage).Subscribe(UpdateDataModelPath).DisposeWith(d); - this.WhenAnyValue(vm => vm.DataModelPath).WhereNotNull().Subscribe(ApplyDataModelPath).DisposeWith(d); - - Disposable.Create(() => - { - _dataModelPath?.Dispose(); - _dataModelPath = null; - }).DisposeWith(d); - }); - } - - public PluginSetting ShowFullPaths { get; } - public PluginSetting ShowDataModelValues { get; } - public ObservableCollection NodePinTypes { get; } - - public ObservableCollection? Modules - { - get => _modules; - set => this.RaiseAndSetIfChanged(ref _modules, value); - } - - public DataModelPath? DataModelPath - { - get => _dataModelPath; - set => this.RaiseAndSetIfChanged(ref _dataModelPath, value); - } - - private void UpdateDataModelPath(DataModelPathEntity? entity) - { - try - { - if (_updating) - return; - - _updating = true; - - DataModelPath? old = DataModelPath; - DataModelPath = entity != null ? new DataModelPath(entity) : null; - old?.Dispose(); - } - finally - { - _updating = false; - } - } - - private void ApplyDataModelPath(DataModelPath path) - { - try - { - if (_updating) - return; - if (path.Path == _node.Storage?.Path) - return; - - _updating = true; - - path.Save(); - _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, path?.Entity, "event")); - } - finally - { - _updating = false; - } - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml deleted file mode 100644 index cef80d0ae..000000000 --- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml +++ /dev/null @@ -1,17 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml.cs deleted file mode 100644 index c40e8768d..000000000 --- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.DataModel.Screens; - -public partial class DataModelNodeCustomView : ReactiveUserControl -{ - public DataModelNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomViewModel.cs deleted file mode 100644 index 91d502e98..000000000 --- a/src/Artemis.VisualScripting/Nodes/DataModel/Screens/DataModelNodeCustomViewModel.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System.Collections.ObjectModel; -using System.Reactive.Disposables; -using Artemis.Core; -using Artemis.Core.Modules; -using Artemis.Core.Services; -using Artemis.Storage.Entities.Profile; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.DataModel.Screens; - -public class DataModelNodeCustomViewModel : CustomNodeViewModel -{ - private readonly DataModelNode _node; - private readonly INodeEditorService _nodeEditorService; - private DataModelPath? _dataModelPath; - private ObservableCollection? _modules; - private bool _updating; - - public DataModelNodeCustomViewModel(DataModelNode node, INodeScript script, ISettingsService settingsService, INodeEditorService nodeEditorService, INodeService nodeService) : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - - ShowFullPaths = settingsService.GetSetting("ProfileEditor.ShowFullPaths", true); - ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues", false); - - List nodePinTypes = nodeService.GetRegisteredTypes(); - nodePinTypes.AddRange(Constants.NumberTypes); - NodePinTypes = new ObservableCollection(nodePinTypes); - - this.WhenActivated(d => - { - // Set up extra modules - if (_node.Script?.Context is Profile scriptProfile && scriptProfile.Configuration.Module != null) - Modules = new ObservableCollection {scriptProfile.Configuration.Module}; - else if (_node.Script?.Context is ProfileConfiguration profileConfiguration && profileConfiguration.Module != null) - Modules = new ObservableCollection {profileConfiguration.Module}; - - // Subscribe to node changes - _node.WhenAnyValue(n => n.Storage).Subscribe(UpdateDataModelPath).DisposeWith(d); - this.WhenAnyValue(vm => vm.DataModelPath).WhereNotNull().Subscribe(ApplyDataModelPath).DisposeWith(d); - - Disposable.Create(() => - { - _dataModelPath?.Dispose(); - _dataModelPath = null; - }).DisposeWith(d); - }); - } - - public PluginSetting ShowFullPaths { get; } - public PluginSetting ShowDataModelValues { get; } - public ObservableCollection NodePinTypes { get; } - - public ObservableCollection? Modules - { - get => _modules; - set => this.RaiseAndSetIfChanged(ref _modules, value); - } - - public DataModelPath? DataModelPath - { - get => _dataModelPath; - set => this.RaiseAndSetIfChanged(ref _dataModelPath, value); - } - - private void UpdateDataModelPath(DataModelPathEntity? entity) - { - try - { - if (_updating) - return; - - _updating = true; - - DataModelPath? old = DataModelPath; - DataModelPath = entity != null ? new DataModelPath(entity) : null; - old?.Dispose(); - } - finally - { - _updating = false; - } - } - - private void ApplyDataModelPath(DataModelPath path) - { - try - { - if (_updating) - return; - if (path.Path == _node.Storage?.Path) - return; - - _updating = true; - - path.Save(); - _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, path?.Entity, "path")); - } - finally - { - _updating = false; - } - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/External/Commands/UpdateLayerPropertyNodeSelectedLayerProperty.cs b/src/Artemis.VisualScripting/Nodes/External/Commands/UpdateLayerPropertyNodeSelectedLayerProperty.cs deleted file mode 100644 index ae6c62f28..000000000 --- a/src/Artemis.VisualScripting/Nodes/External/Commands/UpdateLayerPropertyNodeSelectedLayerProperty.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; - -namespace Artemis.VisualScripting.Nodes.External.Commands; - -public class UpdateLayerPropertyNodeSelectedLayerProperty : INodeEditorCommand -{ - private readonly NodeConnectionStore _connections; - private readonly LayerPropertyNode _node; - private readonly ILayerProperty? _oldValue; - private readonly ILayerProperty? _value; - - public UpdateLayerPropertyNodeSelectedLayerProperty(LayerPropertyNode node, ILayerProperty? value) - { - _node = node; - _connections = new NodeConnectionStore(_node); - - _value = value; - _oldValue = _node.LayerProperty; - } - - - /// - public string DisplayName => "Update node layer property"; - - /// - public void Execute() - { - // Store connections as they currently are - _connections.Store(); - - // Update the selected profile element - _node.ChangeLayerProperty(_value); - } - - /// - public void Undo() - { - // Restore the previous layer property - _node.ChangeLayerProperty(_oldValue); - - // Restore connections - _connections.Restore(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/External/Commands/UpdateLayerPropertyNodeSelectedProfileElement.cs b/src/Artemis.VisualScripting/Nodes/External/Commands/UpdateLayerPropertyNodeSelectedProfileElement.cs deleted file mode 100644 index fa7793b81..000000000 --- a/src/Artemis.VisualScripting/Nodes/External/Commands/UpdateLayerPropertyNodeSelectedProfileElement.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; - -namespace Artemis.VisualScripting.Nodes.External.Commands; - -public class UpdateLayerPropertyNodeSelectedProfileElement : INodeEditorCommand -{ - private readonly NodeConnectionStore _connections; - private readonly LayerPropertyNode _node; - private readonly ILayerProperty? _oldLayerProperty; - private readonly RenderProfileElement? _oldValue; - - private readonly RenderProfileElement? _value; - - public UpdateLayerPropertyNodeSelectedProfileElement(LayerPropertyNode node, RenderProfileElement? value) - { - _node = node; - _connections = new NodeConnectionStore(_node); - - _value = value; - _oldValue = node.ProfileElement; - _oldLayerProperty = node.LayerProperty; - } - - /// - public string DisplayName => "Update node profile element"; - - /// - public void Execute() - { - // Store connections as they currently are - _connections.Store(); - - // Update the selected profile element - _node.ChangeProfileElement(_value); - } - - /// - public void Undo() - { - // Can't undo it if that profile element is now gone :\ - if (_oldValue != null && _oldValue.Disposed) - return; - - // Restore the previous profile element - _node.ChangeProfileElement(_oldValue); - - // Restore the previous layer property - _node.ChangeLayerProperty(_oldLayerProperty); - - // Restore connections - _connections.Restore(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/External/LayerPropertyNode.cs b/src/Artemis.VisualScripting/Nodes/External/LayerPropertyNode.cs deleted file mode 100644 index 5a2199c05..000000000 --- a/src/Artemis.VisualScripting/Nodes/External/LayerPropertyNode.cs +++ /dev/null @@ -1,154 +0,0 @@ -using Artemis.Core; -using Artemis.VisualScripting.Nodes.External.Screens; - -namespace Artemis.VisualScripting.Nodes.External; - -// [Node("Layer/Folder Property", "Outputs the property of a selected layer or folder", "External")] -public class LayerPropertyNode : Node -{ - private readonly object _layerPropertyLock = new(); - private readonly List _pinBucket = new(); - - public LayerPropertyNode() : base("Layer/Folder Property", "Outputs the property of a selected layer or folder") - { - } - - public INodeScript? Script { get; private set; } - public RenderProfileElement? ProfileElement { get; private set; } - public ILayerProperty? LayerProperty { get; private set; } - - public override void Evaluate() - { - lock (_layerPropertyLock) - { - // In this case remove the pins so no further evaluations occur - if (LayerProperty == null) - { - CreatePins(); - return; - } - - List list = LayerProperty.BaseDataBinding.Properties.ToList(); - int index = 0; - foreach (IPin pin in Pins) - { - OutputPin outputPin = (OutputPin) pin; - IDataBindingProperty dataBindingProperty = list[index]; - index++; - - // TODO: Is this really non-nullable? - outputPin.Value = dataBindingProperty.GetValue(); - } - } - } - - public override void Initialize(INodeScript script) - { - Script = script; - - if (script.Context is Profile profile) - profile.ChildRemoved += ProfileOnChildRemoved; - - LoadLayerProperty(); - } - - public void LoadLayerProperty() - { - lock (_layerPropertyLock) - { - if (Script?.Context is not Profile profile || Storage == null) - return; - - RenderProfileElement? element = profile.GetAllRenderElements().FirstOrDefault(l => l.EntityId == Storage.ElementId); - - ProfileElement = element; - LayerProperty = element?.GetAllLayerProperties().FirstOrDefault(p => p.Path == Storage.PropertyPath); - CreatePins(); - } - } - - public void ChangeProfileElement(RenderProfileElement? profileElement) - { - lock (_layerPropertyLock) - { - ProfileElement = profileElement; - LayerProperty = profileElement?.GetAllLayerProperties().FirstOrDefault(); - - Storage = new LayerPropertyNodeEntity - { - ElementId = ProfileElement?.EntityId ?? Guid.Empty, - PropertyPath = null - }; - - CreatePins(); - } - } - - public void ChangeLayerProperty(ILayerProperty? layerProperty) - { - lock (_layerPropertyLock) - { - LayerProperty = layerProperty; - - Storage = new LayerPropertyNodeEntity - { - ElementId = ProfileElement?.EntityId ?? Guid.Empty, - PropertyPath = LayerProperty?.Path - }; - - CreatePins(); - } - } - - private void CreatePins() - { - while (Pins.Any()) - RemovePin((Pin) Pins.First()); - - if (LayerProperty == null) - return; - - foreach (IDataBindingProperty dataBindingRegistration in LayerProperty.BaseDataBinding.Properties) - CreateOrAddOutputPin(dataBindingRegistration.ValueType, dataBindingRegistration.DisplayName); - } - - /// - /// Creates or adds an input pin to the node using a bucket. - /// The bucket might grow a bit over time as the user edits the node but pins won't get lost, enabling undo/redo in the - /// editor. - /// - private new void CreateOrAddOutputPin(Type valueType, string displayName) - { - // Grab the first pin from the bucket that isn't on the node yet - OutputPin? pin = _pinBucket.FirstOrDefault(p => !Pins.Contains(p)); - - // If there is none, create a new one and add it to the bucket - if (pin == null) - { - pin = CreateOutputPin(valueType, displayName); - _pinBucket.Add(pin); - } - // If there was a pin in the bucket, update it's type and display name and reuse it - else - { - pin.ChangeType(valueType); - pin.Name = displayName; - AddPin(pin); - } - } - - private void ProfileOnChildRemoved(object? sender, EventArgs e) - { - if (Script?.Context is not Profile profile) - return; - - if (ProfileElement == null || !profile.GetAllRenderElements().Contains(ProfileElement)) - ChangeProfileElement(null); - } -} - -public class LayerPropertyNodeEntity -{ - public Guid ElementId { get; set; } - public string? PropertyPath { get; set; } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml deleted file mode 100644 index 4a323a590..000000000 --- a/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - Node not available - - - This node cannot be used outside profile scripts. - - - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml.cs deleted file mode 100644 index 4348da66e..000000000 --- a/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.External.Screens; - -public partial class LayerPropertyNodeCustomView : ReactiveUserControl -{ - public LayerPropertyNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomViewModel.cs deleted file mode 100644 index bca028ff6..000000000 --- a/src/Artemis.VisualScripting/Nodes/External/Screens/LayerPropertyNodeCustomViewModel.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System.Collections.ObjectModel; -using System.Reactive.Disposables; -using System.Reactive.Linq; -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.VisualScripting; -using Artemis.VisualScripting.Nodes.External.Commands; -using DynamicData; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.External.Screens; - -public class LayerPropertyNodeCustomViewModel : CustomNodeViewModel -{ - private readonly LayerPropertyNode _node; - private readonly INodeEditorService _nodeEditorService; - private bool _outsideProfileContext; - - public LayerPropertyNodeCustomViewModel(LayerPropertyNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - this.WhenActivated(d => - { - if (_node.Script?.Context is not Profile profile) - { - OutsideProfileContext = true; - return; - } - - OutsideProfileContext = false; - Observable.FromEventPattern(x => profile.DescendentAdded += x, x => profile.DescendentAdded -= x).Subscribe(_ => GetProfileElements()).DisposeWith(d); - Observable.FromEventPattern(x => profile.DescendentRemoved += x, x => profile.DescendentRemoved -= x).Subscribe(_ => GetProfileElements()).DisposeWith(d); - GetProfileElements(); - GetLayerProperties(); - }); - - NodeModified += (_, _) => this.RaisePropertyChanged(nameof(SelectedProfileElement)); - NodeModified += (_, _) => this.RaisePropertyChanged(nameof(SelectedLayerProperty)); - this.WhenAnyValue(vm => vm.SelectedProfileElement).Subscribe(_ => GetLayerProperties()); - } - - public ObservableCollection ProfileElements { get; } = new(); - public ObservableCollection LayerProperties { get; } = new(); - - public bool OutsideProfileContext - { - get => _outsideProfileContext; - set => this.RaiseAndSetIfChanged(ref _outsideProfileContext, value); - } - - public RenderProfileElement? SelectedProfileElement - { - get => _node.ProfileElement; - set - { - if (value != null && !Equals(_node.ProfileElement, value)) - _nodeEditorService.ExecuteCommand(Script, new UpdateLayerPropertyNodeSelectedProfileElement(_node, value)); - } - } - - public ILayerProperty? SelectedLayerProperty - { - get => _node.LayerProperty; - set - { - if (value != null && !Equals(_node.LayerProperty, value)) - _nodeEditorService.ExecuteCommand(Script, new UpdateLayerPropertyNodeSelectedLayerProperty(_node, value)); - } - } - - private void GetProfileElements() - { - ProfileElements.Clear(); - if (_node.Script?.Context is not Profile profile) - return; - - List elements = new(profile.GetAllRenderElements()); - - ProfileElements.AddRange(elements.OrderBy(e => e.Order)); - SelectedProfileElement = _node.ProfileElement; - } - - private void GetLayerProperties() - { - LayerProperties.Clear(); - if (_node.ProfileElement == null) - return; - - LayerProperties.AddRange(_node.ProfileElement.GetAllLayerProperties().Where(l => !l.IsHidden && l.DataBindingsSupported)); - SelectedLayerProperty = _node.LayerProperty; - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/HotkeyEnableDisableNode.cs b/src/Artemis.VisualScripting/Nodes/Input/HotkeyEnableDisableNode.cs deleted file mode 100644 index 12946deb8..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/HotkeyEnableDisableNode.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Artemis.Core; -using Artemis.Core.Services; -using Artemis.VisualScripting.Nodes.Input.Screens; - -namespace Artemis.VisualScripting.Nodes.Input; - -[Node("Hotkey enable/disable", "Outputs a boolean value enabled and disabled by a set of hotkeys", "Input", OutputType = typeof(bool))] -public class HotkeyEnableDisableNode : Node, IDisposable -{ - private readonly IInputService _inputService; - private Hotkey? _disableHotkey; - private Hotkey? _enableHotkey; - private bool _value; - private bool _retrievedInitialValue; - - public HotkeyEnableDisableNode(IInputService inputService) - { - _inputService = inputService; - _inputService.KeyboardKeyUp += InputServiceOnKeyboardKeyUp; - - InitialValue = CreateInputPin(); - Output = CreateOutputPin(); - StorageModified += OnStorageModified; - } - - public InputPin InitialValue { get; } - public OutputPin Output { get; } - - public override void Initialize(INodeScript script) - { - LoadHotkeys(); - } - - public override void Evaluate() - { - if (!_retrievedInitialValue) - { - _value = InitialValue.Value; - _retrievedInitialValue = true; - } - - Output.Value = _value; - } - - private void OnStorageModified(object? sender, EventArgs e) - { - LoadHotkeys(); - } - - private void LoadHotkeys() - { - if (Storage == null) - return; - - _enableHotkey = Storage.EnableHotkey != null ? new Hotkey(Storage.EnableHotkey) : null; - _disableHotkey = Storage.DisableHotkey != null ? new Hotkey(Storage.DisableHotkey) : null; - } - - private void InputServiceOnKeyboardKeyUp(object? sender, ArtemisKeyboardKeyEventArgs e) - { - if (Storage == null) - return; - - if (_disableHotkey != null && _disableHotkey.MatchesEventArgs(e)) - _value = false; - else if (_enableHotkey != null && _enableHotkey.MatchesEventArgs(e)) - _value = true; - } - - public void Dispose() - { - _inputService.KeyboardKeyUp -= InputServiceOnKeyboardKeyUp; - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/HotkeyEnableDisableNodeEntity.cs b/src/Artemis.VisualScripting/Nodes/Input/HotkeyEnableDisableNodeEntity.cs deleted file mode 100644 index 98f84b2b0..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/HotkeyEnableDisableNodeEntity.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Artemis.Core; -using Artemis.Storage.Entities.Profile; - -namespace Artemis.VisualScripting.Nodes.Input; - -public class HotkeyEnableDisableNodeEntity -{ - public HotkeyEnableDisableNodeEntity(Hotkey? enableHotkey, Hotkey? disableHotkey) - { - enableHotkey?.Save(); - EnableHotkey = enableHotkey?.Entity; - disableHotkey?.Save(); - DisableHotkey = disableHotkey?.Entity; - } - - public ProfileConfigurationHotkeyEntity? EnableHotkey { get; set; } - public ProfileConfigurationHotkeyEntity? DisableHotkey { get; set; } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/HotkeyPressNode.cs b/src/Artemis.VisualScripting/Nodes/Input/HotkeyPressNode.cs deleted file mode 100644 index 593eaf8bf..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/HotkeyPressNode.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Artemis.Core; -using Artemis.Core.Services; -using Artemis.VisualScripting.Nodes.Input.Screens; - -namespace Artemis.VisualScripting.Nodes.Input; - -[Node("Hotkey press", "Outputs a boolean value for as long as a hotkey is pressed", "Input", OutputType = typeof(bool))] -public class HotkeyPressNode : Node, IDisposable -{ - private readonly IInputService _inputService; - private Hotkey? _toggleHotkey; - private bool _value; - - public HotkeyPressNode(IInputService inputService) - { - _inputService = inputService; - _inputService.KeyboardKeyDown += InputServiceOnKeyboardKeyDown; - _inputService.KeyboardKeyUp += InputServiceOnKeyboardKeyUp; - - Output = CreateOutputPin(); - StorageModified += OnStorageModified; - } - - public OutputPin Output { get; } - - public override void Initialize(INodeScript script) - { - LoadHotkeys(); - } - - public override void Evaluate() - { - Output.Value = _value; - } - - private void OnStorageModified(object? sender, EventArgs e) - { - LoadHotkeys(); - } - - private void LoadHotkeys() - { - if (Storage == null) - return; - - _toggleHotkey = Storage.EnableHotkey != null ? new Hotkey(Storage.EnableHotkey) : null; - } - - private void InputServiceOnKeyboardKeyDown(object? sender, ArtemisKeyboardKeyEventArgs e) - { - if (Storage == null) - return; - if (_toggleHotkey != null && _toggleHotkey.MatchesEventArgs(e)) - _value = true; - } - - private void InputServiceOnKeyboardKeyUp(object? sender, ArtemisKeyboardKeyEventArgs e) - { - if (Storage == null) - return; - if (_toggleHotkey != null && _toggleHotkey.MatchesEventArgs(e)) - _value = false; - } - - public void Dispose() - { - _inputService.KeyboardKeyUp -= InputServiceOnKeyboardKeyUp; - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/HotkeyToggleNode.cs b/src/Artemis.VisualScripting/Nodes/Input/HotkeyToggleNode.cs deleted file mode 100644 index a31d5d253..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/HotkeyToggleNode.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Artemis.Core; -using Artemis.Core.Services; -using Artemis.VisualScripting.Nodes.Input.Screens; - -namespace Artemis.VisualScripting.Nodes.Input; - -[Node("Hotkey toggle", "Outputs a boolean value toggled by a hotkey", "Input", OutputType = typeof(bool))] -public class HotkeyToggleNode : Node, IDisposable -{ - private readonly IInputService _inputService; - private Hotkey? _toggleHotkey; - private bool _value; - private bool _retrievedInitialValue; - - public HotkeyToggleNode(IInputService inputService) - { - _inputService = inputService; - _inputService.KeyboardKeyUp += InputServiceOnKeyboardKeyUp; - - InitialValue = CreateInputPin(); - Output = CreateOutputPin(); - StorageModified += OnStorageModified; - } - - public InputPin InitialValue { get; } - public OutputPin Output { get; } - - public override void Initialize(INodeScript script) - { - LoadHotkeys(); - } - - public override void Evaluate() - { - if (!_retrievedInitialValue) - { - _value = InitialValue.Value; - _retrievedInitialValue = true; - } - - Output.Value = _value; - } - - private void OnStorageModified(object? sender, EventArgs e) - { - LoadHotkeys(); - } - - private void LoadHotkeys() - { - if (Storage == null) - return; - - _toggleHotkey = Storage.EnableHotkey != null ? new Hotkey(Storage.EnableHotkey) : null; - } - - private void InputServiceOnKeyboardKeyUp(object? sender, ArtemisKeyboardKeyEventArgs e) - { - if (Storage == null) - return; - if (_toggleHotkey != null && _toggleHotkey.MatchesEventArgs(e)) - _value = !_value; - } - - public void Dispose() - { - _inputService.KeyboardKeyUp -= InputServiceOnKeyboardKeyUp; - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/PressedKeyPositionNode.cs b/src/Artemis.VisualScripting/Nodes/Input/PressedKeyPositionNode.cs deleted file mode 100644 index e08b05fab..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/PressedKeyPositionNode.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Artemis.Core; -using Artemis.Core.Services; -using Artemis.VisualScripting.Nodes.Input.Screens; -using SkiaSharp; -using static Artemis.VisualScripting.Nodes.Input.PressedKeyPositionNodeEntity; - -namespace Artemis.VisualScripting.Nodes.Input; - -[Node("Pressed Key Position", "Outputs the position of a pressed key relative to a layer", "Input", OutputType = typeof(Numeric))] -public class PressedKeyPositionNode : Node, IDisposable -{ - private readonly IInputService _inputService; - private Layer? _layer; - private SKPoint _ledPosition; - private Profile? _profile; - - public PressedKeyPositionNode(IInputService inputService) - { - _inputService = inputService; - XPosition = CreateOutputPin("X"); - YPosition = CreateOutputPin("Y"); - - StorageModified += OnStorageModified; - _inputService.KeyboardKeyDown += InputServiceOnKeyboardKeyDown; - _inputService.KeyboardKeyUp += InputServiceOnKeyboardKeyUp; - } - - public OutputPin XPosition { get; } - public OutputPin YPosition { get; } - - public override void Initialize(INodeScript script) - { - Storage ??= new PressedKeyPositionNodeEntity(); - - _profile = script.Context as Profile; - _layer = _profile?.GetAllLayers().FirstOrDefault(l => l.EntityId == Storage.LayerId); - } - - public override void Evaluate() - { - XPosition.Value = _ledPosition.X; - YPosition.Value = _ledPosition.Y; - } - - private void InputServiceOnKeyboardKeyDown(object? sender, ArtemisKeyboardKeyEventArgs e) - { - if (Storage?.RespondTo is KeyPressType.Down or KeyPressType.UpDown) - SetLedPosition(e.Led); - } - - private void InputServiceOnKeyboardKeyUp(object? sender, ArtemisKeyboardKeyEventArgs e) - { - if (Storage?.RespondTo is KeyPressType.Up or KeyPressType.UpDown) - SetLedPosition(e.Led); - } - - private void SetLedPosition(ArtemisLed? led) - { - if (_layer != null && led != null) - _ledPosition = new SKPoint((led.AbsoluteRectangle.MidX - _layer.Bounds.Left) / _layer.Bounds.Width, (led.AbsoluteRectangle.MidY - _layer.Bounds.Top) / _layer.Bounds.Height); - } - - private void OnStorageModified(object? sender, EventArgs e) - { - _layer = _profile?.GetAllLayers().FirstOrDefault(l => l.EntityId == Storage?.LayerId); - } - - public void Dispose() - { - _inputService.KeyboardKeyDown -= InputServiceOnKeyboardKeyDown; - _inputService.KeyboardKeyUp -= InputServiceOnKeyboardKeyUp; - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/PressedKeyPositionNodeEntity.cs b/src/Artemis.VisualScripting/Nodes/Input/PressedKeyPositionNodeEntity.cs deleted file mode 100644 index 1c74a9899..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/PressedKeyPositionNodeEntity.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.ComponentModel; - -namespace Artemis.VisualScripting.Nodes.Input; - -public class PressedKeyPositionNodeEntity -{ - public PressedKeyPositionNodeEntity() - { - } - - public PressedKeyPositionNodeEntity(Guid layerId, KeyPressType respondTo) - { - LayerId = layerId; - RespondTo = respondTo; - } - - public Guid LayerId { get; set; } - public KeyPressType RespondTo { get; set; } - - public enum KeyPressType - { - [Description("Up")] - Up, - [Description("Down")] - Down, - [Description("Up/down")] - UpDown - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomView.axaml deleted file mode 100644 index 7285adced..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomView.axaml +++ /dev/null @@ -1,16 +0,0 @@ - - - Enable - - Disable - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomView.axaml.cs deleted file mode 100644 index 7bc6bf76d..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomView.axaml.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Artemis.UI.Shared; -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Input.Screens; - -public partial class HotkeyEnableDisableNodeCustomView : ReactiveUserControl -{ - public HotkeyEnableDisableNodeCustomView() - { - InitializeComponent(); - } - - - private void HotkeyBox_OnHotkeyChanged(HotkeyBox sender, EventArgs args) - { - ViewModel?.Save(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomViewModel.cs deleted file mode 100644 index abf8bcbb8..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyEnableDisableNodeCustomViewModel.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Reactive.Disposables; -using System.Reactive.Linq; -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Input.Screens; - -public class HotkeyEnableDisableNodeCustomViewModel : CustomNodeViewModel -{ - private readonly HotkeyEnableDisableNode _enableDisableNode; - private readonly INodeEditorService _nodeEditorService; - private Hotkey? _enableHotkey; - private Hotkey? _disableHotkey; - private bool _updating; - - /// - public HotkeyEnableDisableNodeCustomViewModel(HotkeyEnableDisableNode enableDisableNode, INodeScript script, INodeEditorService nodeEditorService) : base(enableDisableNode, script) - { - _enableDisableNode = enableDisableNode; - _nodeEditorService = nodeEditorService; - - this.WhenActivated(d => - { - Observable.FromEventPattern(x => _enableDisableNode.StorageModified += x, x => _enableDisableNode.StorageModified -= x).Subscribe(_ => Update()).DisposeWith(d); - Update(); - }); - - } - - private void Update() - { - _updating = true; - - EnableHotkey = _enableDisableNode.Storage?.EnableHotkey != null ? new Hotkey(_enableDisableNode.Storage.EnableHotkey) : null; - DisableHotkey = _enableDisableNode.Storage?.DisableHotkey != null ? new Hotkey(_enableDisableNode.Storage.DisableHotkey) : null; - - _updating = false; - } - - public Hotkey? EnableHotkey - { - get => _enableHotkey; - set => this.RaiseAndSetIfChanged(ref _enableHotkey, value); - } - - public Hotkey? DisableHotkey - { - get => _disableHotkey; - set => this.RaiseAndSetIfChanged(ref _disableHotkey, value); - } - - public void Save() - { - if (_updating) - return; - - _nodeEditorService.ExecuteCommand( - Script, - new UpdateStorage(_enableDisableNode, new HotkeyEnableDisableNodeEntity(EnableHotkey, DisableHotkey), "hotkey") - ); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml deleted file mode 100644 index 19097f664..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml +++ /dev/null @@ -1,11 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml.cs deleted file mode 100644 index 1ac0f3569..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomView.axaml.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Artemis.UI.Shared; -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Input.Screens; - -public partial class HotkeyPressNodeCustomView : ReactiveUserControl -{ - public HotkeyPressNodeCustomView() - { - InitializeComponent(); - } - - - private void HotkeyBox_OnHotkeyChanged(HotkeyBox sender, EventArgs args) - { - ViewModel?.Save(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomViewModel.cs deleted file mode 100644 index a161de70b..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyPressNodeCustomViewModel.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Reactive.Disposables; -using System.Reactive.Linq; -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Input.Screens; - -public class HotkeyPressNodeCustomViewModel : CustomNodeViewModel -{ - private readonly HotkeyPressNode _pressNode; - private readonly INodeEditorService _nodeEditorService; - private Hotkey? _toggleHotkey; - private bool _updating; - - /// - public HotkeyPressNodeCustomViewModel(HotkeyPressNode pressNode, INodeScript script, INodeEditorService nodeEditorService) : base(pressNode, script) - { - _pressNode = pressNode; - _nodeEditorService = nodeEditorService; - - this.WhenActivated(d => - { - Observable.FromEventPattern(x => _pressNode.StorageModified += x, x => _pressNode.StorageModified -= x).Subscribe(_ => Update()).DisposeWith(d); - Update(); - }); - - } - - private void Update() - { - _updating = true; - ToggleHotkey = _pressNode.Storage?.EnableHotkey != null ? new Hotkey(_pressNode.Storage.EnableHotkey) : null; - _updating = false; - } - - public Hotkey? ToggleHotkey - { - get => _toggleHotkey; - set => this.RaiseAndSetIfChanged(ref _toggleHotkey, value); - } - - public void Save() - { - if (_updating) - return; - - _nodeEditorService.ExecuteCommand( - Script, - new UpdateStorage(_pressNode, new HotkeyEnableDisableNodeEntity(ToggleHotkey, null), "hotkey") - ); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyToggleNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyToggleNodeCustomView.axaml deleted file mode 100644 index b147737f3..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyToggleNodeCustomView.axaml +++ /dev/null @@ -1,11 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyToggleNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyToggleNodeCustomView.axaml.cs deleted file mode 100644 index 53a4a7adc..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyToggleNodeCustomView.axaml.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Artemis.UI.Shared; -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Input.Screens; - -public partial class HotkeyToggleNodeCustomView : ReactiveUserControl -{ - public HotkeyToggleNodeCustomView() - { - InitializeComponent(); - } - - - private void HotkeyBox_OnHotkeyChanged(HotkeyBox sender, EventArgs args) - { - ViewModel?.Save(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyToggleNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyToggleNodeCustomViewModel.cs deleted file mode 100644 index c7dc683ea..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/HotkeyToggleNodeCustomViewModel.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Reactive.Disposables; -using System.Reactive.Linq; -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Input.Screens; - -public class HotkeyToggleNodeCustomViewModel : CustomNodeViewModel -{ - private readonly HotkeyToggleNode _toggleNode; - private readonly INodeEditorService _nodeEditorService; - private Hotkey? _toggleHotkey; - private bool _updating; - - /// - public HotkeyToggleNodeCustomViewModel(HotkeyToggleNode toggleNode, INodeScript script, INodeEditorService nodeEditorService) : base(toggleNode, script) - { - _toggleNode = toggleNode; - _nodeEditorService = nodeEditorService; - - this.WhenActivated(d => - { - Observable.FromEventPattern(x => _toggleNode.StorageModified += x, x => _toggleNode.StorageModified -= x).Subscribe(_ => Update()).DisposeWith(d); - Update(); - }); - - } - - private void Update() - { - _updating = true; - ToggleHotkey = _toggleNode.Storage?.EnableHotkey != null ? new Hotkey(_toggleNode.Storage.EnableHotkey) : null; - _updating = false; - } - - public Hotkey? ToggleHotkey - { - get => _toggleHotkey; - set => this.RaiseAndSetIfChanged(ref _toggleHotkey, value); - } - - public void Save() - { - if (_updating) - return; - - _nodeEditorService.ExecuteCommand( - Script, - new UpdateStorage(_toggleNode, new HotkeyEnableDisableNodeEntity(ToggleHotkey, null), "hotkey") - ); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomView.axaml deleted file mode 100644 index bcb70f3f2..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomView.axaml +++ /dev/null @@ -1,29 +0,0 @@ - - - Layer - - - - - - - - - - - - Respond to - - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomView.axaml.cs deleted file mode 100644 index 0b24f4d51..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Input.Screens; - -public partial class PressedKeyPositionNodeCustomView : ReactiveUserControl -{ - public PressedKeyPositionNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomViewModel.cs deleted file mode 100644 index 2cc2660e1..000000000 --- a/src/Artemis.VisualScripting/Nodes/Input/Screens/PressedKeyPositionNodeCustomViewModel.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System.Collections.ObjectModel; -using System.Reactive.Disposables; -using System.Reactive.Linq; -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; -using static Artemis.VisualScripting.Nodes.Input.PressedKeyPositionNodeEntity; - -namespace Artemis.VisualScripting.Nodes.Input.Screens; - -public class PressedKeyPositionNodeCustomViewModel : CustomNodeViewModel -{ - private readonly INodeEditorService _nodeEditorService; - private readonly Profile? _profile; - private readonly PressedKeyPositionNode _node; - private Layer? _selectedLayer; - private KeyPressType _respondTo; - - public PressedKeyPositionNodeCustomViewModel(PressedKeyPositionNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script) - { - _nodeEditorService = nodeEditorService; - _profile = script.Context as Profile; - _node = node; - - Layers = new ObservableCollection(); - - this.WhenActivated(d => - { - if (_profile == null) - return; - - Observable.FromEventPattern(x => _profile.DescendentAdded += x, x => _profile.DescendentAdded -= x).Subscribe(_ => GetLayers()).DisposeWith(d); - Observable.FromEventPattern(x => _profile.DescendentRemoved += x, x => _profile.DescendentRemoved -= x).Subscribe(_ => GetLayers()).DisposeWith(d); - Observable.FromEventPattern(x => _node.StorageModified += x, x => _node.StorageModified -= x).Subscribe(_ => Update()).DisposeWith(d); - - GetLayers(); - }); - - this.WhenAnyValue(vm => vm.SelectedLayer).Subscribe(UpdateSelectedLayer); - this.WhenAnyValue(vm => vm.RespondTo).Subscribe(UpdateSelectedRespondTo); - } - - public ObservableCollection Layers { get; } - - public Layer? SelectedLayer - { - get => _selectedLayer; - set => this.RaiseAndSetIfChanged(ref _selectedLayer, value); - } - - public KeyPressType RespondTo - { - get => _respondTo; - set => this.RaiseAndSetIfChanged(ref _respondTo, value); - } - - private void GetLayers() - { - Layers.Clear(); - if (_profile == null) - return; - foreach (Layer layer in _profile.GetAllLayers()) - Layers.Add(layer); - - Update(); - } - - private void Update() - { - SelectedLayer = Layers.FirstOrDefault(l => l.EntityId == _node.Storage?.LayerId); - RespondTo = _node.Storage?.RespondTo ?? KeyPressType.Up; - } - - private void UpdateSelectedLayer(Layer? layer) - { - if (layer == null || _node.Storage?.LayerId == layer.EntityId) - return; - - _nodeEditorService.ExecuteCommand( - Script, - new UpdateStorage(_node, new PressedKeyPositionNodeEntity(layer.EntityId, _node.Storage?.RespondTo ?? KeyPressType.Up), "layer") - ); - } - - private void UpdateSelectedRespondTo(KeyPressType respondTo) - { - if (_node.Storage?.RespondTo == respondTo) - return; - - _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, new PressedKeyPositionNodeEntity(_node.Storage?.LayerId ?? Guid.Empty, respondTo), "layer")); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/List/ListOperatorEntity.cs b/src/Artemis.VisualScripting/Nodes/List/ListOperatorEntity.cs deleted file mode 100644 index 515f8be2e..000000000 --- a/src/Artemis.VisualScripting/Nodes/List/ListOperatorEntity.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Artemis.Storage.Entities.Profile.Nodes; - -namespace Artemis.VisualScripting.Nodes.List; - -public class ListOperatorEntity -{ - public NodeScriptEntity? Script { get; set; } - public ListOperator Operator { get; set; } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/List/ListOperatorNode.cs b/src/Artemis.VisualScripting/Nodes/List/ListOperatorNode.cs deleted file mode 100644 index 5a2cadd5b..000000000 --- a/src/Artemis.VisualScripting/Nodes/List/ListOperatorNode.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Collections; -using Artemis.Core; -using Artemis.VisualScripting.Nodes.List.Screens; - -namespace Artemis.VisualScripting.Nodes.List; - -[Node("List Operator (Simple)", "Checks if any/all/no values in the input list match the input value", "List", InputType = typeof(IEnumerable), OutputType = typeof(bool))] -public class ListOperatorNode : Node -{ - public ListOperatorNode() - { - InputList = CreateInputPin(); - InputValue = CreateInputPin(); - - Output = CreateOutputPin(); - } - - public InputPin InputList { get; } - public InputPin InputValue { get; } - public OutputPin Output { get; } - - /// - public override void Evaluate() - { - if (InputList.Value == null) - { - Output.Value = Storage == ListOperator.None; - return; - } - - object? input = InputValue.Value; - if (Storage == ListOperator.Any) - Output.Value = InputList.Value.Cast().Any(v => v.Equals(input)); - else if (Storage == ListOperator.All) - Output.Value = InputList.Value.Cast().All(v => v.Equals(input)); - else if (Storage == ListOperator.None) - Output.Value = InputList.Value.Cast().All(v => !v.Equals(input)); - } -} - -public enum ListOperator -{ - Any, - All, - None -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/List/ListOperatorPredicateNode.cs b/src/Artemis.VisualScripting/Nodes/List/ListOperatorPredicateNode.cs deleted file mode 100644 index 3631e5934..000000000 --- a/src/Artemis.VisualScripting/Nodes/List/ListOperatorPredicateNode.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System.Collections; -using Artemis.Core; -using Artemis.Core.Events; -using Artemis.VisualScripting.Nodes.List.Screens; - -namespace Artemis.VisualScripting.Nodes.List; - -[Node("List Operator (Advanced)", "Checks if any/all/no values in the input list match a condition", "List", InputType = typeof(IEnumerable), OutputType = typeof(bool))] -public class ListOperatorPredicateNode : Node, IDisposable -{ - private readonly object _scriptLock = new(); - private readonly ListOperatorPredicateStartNode _startNode; - - public ListOperatorPredicateNode() - { - _startNode = new ListOperatorPredicateStartNode {X = -200}; - - InputList = CreateInputPin(); - Output = CreateOutputPin(); - - InputList.PinConnected += InputListOnPinConnected; - } - - public InputPin InputList { get; } - public OutputPin Output { get; } - public NodeScript? Script { get; private set; } - - public override void Initialize(INodeScript script) - { - Storage ??= new ListOperatorEntity(); - - lock (_scriptLock) - { - Script = Storage?.Script != null - ? new NodeScript("Is match", "Determines whether the current list item is a match", Storage.Script, script.Context, new List {_startNode}) - : new NodeScript("Is match", "Determines whether the current list item is a match", script.Context, new List {_startNode}); - } - } - - /// - public override void Evaluate() - { - if (Storage == null) - return; - - if (InputList.Value == null) - { - Output.Value = Storage.Operator == ListOperator.None; - return; - } - - lock (_scriptLock) - { - if (Script == null) - return; - - if (Storage.Operator == ListOperator.Any) - Output.Value = InputList.Value.Cast().Any(EvaluateItem); - else if (Storage.Operator == ListOperator.All) - Output.Value = InputList.Value.Cast().All(EvaluateItem); - else if (Storage.Operator == ListOperator.None) - Output.Value = InputList.Value.Cast().All(v => !EvaluateItem(v)); - } - } - - private bool EvaluateItem(object item) - { - if (Script == null) - return false; - - _startNode.Item = item; - Script.Run(); - return Script.Result; - } - - private void UpdateStartNode() - { - Type? type = InputList.ConnectedTo.FirstOrDefault()?.Type; - // List must be generic or there's no way to tell what objects it contains in advance, that's not supported for now - if (type is not {IsGenericType: true}) - return; - - Type listType = type.GetGenericArguments().Single(); - _startNode?.ChangeType(listType); - } - - private void InputListOnPinConnected(object? sender, SingleValueEventArgs e) - { - lock (_scriptLock) - { - UpdateStartNode(); - Script?.LoadConnections(); - } - } - - #region IDisposable - - /// - public void Dispose() - { - Script?.Dispose(); - Script = null; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/List/ListOperatorPredicateStartNode.cs b/src/Artemis.VisualScripting/Nodes/List/ListOperatorPredicateStartNode.cs deleted file mode 100644 index ca37fb237..000000000 --- a/src/Artemis.VisualScripting/Nodes/List/ListOperatorPredicateStartNode.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.List; - -public class ListOperatorPredicateStartNode : DefaultNode -{ - internal static readonly Guid NodeId = new("9A714CF3-8D02-4CC3-A1AC-73833F82D7C6"); - private readonly ObjectOutputPins _objectOutputPins; - - public ListOperatorPredicateStartNode() : base(NodeId, "List item", "Contains the current list item") - { - _objectOutputPins = new ObjectOutputPins(this); - } - - public object? Item { get; set; } - - public override void Evaluate() - { - if (Item != null) - _objectOutputPins.SetCurrentValue(Item); - } - - public void ChangeType(Type? type) - { - _objectOutputPins.ChangeType(type); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorNodeCustomView.axaml deleted file mode 100644 index faa4e5543..000000000 --- a/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorNodeCustomView.axaml +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorNodeCustomView.axaml.cs deleted file mode 100644 index e83b57bb7..000000000 --- a/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.List.Screens; - -public partial class ListOperatorNodeCustomView : ReactiveUserControl -{ - public ListOperatorNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorNodeCustomViewModel.cs deleted file mode 100644 index 134e6e1f1..000000000 --- a/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorNodeCustomViewModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.List.Screens; - -public class ListOperatorNodeCustomViewModel : CustomNodeViewModel -{ - private readonly ListOperatorNode _node; - private readonly INodeEditorService _nodeEditorService; - - public ListOperatorNodeCustomViewModel(ListOperatorNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - - NodeModified += (_, _) => this.RaisePropertyChanged(nameof(CurrentValue)); - } - - public ListOperator CurrentValue - { - get => _node.Storage; - set => _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, value)); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorPredicateNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorPredicateNodeCustomView.axaml deleted file mode 100644 index dbc6728a7..000000000 --- a/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorPredicateNodeCustomView.axaml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - diff --git a/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorPredicateNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorPredicateNodeCustomView.axaml.cs deleted file mode 100644 index 1e34cf875..000000000 --- a/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorPredicateNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.List.Screens; - -public partial class ListOperatorPredicateNodeCustomView : ReactiveUserControl -{ - public ListOperatorPredicateNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorPredicateNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorPredicateNodeCustomViewModel.cs deleted file mode 100644 index b1a922752..000000000 --- a/src/Artemis.VisualScripting/Nodes/List/Screens/ListOperatorPredicateNodeCustomViewModel.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Reactive; -using System.Reactive.Disposables; -using Artemis.Core; -using Artemis.Core.Events; -using Artemis.UI.Shared.Services; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.List.Screens; - -public class ListOperatorPredicateNodeCustomViewModel : CustomNodeViewModel -{ - private readonly ListOperatorPredicateNode _node; - private readonly IWindowService _windowService; - private ListOperator _operator; - private bool _canOpenEditor; - - public ListOperatorPredicateNodeCustomViewModel(ListOperatorPredicateNode node, INodeScript script, IWindowService windowService) : base(node, script) - { - _node = node; - _windowService = windowService; - - OpenEditor = ReactiveCommand.CreateFromTask(ExecuteOpenEditor, this.WhenAnyValue(vm => vm.CanOpenEditor)); - CanOpenEditor = node.InputList.ConnectedTo.Any(); - - this.WhenActivated(d => - { - node.InputList.PinConnected += InputListOnPinConnected; - node.InputList.PinDisconnected += InputListOnPinDisconnected; - - Disposable.Create(() => - { - node.InputList.PinConnected -= InputListOnPinConnected; - node.InputList.PinDisconnected -= InputListOnPinDisconnected; - }).DisposeWith(d); - }); - } - - public ReactiveCommand OpenEditor { get; } - - private bool CanOpenEditor - { - get => _canOpenEditor; - set => this.RaiseAndSetIfChanged(ref _canOpenEditor, value); - } - - public ListOperator Operator - { - get => _operator; - set => this.RaiseAndSetIfChanged(ref _operator, value); - } - - private async Task ExecuteOpenEditor() - { - if (_node.Script == null) - return; - - await _windowService.ShowDialogAsync(_node.Script); - _node.Script.Save(); - - _node.Storage ??= new ListOperatorEntity(); - _node.Storage.Script = _node.Script.Entity; - } - - private void InputListOnPinDisconnected(object? sender, SingleValueEventArgs e) - { - CanOpenEditor = false; - } - - private void InputListOnPinConnected(object? sender, SingleValueEventArgs e) - { - CanOpenEditor = true; - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/Clamp.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/Clamp.cs deleted file mode 100644 index 4cd839ecb..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/Clamp.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Artemis.Core; -using RGB.NET.Core; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Clamp", "Clamps the value to be in between min and max", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class ClampNode : Node -{ - #region Properties & Fields - - public InputPin Value { get; } - public InputPin Min { get; } - public InputPin Max { get; } - - public OutputPin Result { get; } - - #endregion - - #region Constructors - - public ClampNode() - { - Value = CreateInputPin("Value"); - Min = CreateInputPin("Min"); - Max = CreateInputPin("Max"); - - Result = CreateOutputPin(); - } - - #endregion - - #region Methods - - /// - public override void Evaluate() => Result.Value = ((float)Value.Value).Clamp(Min.Value, Max.Value); - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/CounterNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/CounterNode.cs deleted file mode 100644 index b8e08d641..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/CounterNode.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Counter", "Counts from 0.0 to 1.0 at a configurable rate.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class CounterNode : Node -{ - private DateTime _lastEvaluate = DateTime.MinValue; - private float _progress; - - public CounterNode() - { - Time = CreateInputPin("Time (ms)"); - Output = CreateOutputPin(); - } - - public InputPin Time { get; set; } - public OutputPin Output { get; set; } - - public override void Evaluate() - { - DateTime now = DateTime.Now; - TimeSpan delta = now - _lastEvaluate; - - if (Time.Value != 0) - _progress = (float) (_progress + delta.TotalMilliseconds / Time.Value) % 1.0f; - - Output.Value = new Numeric(MathF.Round(_progress, 4, MidpointRounding.AwayFromZero)); - _lastEvaluate = now; - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/LerpNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/LerpNode.cs deleted file mode 100644 index 5ae96af1c..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/LerpNode.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Artemis.Core; -using RGB.NET.Core; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Lerp", "Interpolates linear between the two values A and B", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class LerpNode : Node -{ - #region Properties & Fields - - public InputPin A { get; } - public InputPin B { get; } - public InputPin T { get; } - - public OutputPin Result { get; } - - #endregion - - #region Constructors - - public LerpNode() - { - A = CreateInputPin("A"); - B = CreateInputPin("B"); - T = CreateInputPin("T"); - - Result = CreateOutputPin(); - } - - #endregion - - #region Methods - - /// - public override void Evaluate() - { - float a = A.Value; - float b = B.Value; - float t = ((float)T.Value).Clamp(0f, 1f); - Result.Value = ((b - a) * t) + a; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/MathExpressionNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/MathExpressionNode.cs deleted file mode 100644 index f274c8e03..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/MathExpressionNode.cs +++ /dev/null @@ -1,119 +0,0 @@ -using Artemis.Core; -using Artemis.VisualScripting.Nodes.Mathematics.Screens; -using NoStringEvaluating.Contract; -using NoStringEvaluating.Models.FormulaChecker; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Math Expression", "Outputs the result of a math expression.", "Mathematics", "https://wiki.artemis-rgb.com/en/guides/user/profiles/nodes/mathematics/math-expression?mtm_campaign=artemis&mtm_kwd=node-help", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class MathExpressionNode : Node -{ - private readonly IFormulaChecker _checker; - private readonly INoStringEvaluator _evaluator; - private readonly PinsVariablesContainer _variables; - - #region Constructors - - public MathExpressionNode(INoStringEvaluator evaluator, IFormulaChecker checker) - { - _evaluator = evaluator; - _checker = checker; - Output = CreateOutputPin(); - Values = CreateInputPinCollection("Values", 2); - Values.PinAdded += (_, _) => SetPinNames(); - Values.PinRemoved += (_, _) => SetPinNames(); - _variables = new PinsVariablesContainer(Values); - - SetPinNames(); - } - - #endregion - - public bool IsSyntaxValid(string? s) - { - if (s == null) - return true; - - if (!_checker.CheckSyntax(s).Ok) - return false; - - try - { - _evaluator.CalcNumber(s, _variables); - return true; - } - catch - { - return false; - } - } - - public string GetSyntaxErrors(string? s) - { - if (s == null) - return ""; - - CheckFormulaResult? syntaxCheck = _checker.CheckSyntax(s); - if (!syntaxCheck.Ok) - return string.Join(",", syntaxCheck.Mistakes); - - try - { - _evaluator.CalcNumber(s, _variables); - return ""; - } - catch (Exception e) - { - return e.Message; - } - } - - #region Properties & Fields - - public OutputPin Output { get; } - public InputPinCollection Values { get; } - - #endregion - - #region Methods - - public override void Evaluate() - { - try - { - if (Storage != null) - Output.Value = new Numeric(Math.Round(_evaluator.CalcNumber(Storage, _variables), 4, MidpointRounding.AwayFromZero)); - } - catch - { - Output.Value = new Numeric(0); - } - } - - private void SetPinNames() - { - int index = 1; - foreach (IPin value in Values) - { - value.Name = ExcelColumnFromNumber(index).ToLower(); - index++; - } - } - - public static string ExcelColumnFromNumber(int column) - { - string columnString = ""; - decimal columnNumber = column; - while (columnNumber > 0) - { - decimal currentLetterNumber = (columnNumber - 1) % 26; - char currentLetter = (char) (currentLetterNumber + 65); - columnString = currentLetter + columnString; - columnNumber = (columnNumber - (currentLetterNumber + 1)) / 26; - } - - return columnString; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/MaxNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/MaxNode.cs deleted file mode 100644 index 388774e81..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/MaxNode.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Max", "Outputs the largest of the connected numeric values.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class MaxNumericsNode : Node -{ - #region Constructors - - public MaxNumericsNode() - { - Values = CreateInputPinCollection("Values", 2); - Max = CreateOutputPin("Max"); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - Max.Value = Values.Values.Max(); - } - - #endregion - - #region Properties & Fields - - public InputPinCollection Values { get; } - - public OutputPin Max { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/MinNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/MinNode.cs deleted file mode 100644 index 84a5dee37..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/MinNode.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Min", "Outputs the smallest of the connected numeric values.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class MinNumericsNode : Node -{ - #region Constructors - - public MinNumericsNode() - { - Values = CreateInputPinCollection("Values", 2); - Min = CreateOutputPin("Min"); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - Min.Value = Values.Values.Min(); - } - - #endregion - - #region Properties & Fields - - public InputPinCollection Values { get; } - - public OutputPin Min { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/NormalizeNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/NormalizeNode.cs deleted file mode 100644 index 59a6f1f31..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/NormalizeNode.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Normalize", "Normalizes the number into range between 0-1", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class NormalizeNode : Node -{ - public InputPin Input { get; } - public InputPin Start { get; } - public InputPin End { get; } - - public OutputPin Result { get; } - - public NormalizeNode() - { - Input = CreateInputPin("Input"); - Start = CreateInputPin("Start"); - End = CreateInputPin("End"); - - Result = CreateOutputPin(); - } - - public override void Evaluate() - { - double inputValue = Input.Value; - double startValue = Start.Value; - double endValue = End.Value; - Result.Value = (Math.Clamp(inputValue, startValue, endValue) - startValue) / (endValue - startValue); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/NumericEasingNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/NumericEasingNode.cs deleted file mode 100644 index c2305adaa..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/NumericEasingNode.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Numeric Easing", "Interpolates a value from 0-1 to 0-1 with the given function", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class NumericEasingNode : Node -{ - public InputPin Input { get; } - - public InputPin EasingFunction { get; } - - public OutputPin Result { get; } - - public NumericEasingNode() - { - Input = CreateInputPin("Input"); - EasingFunction = CreateInputPin("Function"); - - Result = CreateOutputPin(); - } - - public override void Evaluate() - { - double inputValue = Input.Value; - double progress = Math.Clamp(inputValue, 0, 1); - - Result.Value = Easings.Interpolate(progress, EasingFunction.Value); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/PinsVariablesContainer.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/PinsVariablesContainer.cs deleted file mode 100644 index 6faf28044..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/PinsVariablesContainer.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Artemis.Core; -using NoStringEvaluating.Contract.Variables; -using NoStringEvaluating.Models.Values; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -public class PinsVariablesContainer : IVariablesContainer -{ - private readonly InputPinCollection _values; - - public PinsVariablesContainer(InputPinCollection values) - { - _values = values; - } - - #region Implementation of IVariablesContainer - - /// - public IVariable AddOrUpdate(string name, double value) - { - throw new NotImplementedException(); - } - - /// - public EvaluatorValue GetValue(string name) - { - IPin? pin = _values.FirstOrDefault(v => v.Name == name); - if (pin?.PinValue is Numeric numeric) - return new EvaluatorValue(numeric); - return new EvaluatorValue(0); - } - - /// - public bool TryGetValue(string name, out EvaluatorValue value) - { - IPin? pin = _values.FirstOrDefault(v => v.Name == name); - if (pin?.PinValue is Numeric numeric) - { - value = new EvaluatorValue(numeric); - return true; - } - - value = new EvaluatorValue(0); - return false; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/RangeNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/RangeNode.cs deleted file mode 100644 index 2f8dbef51..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/RangeNode.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Artemis.Core; -using RGB.NET.Core; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Range", "Selects the best integer value in the given range by the given percentage", "Static", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class RangeNode : Node -{ - #region Properties & Fields - - public InputPin Min { get; } - public InputPin Max { get; } - public InputPin Percentage { get; } - - public OutputPin Result { get; } - - #endregion - - #region Constructors - - public RangeNode() - { - Min = CreateInputPin("Min"); - Max = CreateInputPin("Max"); - Percentage = CreateInputPin("Percentage"); - - Result = CreateOutputPin(); - } - - #endregion - - #region Methods - - /// - public override void Evaluate() - { - int min = Min.Value; - int max = Max.Value; - float percentage = ((float)Percentage.Value).Clamp(0f, 1f); - - int range = max - min; - - Result.Value = percentage >= 1.0f ? max : ((int)(percentage * (range + 1)) + min); - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/RoundNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/RoundNode.cs deleted file mode 100644 index c445f5316..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/RoundNode.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Round", "Outputs a rounded numeric value.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class RoundNode : Node -{ - public RoundNode() - { - Input = CreateInputPin(); - Output = CreateOutputPin(); - } - - public OutputPin Output { get; set; } - public InputPin Input { get; set; } - - #region Overrides of Node - - /// - public override void Evaluate() - { - Output.Value = new Numeric(MathF.Round(Input.Value, MidpointRounding.AwayFromZero)); - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/Saturate.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/Saturate.cs deleted file mode 100644 index 3cd22c958..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/Saturate.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Artemis.Core; -using RGB.NET.Core; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Saturate", "Clamps the value to be in between 0 and 1", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class SaturateNode : Node -{ - #region Properties & Fields - - public InputPin Value { get; } - - public OutputPin Result { get; } - - #endregion - - #region Constructors - - public SaturateNode() - { - Value = CreateInputPin(); - - Result = CreateOutputPin(); - } - - #endregion - - #region Methods - - /// - public override void Evaluate() => Result.Value = ((float)Value.Value).Clamp(0f, 1f); - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomView.axaml deleted file mode 100644 index 0000a401a..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomView.axaml +++ /dev/null @@ -1,14 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomView.axaml.cs deleted file mode 100644 index c4250d95a..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomView.axaml.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Avalonia.Interactivity; -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Mathematics.Screens; - -public partial class MathExpressionNodeCustomView : ReactiveUserControl -{ - public MathExpressionNodeCustomView() - { - InitializeComponent(); - } - - - private void InputElement_OnLostFocus(object? sender, RoutedEventArgs e) - { - ViewModel?.UpdateInputValue(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomViewModel.cs deleted file mode 100644 index 4cd475a8d..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/Screens/MathExpressionNodeCustomViewModel.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System.Reactive.Disposables; -using System.Reactive.Linq; -using Artemis.Core; -using Artemis.Core.Events; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; -using ReactiveUI.Validation.Extensions; - -namespace Artemis.VisualScripting.Nodes.Mathematics.Screens; - -public class MathExpressionNodeCustomViewModel : CustomNodeViewModel -{ - private readonly MathExpressionNode _node; - private readonly INodeEditorService _nodeEditorService; - private string? _inputValue; - - public MathExpressionNodeCustomViewModel(MathExpressionNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - - this.ValidationRule(vm => vm.InputValue, value => _node.IsSyntaxValid(value), value => _node.GetSyntaxErrors(value)); - - this.WhenActivated(d => - { - Observable.FromEventPattern>(x => _node.Values.PinAdded += x, x => _node.Values.PinAdded -= x) - .Subscribe(_ => - { - string? old = InputValue; - InputValue = null; - InputValue = old; - }) - .DisposeWith(d); - Observable.FromEventPattern>(x => _node.Values.PinRemoved += x, x => _node.Values.PinRemoved -= x) - .Subscribe(_ => - { - string? old = InputValue; - InputValue = null; - InputValue = old; - }) - .DisposeWith(d); - }); - - NodeModified += (_, _) => InputValue = _node.Storage; - InputValue = _node.Storage; - } - - public string? InputValue - { - get => _inputValue; - set => this.RaiseAndSetIfChanged(ref _inputValue, value); - } - - public void UpdateInputValue() - { - // The value could be invalid but that's ok, we still want to save it - if (_node.Storage != InputValue) - _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, InputValue)); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/SubtractNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/SubtractNode.cs deleted file mode 100644 index baaf4147a..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/SubtractNode.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Subtract", "Subtracts the connected numeric values.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class SubtractNumericsNode : Node -{ - #region Constructors - - public SubtractNumericsNode() - { - Values = CreateInputPinCollection("Values", 2); - Remainder = CreateOutputPin("Remainder"); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - Remainder.Value = Values.Values.Subtract(); - } - - #endregion - - #region Properties & Fields - - public InputPinCollection Values { get; } - - public OutputPin Remainder { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Mathematics/SumNode.cs b/src/Artemis.VisualScripting/Nodes/Mathematics/SumNode.cs deleted file mode 100644 index 8fc6913c2..000000000 --- a/src/Artemis.VisualScripting/Nodes/Mathematics/SumNode.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Mathematics; - -[Node("Sum", "Sums the connected numeric values.", "Mathematics", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class SumNumericsNode : Node -{ - #region Constructors - - public SumNumericsNode() - { - Values = CreateInputPinCollection("Values", 2); - Sum = CreateOutputPin("Sum"); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - Sum.Value = Values.Values.Sum(); - } - - #endregion - - #region Properties & Fields - - public InputPinCollection Values { get; } - - public OutputPin Sum { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Operators/AndNode.cs b/src/Artemis.VisualScripting/Nodes/Operators/AndNode.cs deleted file mode 100644 index efbecdfc1..000000000 --- a/src/Artemis.VisualScripting/Nodes/Operators/AndNode.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Operators; - -[Node("And", "Checks if all inputs are true.", "Operators", InputType = typeof(bool), OutputType = typeof(bool))] -public class AndNode : Node -{ - #region Constructors - - public AndNode() - { - Input = CreateInputPinCollection(); - Result = CreateOutputPin(); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - Result.Value = Input.Values.All(v => v); - } - - #endregion - - #region Properties & Fields - - public InputPinCollection Input { get; set; } - public OutputPin Result { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Operators/EnumEqualsNode.cs b/src/Artemis.VisualScripting/Nodes/Operators/EnumEqualsNode.cs deleted file mode 100644 index e4e2bdf2f..000000000 --- a/src/Artemis.VisualScripting/Nodes/Operators/EnumEqualsNode.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Artemis.Core; -using Artemis.VisualScripting.Nodes.Operators.Screens; - -namespace Artemis.VisualScripting.Nodes.Operators; - -[Node("Enum Equals", "Determines the equality between an input and a selected enum value", "Operators", InputType = typeof(Enum), OutputType = typeof(bool))] -public class EnumEqualsNode : Node -{ - public EnumEqualsNode() - { - InputPin = CreateInputPin(); - OutputPin = CreateOutputPin(); - } - - public InputPin InputPin { get; } - public OutputPin OutputPin { get; } - - /// - public override void Evaluate() - { - if (InputPin.Value == null) - OutputPin.Value = false; - else - OutputPin.Value = Convert.ToInt64(InputPin.Value) == Storage; - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Operators/EqualsNode.cs b/src/Artemis.VisualScripting/Nodes/Operators/EqualsNode.cs deleted file mode 100644 index 7c022f1d7..000000000 --- a/src/Artemis.VisualScripting/Nodes/Operators/EqualsNode.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Operators; - -[Node("Equals", "Checks if the two inputs are equals.", "Operators", InputType = typeof(bool), OutputType = typeof(bool))] -public class EqualsNode : Node -{ - #region Constructors - - public EqualsNode() - { - Input1 = CreateInputPin(); - Input2 = CreateInputPin(); - Result = CreateOutputPin(); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - try - { - Result.Value = Equals(Input1.Value, Input2.Value); - } - catch - { - Result.Value = false; - } - } - - #endregion - - #region Properties & Fields - - public InputPin Input1 { get; } - public InputPin Input2 { get; } - - public OutputPin Result { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Operators/GreaterThanNode.cs b/src/Artemis.VisualScripting/Nodes/Operators/GreaterThanNode.cs deleted file mode 100644 index adae0971a..000000000 --- a/src/Artemis.VisualScripting/Nodes/Operators/GreaterThanNode.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Collections; -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Operators; - -[Node("Greater than", "Checks if the first input is greater than the second.", "Operators", InputType = typeof(object), OutputType = typeof(bool))] -public class GreaterThanNode : Node -{ - #region Constructors - - public GreaterThanNode() - { - Input1 = CreateInputPin(); - Input2 = CreateInputPin(); - Result = CreateOutputPin(); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - if (Input1.Value is Numeric numeric1 && Input2.Value is Numeric numeric2) - { - Result.Value = numeric1 > numeric2; - return; - } - - if (Input2.Value != null && Input1.Value != null && Input1.Value.IsNumber() && Input2.Value.IsNumber()) - { - Result.Value = Convert.ToSingle(Input1.Value) > Convert.ToSingle(Input2.Value); - return; - } - - try - { - Result.Value = Comparer.DefaultInvariant.Compare(Input1.Value, Input2.Value) == 1; - } - catch - { - Result.Value = false; - } - } - - #endregion - - #region Properties & Fields - - public InputPin Input1 { get; } - public InputPin Input2 { get; } - - public OutputPin Result { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Operators/LessThanNode.cs b/src/Artemis.VisualScripting/Nodes/Operators/LessThanNode.cs deleted file mode 100644 index 4eb100a7f..000000000 --- a/src/Artemis.VisualScripting/Nodes/Operators/LessThanNode.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Collections; -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Operators; - -[Node("Less than", "Checks if the first input is less than the second.", "Operators", InputType = typeof(object), OutputType = typeof(bool))] -public class LessThanNode : Node -{ - #region Constructors - - public LessThanNode() - { - Input1 = CreateInputPin(); - Input2 = CreateInputPin(); - Result = CreateOutputPin(); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - if (Input1.Value is Numeric numeric1 && Input2.Value is Numeric numeric2) - { - Result.Value = numeric1 < numeric2; - return; - } - - if (Input2.Value != null && Input1.Value != null && Input1.Value.IsNumber() && Input2.Value.IsNumber()) - { - Result.Value = Convert.ToSingle(Input1.Value) < Convert.ToSingle(Input2.Value); - return; - } - - try - { - Result.Value = Comparer.DefaultInvariant.Compare(Input1.Value, Input2.Value) == -1; - } - catch - { - Result.Value = false; - } - } - - #endregion - - #region Properties & Fields - - public InputPin Input1 { get; } - public InputPin Input2 { get; } - - public OutputPin Result { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Operators/NegateNode.cs b/src/Artemis.VisualScripting/Nodes/Operators/NegateNode.cs deleted file mode 100644 index a911c2e81..000000000 --- a/src/Artemis.VisualScripting/Nodes/Operators/NegateNode.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Operators; - -[Node("Negate", "Negates the boolean.", "Operators", InputType = typeof(bool), OutputType = typeof(bool))] -public class NegateNode : Node -{ - #region Constructors - - public NegateNode() - { - Input = CreateInputPin(); - Output = CreateOutputPin(); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - Output.Value = !Input.Value; - } - - #endregion - - #region Properties & Fields - - public InputPin Input { get; } - public OutputPin Output { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Operators/OrNode.cs b/src/Artemis.VisualScripting/Nodes/Operators/OrNode.cs deleted file mode 100644 index b78d24d3d..000000000 --- a/src/Artemis.VisualScripting/Nodes/Operators/OrNode.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Operators; - -[Node("Or", "Checks if any inputs are true.", "Operators", InputType = typeof(bool), OutputType = typeof(bool))] -public class OrNode : Node -{ - #region Constructors - - public OrNode() - { - Input = CreateInputPinCollection(); - Result = CreateOutputPin(); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - Result.Value = Input.Values.Any(v => v); - } - - #endregion - - #region Properties & Fields - - public InputPinCollection Input { get; set; } - public OutputPin Result { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml deleted file mode 100644 index 3d6357933..000000000 --- a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml.cs deleted file mode 100644 index 88795dc01..000000000 --- a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Operators.Screens; - -public partial class EnumEqualsNodeCustomView : ReactiveUserControl -{ - public EnumEqualsNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomViewModel.cs deleted file mode 100644 index cb571936d..000000000 --- a/src/Artemis.VisualScripting/Nodes/Operators/Screens/EnumEqualsNodeCustomViewModel.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System.Collections.ObjectModel; -using System.Reactive.Disposables; -using System.Reactive.Linq; -using Artemis.Core; -using Artemis.Core.Events; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using Avalonia.Threading; -using DynamicData; -using Humanizer; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Operators.Screens; - -public class EnumEqualsNodeCustomViewModel : CustomNodeViewModel -{ - private readonly EnumEqualsNode _node; - private readonly INodeEditorService _nodeEditorService; - - public EnumEqualsNodeCustomViewModel(EnumEqualsNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - - NodeModified += (_, _) => this.RaisePropertyChanged(nameof(CurrentValue)); - this.WhenActivated(d => - { - if (_node.InputPin.ConnectedTo.Any()) - { - EnumValues.Clear(); - if (_node.InputPin.ConnectedTo.First().Type.IsEnum) - AddEnumValues(_node.InputPin.ConnectedTo.First().Type); - } - - Observable.FromEventPattern>(x => _node.InputPin.PinConnected += x, x => _node.InputPin.PinConnected -= x) - .Subscribe(p => AddEnumValues(p.EventArgs.Value.Type)) - .DisposeWith(d); - Observable.FromEventPattern>(x => _node.InputPin.PinDisconnected += x, x => _node.InputPin.PinDisconnected -= x) - .Subscribe(_ => EnumValues.Clear()) - .DisposeWith(d); - }); - } - - public ObservableCollection EnumValues { get; } = new(); - - public EnumValueItem? CurrentValue - { - get => EnumValues.FirstOrDefault(v => v.Value == _node.Storage); - set - { - if (!Equals(_node.Storage, value.Value)) - _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, value.Value)); - } - } - - private void AddEnumValues(Type type) - { - Dispatcher.UIThread.Post(() => - { - List values = Enum.GetValues(type).Cast().Select(e => new EnumValueItem(value: Convert.ToInt64(e), name: e.Humanize())).ToList(); - if (values.Count > 20) - EnumValues.AddRange(values.OrderBy(v => v.Name)); - else - EnumValues.AddRange(values); - - this.RaisePropertyChanged(nameof(CurrentValue)); - }, DispatcherPriority.Background); - } -} - -/// -/// Represents a single enum value -/// -public class EnumValueItem -{ - /// - /// Creates a new instance of the class. - /// - public EnumValueItem(long value, string name) - { - Value = value; - Name = name; - } - - /// - /// The underlying value of the enum - /// - public long Value { get; set; } - - /// - /// The name of the enum value - /// - public string Name { get; set; } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Operators/XorNode.cs b/src/Artemis.VisualScripting/Nodes/Operators/XorNode.cs deleted file mode 100644 index 42197ed25..000000000 --- a/src/Artemis.VisualScripting/Nodes/Operators/XorNode.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Operators; - -[Node("Exclusive Or", "Checks if one of the inputs is true.", "Operators", InputType = typeof(bool), OutputType = typeof(bool))] -public class XorNode : Node -{ - #region Constructors - - public XorNode() - { - Input = CreateInputPinCollection(); - Result = CreateOutputPin(); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - Result.Value = Input.Values.Count(v => v) == 1; - } - - #endregion - - #region Properties & Fields - - public InputPinCollection Input { get; set; } - public OutputPin Result { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/DisplayValueNode.cs b/src/Artemis.VisualScripting/Nodes/Static/DisplayValueNode.cs deleted file mode 100644 index d4206cbec..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/DisplayValueNode.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Artemis.Core; -using Artemis.VisualScripting.Nodes.Static.Screens; - -namespace Artemis.VisualScripting.Nodes.Static; - -[Node("Display Value", "Displays an input value for testing purposes.", "Static", InputType = typeof(object))] -public class DisplayValueNode : Node -{ - public DisplayValueNode() - { - Input = CreateInputPin(); - } - - public InputPin Input { get; } - - public override void Evaluate() - { - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/RandomNumericValueNode.cs b/src/Artemis.VisualScripting/Nodes/Static/RandomNumericValueNode.cs deleted file mode 100644 index b00d2f419..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/RandomNumericValueNode.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Static; - -[Node("Random", "Generates a random value between 0 and 1", "Static", OutputType = typeof(Numeric))] -public class RandomNumericValueNode : Node -{ - #region Properties & Fields - - private static readonly Random RANDOM = new(); - - public OutputPin Output { get; } - - #endregion - - #region Constructors - - public RandomNumericValueNode() - { - Output = CreateOutputPin(); - } - - #endregion - - #region Methods - - /// - public override void Evaluate() => Output.Value = RANDOM.NextSingle(); - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml deleted file mode 100644 index 8831dd1e9..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml.cs deleted file mode 100644 index 769c49881..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Static.Screens; - -public partial class DisplayValueNodeCustomView : ReactiveUserControl -{ - public DisplayValueNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomViewModel.cs deleted file mode 100644 index 590a397fb..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/DisplayValueNodeCustomViewModel.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Reactive.Disposables; -using Artemis.Core; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Static.Screens; - -public class DisplayValueNodeCustomViewModel : CustomNodeViewModel -{ - private readonly DisplayValueNode _node; - private object? _currentValue; - - public DisplayValueNodeCustomViewModel(DisplayValueNode node, INodeScript script) : base(node, script) - { - _node = node; - - // Because the DisplayValueNode has no output it never evaluates, manually do so here - this.WhenActivated(d => - { - System.Timers.Timer updateTimer = new(TimeSpan.FromMilliseconds(25.0 / 1000)); - updateTimer.Elapsed += (_, _) => Update(); - updateTimer.Start(); - updateTimer.DisposeWith(d); - }); - } - - public object? CurrentValue - { - get => _currentValue; - private set => this.RaiseAndSetIfChanged(ref _currentValue, value); - } - - private void Update() - { - try - { - CurrentValue = _node.Input.Value; - } - catch (Exception ex) - { - // Don't crash the timer on exceptions and display the messages as a bit of a nice to have - CurrentValue = ex.Message; - } - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomView.axaml deleted file mode 100644 index 4207380d2..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomView.axaml +++ /dev/null @@ -1,13 +0,0 @@ - - - False - True - - diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomView.axaml.cs deleted file mode 100644 index c7a81e188..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Static.Screens; - -public partial class StaticBooleanValueNodeCustomView : ReactiveUserControl -{ - public StaticBooleanValueNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomViewModel.cs deleted file mode 100644 index 6dde68817..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticBooleanValueNodeCustomViewModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Static.Screens; - -public class StaticBooleanValueNodeCustomViewModel : CustomNodeViewModel -{ - private readonly StaticBooleanValueNode _node; - private readonly INodeEditorService _nodeEditorService; - - public StaticBooleanValueNodeCustomViewModel(StaticBooleanValueNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - - NodeModified += (_, _) => this.RaisePropertyChanged(nameof(CurrentValue)); - } - - public int? CurrentValue - { - get => _node.Storage ? 1 : 0; - set => _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, value == 1)); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticNumericValueNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticNumericValueNodeCustomView.axaml deleted file mode 100644 index e420ebbc4..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticNumericValueNodeCustomView.axaml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticNumericValueNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticNumericValueNodeCustomView.axaml.cs deleted file mode 100644 index 869514564..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticNumericValueNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Static.Screens; - -public partial class StaticNumericValueNodeCustomView : ReactiveUserControl -{ - public StaticNumericValueNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticNumericValueNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticNumericValueNodeCustomViewModel.cs deleted file mode 100644 index e9b0ee94c..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticNumericValueNodeCustomViewModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Static.Screens; - -public class StaticNumericValueNodeCustomViewModel : CustomNodeViewModel -{ - private readonly StaticNumericValueNode _node; - private readonly INodeEditorService _nodeEditorService; - - public StaticNumericValueNodeCustomViewModel(StaticNumericValueNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - - NodeModified += (_, _) => this.RaisePropertyChanged(nameof(CurrentValue)); - } - - public Numeric? CurrentValue - { - get => _node.Storage; - set => _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, value ?? new Numeric())); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomView.axaml deleted file mode 100644 index fb109aff3..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomView.axaml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomView.axaml.cs deleted file mode 100644 index 51f401ac5..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomView.axaml.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; -using FluentAvalonia.UI.Controls; - -namespace Artemis.VisualScripting.Nodes.Static.Screens; - -public partial class StaticSKColorValueNodeCustomView : ReactiveUserControl -{ - public StaticSKColorValueNodeCustomView() - { - InitializeComponent(); - } - - - private void ColorPickerButton_OnFlyoutOpened(ColorPickerButton sender, EventArgs args) - { - ViewModel?.PauseUpdating(); - } - - private void ColorPickerButton_OnFlyoutClosed(ColorPickerButton sender, EventArgs args) - { - ViewModel?.ResumeUpdating(); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomViewModel.cs deleted file mode 100644 index a968d14ac..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticSKColorValueNodeCustomViewModel.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Static.Screens; - -public class StaticSKColorValueNodeCustomViewModel : CustomNodeViewModel -{ - private readonly StaticSKColorValueNode _node; - private readonly INodeEditorService _nodeEditorService; - private bool _applyChanges; - private SKColor? _currentValue; - - public StaticSKColorValueNodeCustomViewModel(StaticSKColorValueNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - _applyChanges = true; - - NodeModified += (_, _) => CurrentValue = _node.Storage; - CurrentValue = _node.Storage; - } - - public SKColor? CurrentValue - { - get => _currentValue; - set - { - if (_applyChanges && value != _node.Storage) - _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, value ?? SKColor.Empty)); - this.RaiseAndSetIfChanged(ref _currentValue, value); - } - } - - public void PauseUpdating() - { - _applyChanges = false; - } - - public void ResumeUpdating() - { - _applyChanges = true; - - SKColor updatedValue = CurrentValue ?? SKColor.Empty; - if (updatedValue != _node.Storage) - _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, updatedValue)); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticStringValueNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticStringValueNodeCustomView.axaml deleted file mode 100644 index 03ce44340..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticStringValueNodeCustomView.axaml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticStringValueNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticStringValueNodeCustomView.axaml.cs deleted file mode 100644 index 95644633d..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticStringValueNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Static.Screens; - -public partial class StaticStringValueNodeCustomView : ReactiveUserControl -{ - public StaticStringValueNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticValueNodeViewModels.cs b/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticValueNodeViewModels.cs deleted file mode 100644 index e22c4f2e5..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/Screens/StaticValueNodeViewModels.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Static.Screens; - -public class StaticStringValueNodeCustomViewModel : CustomNodeViewModel -{ - private readonly StaticStringValueNode _node; - private readonly INodeEditorService _nodeEditorService; - - public StaticStringValueNodeCustomViewModel(StaticStringValueNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - - NodeModified += (_, _) => this.RaisePropertyChanged(nameof(CurrentValue)); - } - - public string? CurrentValue - { - get => _node.Storage; - set => _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, value)); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/StaticBooleanValueNode.cs b/src/Artemis.VisualScripting/Nodes/Static/StaticBooleanValueNode.cs deleted file mode 100644 index 9db639db9..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/StaticBooleanValueNode.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Artemis.Core; -using Artemis.VisualScripting.Nodes.Static.Screens; - -namespace Artemis.VisualScripting.Nodes.Static; - -[Node("Boolean-Value", "Outputs a configurable static boolean value.", "Static", OutputType = typeof(bool))] -public class StaticBooleanValueNode : Node -{ - #region Constructors - - public StaticBooleanValueNode() - { - Name = "Boolean"; - Output = CreateOutputPin(); - } - - #endregion - - #region Properties & Fields - - public OutputPin Output { get; } - - #endregion - - #region Methods - - public override void Evaluate() - { - Output.Value = Storage; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/StaticNumericValueNode.cs b/src/Artemis.VisualScripting/Nodes/Static/StaticNumericValueNode.cs deleted file mode 100644 index 8b11709cb..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/StaticNumericValueNode.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Artemis.Core; -using Artemis.VisualScripting.Nodes.Static.Screens; - -namespace Artemis.VisualScripting.Nodes.Static; - -[Node("Numeric-Value", "Outputs a configurable static numeric value.", "Static", OutputType = typeof(Numeric))] -public class StaticNumericValueNode : Node -{ - #region Constructors - - public StaticNumericValueNode() - { - Name = "Numeric"; - Output = CreateOutputPin(); - } - - #endregion - - #region Properties & Fields - - public OutputPin Output { get; } - - #endregion - - #region Methods - - public override void Evaluate() - { - Output.Value = Storage; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/StaticSKColorValueNode.cs b/src/Artemis.VisualScripting/Nodes/Static/StaticSKColorValueNode.cs deleted file mode 100644 index 84879d3a3..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/StaticSKColorValueNode.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Artemis.Core; -using Artemis.VisualScripting.Nodes.Static.Screens; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Static; - -[Node("Color-Value", "Outputs a configurable color value.", "Static", InputType = typeof(SKColor), OutputType = typeof(SKColor))] -public class StaticSKColorValueNode : Node -{ - #region Constructors - - public StaticSKColorValueNode() - { - Name = "Color"; - Output = CreateOutputPin(); - Storage = new SKColor(255, 0, 0); - } - - #endregion - - #region Properties & Fields - - public OutputPin Output { get; } - - #endregion - - #region Methods - - public override void Evaluate() - { - Output.Value = Storage; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Static/StaticStringValueNode.cs b/src/Artemis.VisualScripting/Nodes/Static/StaticStringValueNode.cs deleted file mode 100644 index 2c1c7079a..000000000 --- a/src/Artemis.VisualScripting/Nodes/Static/StaticStringValueNode.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Artemis.Core; -using Artemis.VisualScripting.Nodes.Static.Screens; - -namespace Artemis.VisualScripting.Nodes.Static; - -[Node("Text-Value", "Outputs a configurable static text value.", "Static", OutputType = typeof(string))] -public class StaticStringValueNode : Node -{ - #region Constructors - - public StaticStringValueNode() - { - Name = "Text"; - Output = CreateOutputPin(); - } - - #endregion - - #region Properties & Fields - - public OutputPin Output { get; } - - #endregion - - #region Methods - - public override void Evaluate() - { - Output.Value = Storage; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Text/StringContainsNode.cs b/src/Artemis.VisualScripting/Nodes/Text/StringContainsNode.cs deleted file mode 100644 index 547a85fbe..000000000 --- a/src/Artemis.VisualScripting/Nodes/Text/StringContainsNode.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Text; - -[Node("Contains", "Checks whether the first input is contained in the second input.", "Text", InputType = typeof(string), OutputType = typeof(bool))] -public class StringContainsNode : Node -{ - public StringContainsNode() - { - Input1 = CreateInputPin(); - Input2 = CreateInputPin(); - Result = CreateOutputPin(); - } - - public InputPin Input1 { get; } - public InputPin Input2 { get; } - - public OutputPin Result { get; } - - public override void Evaluate() - { - if (Input1.Value == null && Input2.Value == null) - Result.Value = false; - else if (Input1.Value == null && Input2.Value != null) - Result.Value = false; - else if (Input1.Value != null && Input2.Value == null) - Result.Value = true; - else if (Input1.Value != null && Input2.Value != null) - Result.Value = Input1.Value.Contains(Input2.Value, StringComparison.InvariantCultureIgnoreCase); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Text/StringFormatNode.cs b/src/Artemis.VisualScripting/Nodes/Text/StringFormatNode.cs deleted file mode 100644 index 4985555c1..000000000 --- a/src/Artemis.VisualScripting/Nodes/Text/StringFormatNode.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Text; - -[Node("Format", "Formats the input text.", "Text", InputType = typeof(object), OutputType = typeof(string))] -public class StringFormatNode : Node -{ - #region Constructors - - public StringFormatNode() - { - Format = CreateInputPin("Format"); - Values = CreateInputPinCollection("Values"); - Output = CreateOutputPin("Result"); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - // Convert numerics to floats beforehand to allow string.Format to format them - object[] values = Values.Values.Select(v => v is Numeric n ? (float) n : v).ToArray(); - Output.Value = string.Format(Format.Value ?? string.Empty, values); - } - - #endregion - - #region Properties & Fields - - public InputPin Format { get; } - public InputPinCollection Values { get; } - - public OutputPin Output { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Text/StringLengthNode.cs b/src/Artemis.VisualScripting/Nodes/Text/StringLengthNode.cs deleted file mode 100644 index 006f84c5f..000000000 --- a/src/Artemis.VisualScripting/Nodes/Text/StringLengthNode.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Text; - -[Node("Text Length", "Outputs the length of the input text.", - "Text", InputType = typeof(string), OutputType = typeof(Numeric))] -public class StringLengthNode : Node -{ - public StringLengthNode() - { - Input1 = CreateInputPin(); - Result = CreateOutputPin(); - } - - public InputPin Input1 { get; } - - public OutputPin Result { get; } - - public override void Evaluate() - { - Result.Value = Input1.Value == null ? new Numeric(0) : new Numeric(Input1.Value.Length); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Text/StringNullOrEmptyNode.cs b/src/Artemis.VisualScripting/Nodes/Text/StringNullOrEmptyNode.cs deleted file mode 100644 index 50e703c96..000000000 --- a/src/Artemis.VisualScripting/Nodes/Text/StringNullOrEmptyNode.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Text; - -[Node("Text is empty", "Outputs true if the input text is empty, false if it contains any text.", - "Text", InputType = typeof(string), OutputType = typeof(bool))] -public class StringNullOrEmptyNode : Node -{ - public StringNullOrEmptyNode() - { - Input1 = CreateInputPin(); - Output1 = CreateOutputPin(); - } - - public InputPin Input1 { get; } - - public OutputPin Output1 { get; } - - public override void Evaluate() - { - bool isNullOrWhiteSpace = string.IsNullOrWhiteSpace(Input1.Value); - Output1.Value = isNullOrWhiteSpace; - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Text/StringRegexMatchNode.cs b/src/Artemis.VisualScripting/Nodes/Text/StringRegexMatchNode.cs deleted file mode 100644 index b33a0aaa3..000000000 --- a/src/Artemis.VisualScripting/Nodes/Text/StringRegexMatchNode.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.Text.RegularExpressions; -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Text; - -[Node("Regex Match", "Checks provided regex pattern matches the input.", "Text", InputType = typeof(string), OutputType = typeof(bool))] -public class StringRegexMatchNode : Node -{ - private string? _lastPattern; - private Regex? _regex; - private Exception? _exception; - - public StringRegexMatchNode() - { - Pattern = CreateInputPin("Pattern"); - Input = CreateInputPin("Input"); - Result = CreateOutputPin(); - } - - public InputPin Pattern { get; } - public InputPin Input { get; } - public OutputPin Result { get; } - - public override void Evaluate() - { - if (Input.Value == null || Pattern.Value == null) - return; - - // If the regex was invalid output false and rethrow the exception - if (_lastPattern == Pattern.Value && _exception != null) - { - Result.Value = false; - throw _exception; - } - - // If there is no regex yet or the regex changed, recompile - if (_regex == null || _lastPattern != Pattern.Value) - { - try - { - _regex = new Regex(Pattern.Value, RegexOptions.Compiled); - _exception = null; - } - catch (Exception e) - { - // If there is an exception, save it to keep rethrowing until the regex is fixed - _exception = e; - throw; - } - finally - { - _lastPattern = Pattern.Value; - } - } - - Result.Value = _regex.IsMatch(Input.Value); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Timing/DelayNode.cs b/src/Artemis.VisualScripting/Nodes/Timing/DelayNode.cs deleted file mode 100644 index d1a1f59b7..000000000 --- a/src/Artemis.VisualScripting/Nodes/Timing/DelayNode.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System.Diagnostics; -using Artemis.Core; -using Artemis.Core.Events; -using RGB.NET.Core; - -namespace Artemis.VisualScripting.Nodes.Timing; - -[Node("Delay", "Delays the resolution of the input pin(s) for the given time after each update", "Timing", InputType = typeof(object), OutputType = typeof(object))] -public class DelayNode : Node -{ - #region Properties & Fields - - private long _lastUpdateTimestamp = 0; - - public InputPin Delay { get; } - public InputPinCollection Input { get; } - - public OutputPin IsUpdated { get; } - public OutputPin NextUpdateTime { get; } - - private Dictionary _pinPairs = new(); - - #endregion - - #region Constructors - - public DelayNode() - { - Delay = CreateInputPin("Delay"); - Input = CreateInputPinCollection(typeof(object), initialCount: 0); - - IsUpdated = CreateOutputPin("Updated"); - NextUpdateTime = CreateOutputPin("Next Update"); - - Input.PinAdded += OnInputPinAdded; - Input.PinRemoved += OnInputPinRemoved; - - Input.Add(Input.CreatePin()); - } - - #endregion - - #region Methods - - private void OnInputPinAdded(object? sender, SingleValueEventArgs args) - { - IPin inputPin = args.Value; - _pinPairs.Add(inputPin, CreateOutputPin(typeof(object))); - - inputPin.PinConnected += OnInputPinConnected; - inputPin.PinDisconnected += OnInputPinDisconnected; - - UpdatePinNames(); - } - - private void OnInputPinRemoved(object? sender, SingleValueEventArgs args) - { - IPin inputPin = args.Value; - RemovePin(_pinPairs[inputPin]); - _pinPairs.Remove(inputPin); - - inputPin.PinConnected -= OnInputPinConnected; - inputPin.PinDisconnected -= OnInputPinDisconnected; - - UpdatePinNames(); - } - - private void OnInputPinConnected(object? sender, SingleValueEventArgs args) - { - if (sender is not IPin inputPin || !_pinPairs.ContainsKey(inputPin)) return; - - OutputPin outputPin = _pinPairs[inputPin]; - outputPin.ChangeType(args.Value.Type); - } - - private void OnInputPinDisconnected(object? sender, SingleValueEventArgs args) - { - if (sender is not IPin inputPin || !_pinPairs.ContainsKey(inputPin)) return; - - OutputPin outputPin = _pinPairs[inputPin]; - outputPin.ChangeType(typeof(object)); - } - - private void UpdatePinNames() - { - int counter = 1; - foreach (IPin inputPin in Input.Pins) - { - string name = counter.ToString(); - inputPin.Name = name; - _pinPairs[inputPin].Name = name; - - counter++; - } - } - - /// - public override void Evaluate() - { - double nextUpdateIn = Delay.Value - TimerHelper.GetElapsedTime(_lastUpdateTimestamp); - NextUpdateTime.Value = nextUpdateIn; - - if (nextUpdateIn <= 0) - { - IsUpdated.Value = true; - foreach ((IPin input, OutputPin output) in _pinPairs) - output.Value = input.PinValue; - - _lastUpdateTimestamp = Stopwatch.GetTimestamp(); - } - else - IsUpdated.Value = false; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Timing/EdgeNode.cs b/src/Artemis.VisualScripting/Nodes/Timing/EdgeNode.cs deleted file mode 100644 index 10f341668..000000000 --- a/src/Artemis.VisualScripting/Nodes/Timing/EdgeNode.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Timing; - -[Node("Edge", "Outputs true on each edge when the input changes", "Timing", InputType = typeof(bool), OutputType = typeof(bool))] -public class EdgeNode : Node -{ - #region Properties & Fields - - private bool _lastInput; - - public InputPin Input { get; } - public OutputPin Output { get; } - - #endregion - - #region Constructors - - public EdgeNode() - { - Input = CreateInputPin(); - Output = CreateOutputPin(); - } - - #endregion - - #region Methods - - /// - public override void Evaluate() - { - bool input = Input.Value; - - Output.Value = input != _lastInput; - - _lastInput = input; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Timing/FlipFlopNode.cs b/src/Artemis.VisualScripting/Nodes/Timing/FlipFlopNode.cs deleted file mode 100644 index a3807e93d..000000000 --- a/src/Artemis.VisualScripting/Nodes/Timing/FlipFlopNode.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Timing; - -[Node("FlipFlop", "Inverts the output when the input changes from false to true", "Timing", InputType = typeof(bool), OutputType = typeof(bool))] -public class FlipFlopNode : Node -{ - #region Properties & Fields - - private bool _lastInput; - private bool _currentValue; - - public InputPin Input { get; } - public OutputPin Output { get; } - - #endregion - - #region Constructors - - public FlipFlopNode() - { - Input = CreateInputPin(); - Output = CreateOutputPin(); - } - - #endregion - - #region Methods - - /// - public override void Evaluate() - { - bool input = Input.Value; - if (input && !_lastInput) - { - _currentValue = !_currentValue; - Output.Value = _currentValue; - } - - _lastInput = input; - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Timing/LatchNode.cs b/src/Artemis.VisualScripting/Nodes/Timing/LatchNode.cs deleted file mode 100644 index 53c2e71c5..000000000 --- a/src/Artemis.VisualScripting/Nodes/Timing/LatchNode.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System.Diagnostics; -using Artemis.Core; -using Artemis.Core.Events; -using RGB.NET.Core; - -namespace Artemis.VisualScripting.Nodes.Timing; - -[Node("Latch", "Only passes the input to the output as long as the control-pin is true. If the control pin is false the last passed value is provided.", "Timing", InputType = typeof(object), OutputType = typeof(object))] -public class LatchNode : Node -{ - #region Properties & Fields - - private long _lastUpdateTimestamp = 0; - - public InputPin Control { get; } - public InputPinCollection Input { get; } - - //TODO DarthAffe 21.08.2022: Find something to output to aling in- and outputs - public OutputPin LastUpdateTime { get; } - - private Dictionary _pinPairs = new(); - - #endregion - - #region Constructors - - public LatchNode() - { - Control = CreateInputPin("Control"); - Input = CreateInputPinCollection(typeof(object), initialCount: 0); - - LastUpdateTime = CreateOutputPin("Last Update"); - - Input.PinAdded += OnInputPinAdded; - Input.PinRemoved += OnInputPinRemoved; - - Input.Add(Input.CreatePin()); - } - - #endregion - - #region Methods - - private void OnInputPinAdded(object? sender, SingleValueEventArgs args) - { - IPin inputPin = args.Value; - _pinPairs.Add(inputPin, CreateOutputPin(typeof(object))); - - inputPin.PinConnected += OnInputPinConnected; - inputPin.PinDisconnected += OnInputPinDisconnected; - - UpdatePinNames(); - } - - private void OnInputPinRemoved(object? sender, SingleValueEventArgs args) - { - IPin inputPin = args.Value; - RemovePin(_pinPairs[inputPin]); - _pinPairs.Remove(inputPin); - - inputPin.PinConnected -= OnInputPinConnected; - inputPin.PinDisconnected -= OnInputPinDisconnected; - - UpdatePinNames(); - } - - private void OnInputPinConnected(object? sender, SingleValueEventArgs args) - { - if (sender is not IPin inputPin || !_pinPairs.ContainsKey(inputPin)) return; - - OutputPin outputPin = _pinPairs[inputPin]; - outputPin.ChangeType(args.Value.Type); - } - - private void OnInputPinDisconnected(object? sender, SingleValueEventArgs args) - { - if (sender is not IPin inputPin || !_pinPairs.ContainsKey(inputPin)) return; - - OutputPin outputPin = _pinPairs[inputPin]; - outputPin.ChangeType(typeof(object)); - } - - private void UpdatePinNames() - { - int counter = 1; - foreach (IPin inputPin in Input.Pins) - { - string name = counter.ToString(); - inputPin.Name = name; - _pinPairs[inputPin].Name = name; - - counter++; - } - } - - /// - public override void Evaluate() - { - if (Control.Value) - { - foreach ((IPin input, OutputPin output) in _pinPairs) - output.Value = input.PinValue; - - LastUpdateTime.Value = 0; - _lastUpdateTimestamp = Stopwatch.GetTimestamp(); - } - else - LastUpdateTime.Value = TimerHelper.GetElapsedTime(_lastUpdateTimestamp); - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Timing/SequencerNode.cs b/src/Artemis.VisualScripting/Nodes/Timing/SequencerNode.cs deleted file mode 100644 index e72c8d5e1..000000000 --- a/src/Artemis.VisualScripting/Nodes/Timing/SequencerNode.cs +++ /dev/null @@ -1,135 +0,0 @@ -using Artemis.Core; -using Artemis.Core.Events; - -namespace Artemis.VisualScripting.Nodes.Timing; - -[Node("Sequencer", "Advances on input every time the control has a rising edge (change to true)", "Timing", OutputType = typeof(object))] -public class SequencerNode : Node -{ - #region Properties & Fields - - private int _currentIndex; - private Type _currentType; - private bool _updating; - private IPin? _currentCyclePin; - - private bool _lastInput; - - public InputPin Input { get; } - public InputPinCollection CycleValues { get; } - - public OutputPin Output { get; } - - #endregion - - #region Constructors - - public SequencerNode() - { - _currentType = typeof(object); - - Input = CreateInputPin("Control"); - CycleValues = CreateInputPinCollection(typeof(object), "", 0); - Output = CreateOutputPin(typeof(object)); - - CycleValues.PinAdded += CycleValuesOnPinAdded; - CycleValues.PinRemoved += CycleValuesOnPinRemoved; - CycleValues.Add(CycleValues.CreatePin()); - } - - #endregion - - #region Methods - - public override void Evaluate() - { - bool input = Input.Value; - - if (input != _lastInput) - { - _currentIndex++; - - if (_currentIndex >= CycleValues.Count()) - _currentIndex = 0; - - _currentCyclePin = null; - } - - _currentCyclePin ??= CycleValues.ElementAt(_currentIndex); - - object? outputValue = _currentCyclePin.PinValue; - if (Output.Type.IsInstanceOfType(outputValue)) - Output.Value = outputValue; - else if (Output.Type.IsValueType) - Output.Value = Output.Type.GetDefault()!; - - _lastInput = input; - } - - private void CycleValuesOnPinAdded(object? sender, SingleValueEventArgs e) - { - e.Value.PinConnected += OnPinConnected; - e.Value.PinDisconnected += OnPinDisconnected; - - _currentCyclePin = null; - } - - private void CycleValuesOnPinRemoved(object? sender, SingleValueEventArgs e) - { - e.Value.PinConnected -= OnPinConnected; - e.Value.PinDisconnected -= OnPinDisconnected; - - _currentCyclePin = null; - } - - private void OnPinDisconnected(object? sender, SingleValueEventArgs e) => ProcessPinDisconnected(); - - private void OnPinConnected(object? sender, SingleValueEventArgs e) => ProcessPinConnected(e.Value); - - private void ProcessPinConnected(IPin source) - { - if (_updating) - return; - - try - { - _updating = true; - - // No need to change anything if the types haven't changed - if (_currentType != source.Type) - ChangeCurrentType(source.Type); - } - finally - { - _updating = false; - } - } - - private void ChangeCurrentType(Type type) - { - CycleValues.ChangeType(type); - Output.ChangeType(type); - - _currentType = type; - } - - private void ProcessPinDisconnected() - { - if (_updating) - return; - try - { - // If there's still a connected pin, stick to the current type - if (CycleValues.Any(v => v.ConnectedTo.Any())) - return; - - ChangeCurrentType(typeof(object)); - } - finally - { - _updating = false; - } - } - - #endregion -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Transition/ColorGradientTransitionNode.cs b/src/Artemis.VisualScripting/Nodes/Transition/ColorGradientTransitionNode.cs deleted file mode 100644 index 69430d4ea..000000000 --- a/src/Artemis.VisualScripting/Nodes/Transition/ColorGradientTransitionNode.cs +++ /dev/null @@ -1,71 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Transition; - -[Node("Color Gradient Transition", "Outputs smoothly transitioned changes to the input color gradient", "Transition", InputType = typeof(ColorGradient), OutputType = typeof(ColorGradient))] -public class ColorGradientTransitionNode : Node -{ - private DateTime _lastEvaluate = DateTime.MinValue; - private float _progress; - private ColorGradient? _currentValue; - private ColorGradient? _sourceValue; - private ColorGradient? _targetValue; - - public ColorGradientTransitionNode() - { - Input = CreateInputPin(); - EasingTime = CreateInputPin("Delay"); - EasingFunction = CreateInputPin("Function"); - - Output = CreateOutputPin(); - } - - public InputPin Input { get; set; } - public InputPin EasingTime { get; set; } - public InputPin EasingFunction { get; set; } - - public OutputPin Output { get; set; } - - public override void Evaluate() - { - DateTime now = DateTime.Now; - - if (Input.Value == null) - return; - - // If the value changed reset progress - if (!Equals(_targetValue, Input.Value)) - { - _sourceValue = _currentValue ?? new ColorGradient(Input.Value); - _targetValue = new ColorGradient(Input.Value); - _progress = 0f; - } - - // Update until finished - if (_progress < 1f) - { - Update(); - Output.Value = _currentValue; - } - // Stop updating past 1 and use the target value - else - { - Output.Value = _targetValue; - } - - _lastEvaluate = now; - } - - private void Update() - { - if (_sourceValue == null || _targetValue == null) - return; - - float easingTime = EasingTime.Value != 0f ? EasingTime.Value : 1f; - TimeSpan delta = DateTime.Now - _lastEvaluate; - - // In case of odd delta's, keep progress between 0f and 1f - _progress = Math.Clamp(_progress + (float) delta.TotalMilliseconds / easingTime, 0f, 1f); - _currentValue = _sourceValue.Interpolate(_targetValue, (float) Easings.Interpolate(_progress, EasingFunction.Value)); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Transition/EasingFunctionNode.cs b/src/Artemis.VisualScripting/Nodes/Transition/EasingFunctionNode.cs deleted file mode 100644 index a0086bf27..000000000 --- a/src/Artemis.VisualScripting/Nodes/Transition/EasingFunctionNode.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Artemis.Core; -using Artemis.VisualScripting.Nodes.Transition.Screens; - -namespace Artemis.VisualScripting.Nodes.Transition; - -[Node("Easing Function", "Outputs a selectable easing function", "Transition", OutputType = typeof(Easings.Functions))] -public class EasingFunctionNode : Node -{ - public EasingFunctionNode() - { - Output = CreateOutputPin(); - } - - public OutputPin Output { get; } - - public override void Evaluate() - { - Output.Value = Storage; - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Transition/NumericTransitionNode.cs b/src/Artemis.VisualScripting/Nodes/Transition/NumericTransitionNode.cs deleted file mode 100644 index 658ceedf3..000000000 --- a/src/Artemis.VisualScripting/Nodes/Transition/NumericTransitionNode.cs +++ /dev/null @@ -1,68 +0,0 @@ -using Artemis.Core; - -namespace Artemis.VisualScripting.Nodes.Transition; - -[Node("Numeric Transition", "Outputs smoothly transitioned changes to the input numeric value", "Transition", InputType = typeof(Numeric), OutputType = typeof(Numeric))] -public class NumericTransitionNode : Node -{ - private float _currentValue; - private DateTime _lastEvaluate = DateTime.MinValue; - private float _progress; - private float _sourceValue; - private float _targetValue; - - public NumericTransitionNode() - { - Input = CreateInputPin(); - EasingTime = CreateInputPin("Delay"); - EasingFunction = CreateInputPin("Function"); - - Output = CreateOutputPin(); - } - - public InputPin Input { get; set; } - public InputPin EasingTime { get; set; } - public InputPin EasingFunction { get; set; } - - public OutputPin Output { get; set; } - - public override void Evaluate() - { - DateTime now = DateTime.Now; - float inputValue = Input.Value; - - // If the value changed reset progress - if (Math.Abs(_targetValue - inputValue) > 0.001f) - { - _sourceValue = _currentValue; - _targetValue = Input.Value; - _progress = 0f; - } - - // Update until finished - if (_progress < 1f) - { - Update(); - Output.Value = new Numeric(_currentValue); - } - // Stop updating past 1 and use the target value - else - { - Output.Value = new Numeric(_targetValue); - } - - _lastEvaluate = now; - } - - private void Update() - { - float easingTime = EasingTime.Value != 0f ? EasingTime.Value : 1f; - TimeSpan delta = DateTime.Now - _lastEvaluate; - - // In case of odd delta's, keep progress between 0f and 1f - _progress = Math.Clamp(_progress + (float) delta.TotalMilliseconds / easingTime, 0f, 1f); - - double eased = _sourceValue + (_targetValue - _sourceValue) * Easings.Interpolate(_progress, EasingFunction.Value); - _currentValue = (float) eased; - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Transition/SKColorTransitionNode.cs b/src/Artemis.VisualScripting/Nodes/Transition/SKColorTransitionNode.cs deleted file mode 100644 index 7ffd037b8..000000000 --- a/src/Artemis.VisualScripting/Nodes/Transition/SKColorTransitionNode.cs +++ /dev/null @@ -1,66 +0,0 @@ -using Artemis.Core; -using SkiaSharp; - -namespace Artemis.VisualScripting.Nodes.Transition; - -[Node("Color Transition", "Outputs smoothly transitioned changes to the input color", "Transition", InputType = typeof(SKColor), OutputType = typeof(SKColor))] -public class SKColorTransitionNode : Node -{ - private SKColor _currentValue; - private DateTime _lastEvaluate = DateTime.MinValue; - private float _progress; - private SKColor _sourceValue; - private SKColor _targetValue; - - public SKColorTransitionNode() - { - Input = CreateInputPin(); - EasingTime = CreateInputPin("Delay"); - EasingFunction = CreateInputPin("Function"); - - Output = CreateOutputPin(); - } - - public InputPin Input { get; set; } - public InputPin EasingTime { get; set; } - public InputPin EasingFunction { get; set; } - - public OutputPin Output { get; set; } - - public override void Evaluate() - { - DateTime now = DateTime.Now; - - // If the value changed reset progress - if (_targetValue != Input.Value) - { - _sourceValue = _currentValue; - _targetValue = Input.Value; - _progress = 0f; - } - - // Update until finished - if (_progress < 1f) - { - Update(); - Output.Value = _currentValue; - } - // Stop updating past 1 and use the target value - else - { - Output.Value = _targetValue; - } - - _lastEvaluate = now; - } - - private void Update() - { - float easingTime = EasingTime.Value != 0f ? EasingTime.Value : 1f; - TimeSpan delta = DateTime.Now - _lastEvaluate; - - // In case of odd delta's, keep progress between 0f and 1f - _progress = Math.Clamp(_progress + (float) delta.TotalMilliseconds / easingTime, 0f, 1f); - _currentValue = _sourceValue.Interpolate(_targetValue, (float) Easings.Interpolate(_progress, EasingFunction.Value)); - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml b/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml deleted file mode 100644 index 457cb2994..000000000 --- a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml +++ /dev/null @@ -1,10 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml.cs deleted file mode 100644 index e989a374a..000000000 --- a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Markup.Xaml; -using Avalonia.ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Transition.Screens; - -public partial class EasingFunctionNodeCustomView : ReactiveUserControl -{ - public EasingFunctionNodeCustomView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomViewModel.cs b/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomViewModel.cs deleted file mode 100644 index 01540d7e6..000000000 --- a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionNodeCustomViewModel.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Collections.ObjectModel; -using Artemis.Core; -using Artemis.UI.Shared.Services.NodeEditor; -using Artemis.UI.Shared.Services.NodeEditor.Commands; -using Artemis.UI.Shared.VisualScripting; -using ReactiveUI; - -namespace Artemis.VisualScripting.Nodes.Transition.Screens; - -public class EasingFunctionNodeCustomViewModel : CustomNodeViewModel -{ - private readonly EasingFunctionNode _node; - private readonly INodeEditorService _nodeEditorService; - - public EasingFunctionNodeCustomViewModel(EasingFunctionNode node, INodeScript script, INodeEditorService nodeEditorService) : base(node, script) - { - _node = node; - _nodeEditorService = nodeEditorService; - - NodeModified += (_, _) => this.RaisePropertyChanged(nameof(SelectedEasingViewModel)); - EasingViewModels = - new ObservableCollection(Enum.GetValues(typeof(Easings.Functions)).Cast().Select(e => new EasingFunctionViewModel(e))); - } - - public ObservableCollection EasingViewModels { get; } - - public EasingFunctionViewModel? SelectedEasingViewModel - { - get => EasingViewModels.FirstOrDefault(e => e.EasingFunction == _node.Storage); - set - { - if (value != null && _node.Storage != value.EasingFunction) - _nodeEditorService.ExecuteCommand(Script, new UpdateStorage(_node, value.EasingFunction)); - } - } -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionView.axaml b/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionView.axaml deleted file mode 100644 index 93f9b1de0..000000000 --- a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionView.axaml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - diff --git a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionView.axaml.cs b/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionView.axaml.cs deleted file mode 100644 index c55200ad6..000000000 --- a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionView.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Markup.Xaml; - -namespace Artemis.VisualScripting.Nodes.Transition.Screens; - -public partial class EasingFunctionView : UserControl -{ - public EasingFunctionView() - { - InitializeComponent(); - } - -} \ No newline at end of file diff --git a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionViewModel.cs b/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionViewModel.cs deleted file mode 100644 index 29f3ad39d..000000000 --- a/src/Artemis.VisualScripting/Nodes/Transition/Screens/EasingFunctionViewModel.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Artemis.Core; -using Artemis.UI.Shared; -using Avalonia; -using Humanizer; - -namespace Artemis.VisualScripting.Nodes.Transition.Screens; - -public class EasingFunctionViewModel : ViewModelBase -{ - public EasingFunctionViewModel(Easings.Functions easingFunction) - { - EasingFunction = easingFunction; - Description = easingFunction.Humanize(); - - EasingPoints = new List(); - for (int i = 1; i <= 10; i++) - { - double y = Easings.Interpolate(i / 10.0, EasingFunction) * 10; - EasingPoints.Add(new Point(i, y)); - } - } - - public Easings.Functions EasingFunction { get; } - public List EasingPoints { get; } - public string Description { get; } -} \ No newline at end of file diff --git a/src/Artemis.sln b/src/Artemis.sln index cd0039bd1..03067b279 100644 --- a/src/Artemis.sln +++ b/src/Artemis.sln @@ -17,8 +17,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Artemis.UI.Linux", "Artemis EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Artemis.UI.MacOS", "Artemis.UI.MacOS\Artemis.UI.MacOS.csproj", "{2F5F16DC-FACF-4559-9882-37C2949814C7}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Artemis.VisualScripting", "Artemis.VisualScripting\Artemis.VisualScripting.csproj", "{412B921A-26F5-4AE6-8B32-0C19BE54F421}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.WebClient.Updating", "Artemis.WebClient.Updating\Artemis.WebClient.Updating.csproj", "{7C8C6F50-0CC8-45B3-B608-A7218C005E4B}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.WebClient.Workshop", "Artemis.WebClient.Workshop\Artemis.WebClient.Workshop.csproj", "{2B982C2E-3CBC-4DAB-9167-CCCA4C78E92B}" @@ -63,10 +61,6 @@ Global {2F5F16DC-FACF-4559-9882-37C2949814C7}.Debug|x64.Build.0 = Debug|x64 {2F5F16DC-FACF-4559-9882-37C2949814C7}.Release|x64.ActiveCfg = Release|x64 {2F5F16DC-FACF-4559-9882-37C2949814C7}.Release|x64.Build.0 = Release|x64 - {412B921A-26F5-4AE6-8B32-0C19BE54F421}.Debug|x64.ActiveCfg = Debug|x64 - {412B921A-26F5-4AE6-8B32-0C19BE54F421}.Debug|x64.Build.0 = Debug|x64 - {412B921A-26F5-4AE6-8B32-0C19BE54F421}.Release|x64.ActiveCfg = Release|x64 - {412B921A-26F5-4AE6-8B32-0C19BE54F421}.Release|x64.Build.0 = Release|x64 {7C8C6F50-0CC8-45B3-B608-A7218C005E4B}.Debug|x64.ActiveCfg = Debug|x64 {7C8C6F50-0CC8-45B3-B608-A7218C005E4B}.Debug|x64.Build.0 = Debug|x64 {7C8C6F50-0CC8-45B3-B608-A7218C005E4B}.Release|x64.ActiveCfg = Release|x64 From bfd4a436de9901f5f4645a0b00ce94f2c39db3b0 Mon Sep 17 00:00:00 2001 From: RobertBeekman Date: Thu, 22 Feb 2024 21:23:47 +0100 Subject: [PATCH 08/12] Profile service - Migrate profiles before importing them --- .../DryIoc/ContainerExtensions.cs | 1 + .../Storage/Interfaces/IProfileMigration.cs | 9 ++ .../ProfileMigrators/M0001NodeProviders.cs | 90 +++++++++++++++++++ .../Services/Storage/ProfileService.cs | 32 ++++++- .../Profile/ProfileConfigurationEntity.cs | 1 + 5 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 src/Artemis.Core/Services/Storage/Interfaces/IProfileMigration.cs create mode 100644 src/Artemis.Core/Services/Storage/ProfileMigrators/M0001NodeProviders.cs diff --git a/src/Artemis.Core/DryIoc/ContainerExtensions.cs b/src/Artemis.Core/DryIoc/ContainerExtensions.cs index 44d377e8a..337fb1def 100644 --- a/src/Artemis.Core/DryIoc/ContainerExtensions.cs +++ b/src/Artemis.Core/DryIoc/ContainerExtensions.cs @@ -36,6 +36,7 @@ public static class ContainerExtensions // Bind migrations container.RegisterMany(storageAssembly, type => type.IsAssignableTo(), Reuse.Singleton, nonPublicServiceTypes: true); + container.RegisterMany(coreAssembly, type => type.IsAssignableTo(), Reuse.Singleton, nonPublicServiceTypes: true); container.RegisterMany(coreAssembly, type => type.IsAssignableTo(), Reuse.Singleton); container.Register(Reuse.Singleton); diff --git a/src/Artemis.Core/Services/Storage/Interfaces/IProfileMigration.cs b/src/Artemis.Core/Services/Storage/Interfaces/IProfileMigration.cs new file mode 100644 index 000000000..7365014e8 --- /dev/null +++ b/src/Artemis.Core/Services/Storage/Interfaces/IProfileMigration.cs @@ -0,0 +1,9 @@ +using Newtonsoft.Json.Linq; + +namespace Artemis.Core.Services; + +internal interface IProfileMigration +{ + int Version { get; } + void Migrate(JObject profileJson); +} \ No newline at end of file diff --git a/src/Artemis.Core/Services/Storage/ProfileMigrators/M0001NodeProviders.cs b/src/Artemis.Core/Services/Storage/ProfileMigrators/M0001NodeProviders.cs new file mode 100644 index 000000000..c55fde0a9 --- /dev/null +++ b/src/Artemis.Core/Services/Storage/ProfileMigrators/M0001NodeProviders.cs @@ -0,0 +1,90 @@ +using Newtonsoft.Json.Linq; + +namespace Artemis.Core.Services.ProfileMigrators; + +/// +/// Migrates nodes to be provider-based. +/// This requires giving them a ProviderId and updating the their namespaces to match the namespace of the new plugin. +/// +internal class M0001NodeProviders : IProfileMigration +{ + /// + public int Version => 1; + + /// + public void Migrate(JObject profileJson) + { + JArray? folders = (JArray?) profileJson["Folders"]?["$values"]; + JArray? layers = (JArray?) profileJson["Layers"]?["$values"]; + + if (folders != null) + { + foreach (JToken folder in folders) + { + MigrateProfileElement(folder); + } + } + + if (layers != null) + { + foreach (JToken layer in layers) + { + MigrateProfileElement(layer); + MigratePropertyGroup(layer["GeneralPropertyGroup"]); + MigratePropertyGroup(layer["TransformPropertyGroup"]); + MigratePropertyGroup(layer["LayerBrush"]?["PropertyGroup"]); + } + } + } + + private void MigrateProfileElement(JToken profileElement) + { + JArray? layerEffects = (JArray?) profileElement["LayerEffects"]?["$values"]; + if (layerEffects != null) + { + foreach (JToken layerEffect in layerEffects) + MigratePropertyGroup(layerEffect["PropertyGroup"]); + } + + JToken? displayCondition = profileElement["DisplayCondition"]; + if (displayCondition != null) + MigrateNodeScript(displayCondition["Script"]); + } + + private void MigratePropertyGroup(JToken? propertyGroup) + { + if (propertyGroup == null || !propertyGroup.HasValues) + return; + + JArray? properties = (JArray?) propertyGroup["Properties"]?["$values"]; + JArray? propertyGroups = (JArray?) propertyGroup["PropertyGroups"]?["$values"]; + + if (properties != null) + { + foreach (JToken property in properties) + MigrateNodeScript(property["DataBinding"]?["NodeScript"]); + } + + if (propertyGroups != null) + { + foreach (JToken childPropertyGroup in propertyGroups) + MigratePropertyGroup(childPropertyGroup); + } + } + + private void MigrateNodeScript(JToken? nodeScript) + { + if (nodeScript == null || !nodeScript.HasValues) + return; + + JArray? nodes = (JArray?) nodeScript["Nodes"]?["$values"]; + if (nodes == null) + return; + + foreach (JToken node in nodes) + { + node["Type"] = node["Type"]?.Value()?.Replace("Artemis.VisualScripting.Nodes", "Artemis.Plugins.Nodes.General.Nodes"); + node["ProviderId"] = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78"; + } + } +} \ No newline at end of file diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs index f93a4f152..e3d0b6fe7 100644 --- a/src/Artemis.Core/Services/Storage/ProfileService.cs +++ b/src/Artemis.Core/Services/Storage/ProfileService.cs @@ -10,6 +10,7 @@ using Artemis.Core.Modules; using Artemis.Storage.Entities.Profile; using Artemis.Storage.Repositories.Interfaces; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Serilog; using SkiaSharp; @@ -24,9 +25,10 @@ internal class ProfileService : IProfileService private readonly List _pendingKeyboardEvents = new(); private readonly List _profileCategories; private readonly IProfileRepository _profileRepository; + private readonly List _profileMigrators; private readonly List _renderExceptions = new(); private readonly List _updateExceptions = new(); - + private DateTime _lastRenderExceptionLog; private DateTime _lastUpdateExceptionLog; @@ -35,13 +37,15 @@ internal class ProfileService : IProfileService IPluginManagementService pluginManagementService, IInputService inputService, IDeviceService deviceService, - IProfileRepository profileRepository) + IProfileRepository profileRepository, + List profileMigrators) { _logger = logger; _profileCategoryRepository = profileCategoryRepository; _pluginManagementService = pluginManagementService; _deviceService = deviceService; _profileRepository = profileRepository; + _profileMigrators = profileMigrators; _profileCategories = new List(_profileCategoryRepository.GetAll().Select(c => new ProfileCategory(c)).OrderBy(c => c.Order)); _deviceService.LedsChanged += DeviceServiceOnLedsChanged; @@ -58,7 +62,7 @@ internal class ProfileService : IProfileService public ProfileConfiguration? FocusProfile { get; set; } public ProfileElement? FocusProfileElement { get; set; } public bool UpdateFocusProfile { get; set; } - + public bool ProfileRenderingDisabled { get; set; } /// @@ -461,7 +465,12 @@ internal class ProfileService : IProfileService await using Stream profileStream = profileEntry.Open(); using StreamReader profileReader = new(profileStream); - ProfileEntity? profileEntity = JsonConvert.DeserializeObject(await profileReader.ReadToEndAsync(), IProfileService.ExportSettings); + JObject? profileJson = JsonConvert.DeserializeObject(await profileReader.ReadToEndAsync(), IProfileService.ExportSettings); + + // Before deserializing, apply any pending migrations + MigrateProfile(configurationEntity, profileJson); + + ProfileEntity? profileEntity = profileJson?.ToObject(JsonSerializer.Create(IProfileService.ExportSettings)); if (profileEntity == null) throw new ArtemisCoreException("Could not import profile, failed to deserialize profile.json"); @@ -545,6 +554,21 @@ internal class ProfileService : IProfileService } } + private void MigrateProfile(ProfileConfigurationEntity configurationEntity, JObject? profileJson) + { + if (profileJson == null) + return; + + foreach (IProfileMigration profileMigrator in _profileMigrators.OrderBy(m => m.Version)) + { + if (profileMigrator.Version <= configurationEntity.Version) + continue; + + profileMigrator.Migrate(profileJson); + configurationEntity.Version = profileMigrator.Version; + } + } + /// /// Populates all missing LEDs on all currently active profiles /// diff --git a/src/Artemis.Storage/Entities/Profile/ProfileConfigurationEntity.cs b/src/Artemis.Storage/Entities/Profile/ProfileConfigurationEntity.cs index 276b6ec8d..941c9057b 100644 --- a/src/Artemis.Storage/Entities/Profile/ProfileConfigurationEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/ProfileConfigurationEntity.cs @@ -26,4 +26,5 @@ public class ProfileConfigurationEntity public Guid ProfileId { get; set; } public bool FadeInAndOut { get; set; } + public int Version { get; set; } } \ No newline at end of file From 248d4c8e1825b5d5ecfd1bb2df2ad3a7c70c8d93 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 23 Feb 2024 17:35:06 +0100 Subject: [PATCH 09/12] Storage - Use nullable reference types Core - Fix build warnings --- src/Artemis.Core/Models/Profile/Layer.cs | 4 +- .../Models/Profile/LayerPropertyGroup.cs | 3 +- .../Models/Surface/ArtemisDevice.cs | 7 +- .../Models/Surface/Layout/ArtemisLayout.cs | 3 + .../LayerBrushes/LayerBrushDescriptor.cs | 2 +- .../LayerEffects/Internal/BaseLayerEffect.cs | 2 +- .../Plugins/Settings/PluginSettings.cs | 2 +- .../Providers/CustomPathLayoutProvider.cs | 12 ++- .../Providers/DefaultLayoutProvider.cs | 12 ++- .../Providers/Interfaces/ILayoutProvider.cs | 11 +++ .../Providers/NoneLayoutProvider.cs | 12 ++- .../ProcessMonitoring/ProcessMonitor.cs | 54 +++++++++-- .../Registration/LayerBrushService.cs | 1 + .../Services/Storage/ProfileService.cs | 6 +- .../WebServer/Interfaces/IWebServerService.cs | 2 +- src/Artemis.Storage/Artemis.Storage.csproj | 4 +- .../Entities/General/QueuedActionEntity.cs | 2 +- .../Entities/General/ReleaseEntity.cs | 2 +- .../General/ScriptConfigurationEntity.cs | 6 +- .../Entities/Plugins/PluginEntity.cs | 2 +- .../Entities/Plugins/PluginSettingEntity.cs | 4 +- .../Abstract/DisplayConditionPartEntity.cs | 8 -- .../Profile/Abstract/RenderElementEntity.cs | 6 +- .../AdaptionHints/IAdaptionHintEntity.cs | 4 +- .../Conditions/AlwaysOnConditionEntity.cs | 4 +- .../Conditions/EventConditionEntity.cs | 4 +- .../Profile/Conditions/IConditionEntity.cs | 4 +- .../Conditions/PlayOnceConditionEntity.cs | 4 +- .../Conditions/StaticConditionEntity.cs | 2 +- .../Profile/DataBindings/DataBindingEntity.cs | 3 +- .../Entities/Profile/DataModelPathEntity.cs | 6 +- .../Entities/Profile/FolderEntity.cs | 10 +- .../Entities/Profile/KeyframeEntity.cs | 2 +- .../Entities/Profile/LayerBrushEntity.cs | 6 +- .../Entities/Profile/LayerEffectEntity.cs | 8 +- .../Entities/Profile/LayerEntity.cs | 11 +-- .../Entities/Profile/LedEntity.cs | 6 +- .../Profile/Nodes/NodeConnectionEntity.cs | 4 +- .../Entities/Profile/Nodes/NodeEntity.cs | 10 +- .../Profile/Nodes/NodeScriptEntity.cs | 4 +- .../Entities/Profile/ProfileCategoryEntity.cs | 2 +- .../Profile/ProfileConfigurationEntity.cs | 12 +-- .../Entities/Profile/ProfileEntity.cs | 4 +- .../Entities/Profile/PropertyEntity.cs | 6 +- .../Entities/Profile/PropertyGroupEntity.cs | 2 +- .../Entities/Surface/DeviceEntity.cs | 14 +-- .../Entities/Workshop/EntryEntity.cs | 7 +- .../Migrations/IProfileMigration.cs | 11 +++ .../{Interfaces => }/IStorageMigration.cs | 0 .../Migrations/Profile/M0001NodeProviders.cs | 97 +++++++++++++++++++ .../{ => Storage}/M0020AvaloniaReset.cs | 0 .../{ => Storage}/M0021GradientNodes.cs | 13 ++- .../{ => Storage}/M0022TransitionNodes.cs | 10 +- .../{ => Storage}/M0023LayoutProviders.cs | 0 .../Repositories/DeviceRepository.cs | 2 +- .../Repositories/EntryRepository.cs | 4 +- .../Interfaces/IDeviceRepository.cs | 2 +- .../Interfaces/IEntryRepository.cs | 4 +- .../Interfaces/IPluginRepository.cs | 6 +- .../Interfaces/IProfileCategoryRepository.cs | 4 +- .../Interfaces/IProfileRepository.cs | 2 +- .../Repositories/Interfaces/IRepository.cs | 4 +- .../Repositories/PluginRepository.cs | 6 +- .../Repositories/ProfileCategoryRepository.cs | 4 +- .../Repositories/ProfileRepository.cs | 2 +- 65 files changed, 318 insertions(+), 159 deletions(-) delete mode 100644 src/Artemis.Storage/Entities/Profile/Abstract/DisplayConditionPartEntity.cs create mode 100644 src/Artemis.Storage/Migrations/IProfileMigration.cs rename src/Artemis.Storage/Migrations/{Interfaces => }/IStorageMigration.cs (100%) create mode 100644 src/Artemis.Storage/Migrations/Profile/M0001NodeProviders.cs rename src/Artemis.Storage/Migrations/{ => Storage}/M0020AvaloniaReset.cs (100%) rename src/Artemis.Storage/Migrations/{ => Storage}/M0021GradientNodes.cs (87%) rename src/Artemis.Storage/Migrations/{ => Storage}/M0022TransitionNodes.cs (89%) rename src/Artemis.Storage/Migrations/{ => Storage}/M0023LayoutProviders.cs (100%) diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs index 58c13265f..66df68a05 100644 --- a/src/Artemis.Core/Models/Profile/Layer.cs +++ b/src/Artemis.Core/Models/Profile/Layer.cs @@ -248,8 +248,8 @@ public sealed class Layer : RenderProfileElement typeof(PropertyGroupDescriptionAttribute) )!; - LayerEntity.GeneralPropertyGroup ??= new PropertyGroupEntity {Identifier = generalAttribute.Identifier}; - LayerEntity.TransformPropertyGroup ??= new PropertyGroupEntity {Identifier = transformAttribute.Identifier}; + LayerEntity.GeneralPropertyGroup ??= new PropertyGroupEntity {Identifier = generalAttribute.Identifier!}; + LayerEntity.TransformPropertyGroup ??= new PropertyGroupEntity {Identifier = transformAttribute.Identifier!}; General.Initialize(this, null, generalAttribute, LayerEntity.GeneralPropertyGroup); Transform.Initialize(this, null, transformAttribute, LayerEntity.TransformPropertyGroup); diff --git a/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs b/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs index 591dd4faa..31b4af879 100644 --- a/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs +++ b/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs @@ -240,7 +240,8 @@ public abstract class LayerPropertyGroup : IDisposable foreach (LayerPropertyGroup layerPropertyGroup in LayerPropertyGroups) { layerPropertyGroup.ApplyToEntity(); - PropertyGroupEntity.PropertyGroups.Add(layerPropertyGroup.PropertyGroupEntity); + if (layerPropertyGroup.PropertyGroupEntity != null) + PropertyGroupEntity.PropertyGroups.Add(layerPropertyGroup.PropertyGroupEntity); } } diff --git a/src/Artemis.Core/Models/Surface/ArtemisDevice.cs b/src/Artemis.Core/Models/Surface/ArtemisDevice.cs index 6a42aacc7..40482de47 100644 --- a/src/Artemis.Core/Models/Surface/ArtemisDevice.cs +++ b/src/Artemis.Core/Models/Surface/ArtemisDevice.cs @@ -46,7 +46,7 @@ public class ArtemisDevice : CorePropertyChanged InputIdentifiers = new List(); InputMappings = new Dictionary(); Categories = new HashSet(); - LayoutSelection = new LayoutSelection {Type = DefaultLayoutProvider.LayoutType}; + LayoutSelection = new LayoutSelection {Type = DefaultLayoutProvider.LAYOUT_TYPE}; RgbDevice.ColorCorrections.Clear(); RgbDevice.ColorCorrections.Add(new ScaleColorCorrection(this)); @@ -75,7 +75,7 @@ public class ArtemisDevice : CorePropertyChanged InputIdentifiers = new List(); InputMappings = new Dictionary(); Categories = new HashSet(); - LayoutSelection = new LayoutSelection {Type = DefaultLayoutProvider.LayoutType}; + LayoutSelection = new LayoutSelection {Type = DefaultLayoutProvider.LAYOUT_TYPE}; foreach (DeviceInputIdentifierEntity identifierEntity in DeviceEntity.InputIdentifiers) InputIdentifiers.Add(new ArtemisDeviceInputIdentifier(identifierEntity.InputProvider, identifierEntity.Identifier)); @@ -155,6 +155,9 @@ public class ArtemisDevice : CorePropertyChanged /// public HashSet Categories { get; } + /// + /// Gets the layout selection applied to this device + /// public LayoutSelection LayoutSelection { get; } /// diff --git a/src/Artemis.Core/Models/Surface/Layout/ArtemisLayout.cs b/src/Artemis.Core/Models/Surface/Layout/ArtemisLayout.cs index 5304f5e37..44ddbf082 100644 --- a/src/Artemis.Core/Models/Surface/Layout/ArtemisLayout.cs +++ b/src/Artemis.Core/Models/Surface/Layout/ArtemisLayout.cs @@ -57,6 +57,9 @@ public class ArtemisLayout /// public LayoutCustomDeviceData LayoutCustomDeviceData { get; private set; } = null!; + /// + /// Gets a boolean indicating whether this layout is a default layout or not + /// public bool IsDefaultLayout { get; private set; } /// diff --git a/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushDescriptor.cs b/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushDescriptor.cs index 3e245f9c4..e82488b46 100644 --- a/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushDescriptor.cs +++ b/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushDescriptor.cs @@ -65,7 +65,7 @@ public class LayerBrushDescriptor BaseLayerBrush brush = (BaseLayerBrush) Provider.Plugin.Resolve(LayerBrushType); brush.Layer = layer; brush.Descriptor = this; - brush.LayerBrushEntity = entity ?? new LayerBrushEntity {ProviderId = Provider.Id, BrushType = LayerBrushType.FullName}; + brush.LayerBrushEntity = entity ?? new LayerBrushEntity {ProviderId = Provider.Id, BrushType = LayerBrushType.FullName ?? throw new InvalidOperationException()}; brush.Initialize(); return brush; diff --git a/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs b/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs index 94cc830ba..7d300077f 100644 --- a/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs +++ b/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs @@ -231,7 +231,7 @@ public abstract class BaseLayerEffect : BreakableModel, IDisposable, IStorageMod return; LayerEffectEntity.ProviderId = Descriptor.Provider.Id; - LayerEffectEntity.EffectType = GetType().FullName; + LayerEffectEntity.EffectType = GetType().FullName ?? throw new InvalidOperationException(); BaseProperties?.ApplyToEntity(); LayerEffectEntity.PropertyGroup = BaseProperties?.PropertyGroupEntity; } diff --git a/src/Artemis.Core/Plugins/Settings/PluginSettings.cs b/src/Artemis.Core/Plugins/Settings/PluginSettings.cs index 8e795caaf..84061e48e 100644 --- a/src/Artemis.Core/Plugins/Settings/PluginSettings.cs +++ b/src/Artemis.Core/Plugins/Settings/PluginSettings.cs @@ -41,7 +41,7 @@ public class PluginSettings if (_settingEntities.ContainsKey(name)) return (PluginSetting) _settingEntities[name]; // Try to find in database - PluginSettingEntity settingEntity = _pluginRepository.GetSettingByNameAndGuid(name, Plugin.Guid); + PluginSettingEntity? settingEntity = _pluginRepository.GetSettingByNameAndGuid(name, Plugin.Guid); // If not found, create a new one if (settingEntity == null) { diff --git a/src/Artemis.Core/Providers/CustomPathLayoutProvider.cs b/src/Artemis.Core/Providers/CustomPathLayoutProvider.cs index bd2ba228b..21e932540 100644 --- a/src/Artemis.Core/Providers/CustomPathLayoutProvider.cs +++ b/src/Artemis.Core/Providers/CustomPathLayoutProvider.cs @@ -1,8 +1,14 @@ namespace Artemis.Core.Providers; +/// +/// Represents a layout provider that loads a layout from a custom path. +/// public class CustomPathLayoutProvider : ILayoutProvider { - public static string LayoutType = "CustomPath"; + /// + /// The layout type of this layout provider. + /// + public const string LAYOUT_TYPE = "CustomPath"; /// public ArtemisLayout? GetDeviceLayout(ArtemisDevice device) @@ -21,7 +27,7 @@ public class CustomPathLayoutProvider : ILayoutProvider /// public bool IsMatch(ArtemisDevice device) { - return device.LayoutSelection.Type == LayoutType; + return device.LayoutSelection.Type == LAYOUT_TYPE; } /// @@ -31,7 +37,7 @@ public class CustomPathLayoutProvider : ILayoutProvider /// The path to the custom layout. public void ConfigureDevice(ArtemisDevice device, string? path) { - device.LayoutSelection.Type = LayoutType; + device.LayoutSelection.Type = LAYOUT_TYPE; device.LayoutSelection.Parameter = path; } } \ No newline at end of file diff --git a/src/Artemis.Core/Providers/DefaultLayoutProvider.cs b/src/Artemis.Core/Providers/DefaultLayoutProvider.cs index 8c709ab27..906cd445c 100644 --- a/src/Artemis.Core/Providers/DefaultLayoutProvider.cs +++ b/src/Artemis.Core/Providers/DefaultLayoutProvider.cs @@ -1,8 +1,14 @@ namespace Artemis.Core.Providers; +/// +/// Represents a layout provider that loads a layout from the plugin and falls back to a default layout. +/// public class DefaultLayoutProvider : ILayoutProvider { - public static string LayoutType = "Default"; + /// + /// The layout type of this layout provider. + /// + public const string LAYOUT_TYPE = "Default"; /// public ArtemisLayout? GetDeviceLayout(ArtemisDevice device) @@ -26,7 +32,7 @@ public class DefaultLayoutProvider : ILayoutProvider /// public bool IsMatch(ArtemisDevice device) { - return device.LayoutSelection.Type == LayoutType; + return device.LayoutSelection.Type == LAYOUT_TYPE; } /// @@ -35,7 +41,7 @@ public class DefaultLayoutProvider : ILayoutProvider /// The device to apply the provider to. public void ConfigureDevice(ArtemisDevice device) { - device.LayoutSelection.Type = LayoutType; + device.LayoutSelection.Type = LAYOUT_TYPE; device.LayoutSelection.Parameter = null; } } \ No newline at end of file diff --git a/src/Artemis.Core/Providers/Interfaces/ILayoutProvider.cs b/src/Artemis.Core/Providers/Interfaces/ILayoutProvider.cs index 3cccfe39d..2ce2e511c 100644 --- a/src/Artemis.Core/Providers/Interfaces/ILayoutProvider.cs +++ b/src/Artemis.Core/Providers/Interfaces/ILayoutProvider.cs @@ -12,6 +12,17 @@ public interface ILayoutProvider /// The resulting layout if one was available; otherwise . ArtemisLayout? GetDeviceLayout(ArtemisDevice device); + /// + /// Applies the layout to the provided device. + /// + /// The device to apply to. + /// The layout to apply. void ApplyLayout(ArtemisDevice device, ArtemisLayout layout); + + /// + /// Determines whether the provided device is configured to use this layout provider. + /// + /// The device to check. + /// A value indicating whether the provided device is configured to use this layout provider. bool IsMatch(ArtemisDevice device); } \ No newline at end of file diff --git a/src/Artemis.Core/Providers/NoneLayoutProvider.cs b/src/Artemis.Core/Providers/NoneLayoutProvider.cs index 59c13391b..1a1c774c7 100644 --- a/src/Artemis.Core/Providers/NoneLayoutProvider.cs +++ b/src/Artemis.Core/Providers/NoneLayoutProvider.cs @@ -1,8 +1,14 @@ namespace Artemis.Core.Providers; +/// +/// Represents a layout provider that does not load a layout. +/// public class NoneLayoutProvider : ILayoutProvider { - public static string LayoutType = "None"; + /// + /// The layout type of this layout provider. + /// + public const string LAYOUT_TYPE = "None"; /// public ArtemisLayout? GetDeviceLayout(ArtemisDevice device) @@ -19,7 +25,7 @@ public class NoneLayoutProvider : ILayoutProvider /// public bool IsMatch(ArtemisDevice device) { - return device.LayoutSelection.Type == LayoutType; + return device.LayoutSelection.Type == LAYOUT_TYPE; } /// @@ -28,7 +34,7 @@ public class NoneLayoutProvider : ILayoutProvider /// The device to apply the provider to. public void ConfigureDevice(ArtemisDevice device) { - device.LayoutSelection.Type = LayoutType; + device.LayoutSelection.Type = LAYOUT_TYPE; device.LayoutSelection.Parameter = null; } } \ No newline at end of file diff --git a/src/Artemis.Core/Services/ProcessMonitoring/ProcessMonitor.cs b/src/Artemis.Core/Services/ProcessMonitoring/ProcessMonitor.cs index 0ad901301..aa0cf8d5b 100644 --- a/src/Artemis.Core/Services/ProcessMonitoring/ProcessMonitor.cs +++ b/src/Artemis.Core/Services/ProcessMonitoring/ProcessMonitor.cs @@ -7,6 +7,9 @@ using System.Threading; namespace Artemis.Core.Services; +/// +/// Represents a monitor that efficiently keeps track of running processes. +/// public static partial class ProcessMonitor { #region Properties & Fields @@ -15,8 +18,11 @@ public static partial class ProcessMonitor private static Timer? _timer; - private static Dictionary _processes = new(); + private static readonly Dictionary _processes = new(); + /// + /// Gets an immutable array of the current processes. + /// public static ImmutableArray Processes { get @@ -25,9 +31,17 @@ public static partial class ProcessMonitor return _processes.Values.ToImmutableArray(); } } + + /// + /// Gets the date time at which the last update took place. + /// public static DateTime LastUpdate { get; private set; } private static TimeSpan _updateInterval = TimeSpan.FromSeconds(1); + + /// + /// Gets or sets the interval at which to update the list of processes. + /// public static TimeSpan UpdateInterval { get => _updateInterval; @@ -40,6 +54,9 @@ public static partial class ProcessMonitor } } + /// + /// Gets a value indicating whether the monitoring has started. + /// public static bool IsStarted { get @@ -53,7 +70,14 @@ public static partial class ProcessMonitor #region Events + /// + /// Occurs when a new process is started. + /// public static event EventHandler? ProcessStarted; + + /// + /// Occurs when a process is stopped. + /// public static event EventHandler? ProcessStopped; #endregion @@ -69,6 +93,9 @@ public static partial class ProcessMonitor #region Methods + /// + /// Starts monitoring processes. + /// public static void Start() { lock (LOCK) @@ -87,6 +114,9 @@ public static partial class ProcessMonitor } } + /// + /// Stops monitoring processes. + /// public static void Stop() { lock (LOCK) @@ -100,7 +130,7 @@ public static partial class ProcessMonitor FreeBuffer(); } } - + /// /// Returns whether the specified process is running /// @@ -111,7 +141,7 @@ public static partial class ProcessMonitor { if (!IsStarted || (processName == null && processLocation == null)) return false; - + lock (LOCK) { return _processes.Values.Any(x => IsProcessRunning(x, processName, processLocation)); @@ -130,19 +160,19 @@ public static partial class ProcessMonitor OnProcessStopped(info); } } - + private static bool IsProcessRunning(ProcessInfo info, string? processName, string? processLocation) { if (processName != null && processLocation != null) return string.Equals(info.ProcessName, processName, StringComparison.InvariantCultureIgnoreCase) && string.Equals(Path.GetDirectoryName(info.Executable), processLocation, StringComparison.InvariantCultureIgnoreCase); - + if (processName != null) return string.Equals(info.ProcessName, processName, StringComparison.InvariantCultureIgnoreCase); - + if (processLocation != null) return string.Equals(Path.GetDirectoryName(info.Executable), processLocation, StringComparison.InvariantCultureIgnoreCase); - + return false; } @@ -152,7 +182,10 @@ public static partial class ProcessMonitor { ProcessStarted?.Invoke(null, new ProcessEventArgs(processInfo)); } - catch { /* Subscribers are idiots! */ } + catch + { + /* Subscribers are idiots! */ + } } private static void OnProcessStopped(ProcessInfo processInfo) @@ -161,7 +194,10 @@ public static partial class ProcessMonitor { ProcessStopped?.Invoke(null, new ProcessEventArgs(processInfo)); } - catch { /* Subscribers are idiots! */ } + catch + { + /* Subscribers are idiots! */ + } } #endregion diff --git a/src/Artemis.Core/Services/Registration/LayerBrushService.cs b/src/Artemis.Core/Services/Registration/LayerBrushService.cs index fd12bed2c..ed9858d6d 100644 --- a/src/Artemis.Core/Services/Registration/LayerBrushService.cs +++ b/src/Artemis.Core/Services/Registration/LayerBrushService.cs @@ -42,6 +42,7 @@ internal class LayerBrushService : ILayerBrushService BrushType = "SolidBrush" }); + defaultReference.Value ??= new LayerBrushReference(); defaultReference.Value.LayerBrushProviderId ??= "Artemis.Plugins.LayerBrushes.Color.ColorBrushProvider-92a9d6ba"; defaultReference.Value.BrushType ??= "SolidBrush"; return LayerBrushStore.Get(defaultReference.Value.LayerBrushProviderId, defaultReference.Value.BrushType)?.LayerBrushDescriptor; diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs index f93a4f152..f2dd26de6 100644 --- a/src/Artemis.Core/Services/Storage/ProfileService.cs +++ b/src/Artemis.Core/Services/Storage/ProfileService.cs @@ -221,7 +221,7 @@ internal class ProfileService : IProfileService return profileConfiguration.Profile; } - ProfileEntity profileEntity; + ProfileEntity? profileEntity; try { profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId); @@ -280,7 +280,7 @@ internal class ProfileService : IProfileService { DeactivateProfile(profileConfiguration); - ProfileEntity profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId); + ProfileEntity? profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId); if (profileEntity == null) return; @@ -353,7 +353,7 @@ internal class ProfileService : IProfileService DeactivateProfile(profileConfiguration); SaveProfileCategory(profileConfiguration.Category); - ProfileEntity profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId); + ProfileEntity? profileEntity = _profileRepository.Get(profileConfiguration.Entity.ProfileId); if (profileEntity != null) _profileRepository.Remove(profileEntity); diff --git a/src/Artemis.Core/Services/WebServer/Interfaces/IWebServerService.cs b/src/Artemis.Core/Services/WebServer/Interfaces/IWebServerService.cs index b950f9f49..d185d33c9 100644 --- a/src/Artemis.Core/Services/WebServer/Interfaces/IWebServerService.cs +++ b/src/Artemis.Core/Services/WebServer/Interfaces/IWebServerService.cs @@ -100,7 +100,7 @@ public interface IWebServerService : IArtemisService /// /// Removes an existing Web API controller and restarts the web server /// - /// The type of Web API controller to remove + /// The registration of the controller to remove. void RemoveController(WebApiControllerRegistration registration); /// diff --git a/src/Artemis.Storage/Artemis.Storage.csproj b/src/Artemis.Storage/Artemis.Storage.csproj index d682d5570..d7ebef960 100644 --- a/src/Artemis.Storage/Artemis.Storage.csproj +++ b/src/Artemis.Storage/Artemis.Storage.csproj @@ -1,12 +1,14 @@ - + net8.0 false x64 + enable + \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/General/QueuedActionEntity.cs b/src/Artemis.Storage/Entities/General/QueuedActionEntity.cs index 45c7e72fa..942a6501d 100644 --- a/src/Artemis.Storage/Entities/General/QueuedActionEntity.cs +++ b/src/Artemis.Storage/Entities/General/QueuedActionEntity.cs @@ -11,7 +11,7 @@ public class QueuedActionEntity } public Guid Id { get; set; } - public string Type { get; set; } + public string Type { get; set; } = string.Empty; public DateTimeOffset CreatedAt { get; set; } public Dictionary Parameters { get; set; } diff --git a/src/Artemis.Storage/Entities/General/ReleaseEntity.cs b/src/Artemis.Storage/Entities/General/ReleaseEntity.cs index b3f39fb64..f83efb6f1 100644 --- a/src/Artemis.Storage/Entities/General/ReleaseEntity.cs +++ b/src/Artemis.Storage/Entities/General/ReleaseEntity.cs @@ -6,6 +6,6 @@ public class ReleaseEntity { public Guid Id { get; set; } - public string Version { get; set; } + public string Version { get; set; } = string.Empty; public DateTimeOffset? InstalledAt { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/General/ScriptConfigurationEntity.cs b/src/Artemis.Storage/Entities/General/ScriptConfigurationEntity.cs index 73709a8a4..3bd28f252 100644 --- a/src/Artemis.Storage/Entities/General/ScriptConfigurationEntity.cs +++ b/src/Artemis.Storage/Entities/General/ScriptConfigurationEntity.cs @@ -6,7 +6,7 @@ public class ScriptConfigurationEntity { public Guid Id { get; set; } - public string Name { get; set; } - public string ScriptingProviderId { get; set; } - public string ScriptContent { get; set; } + public string Name { get; set; } = string.Empty; + public string ScriptingProviderId { get; set; } = string.Empty; + public string? ScriptContent { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Plugins/PluginEntity.cs b/src/Artemis.Storage/Entities/Plugins/PluginEntity.cs index 2be0e45e1..611200781 100644 --- a/src/Artemis.Storage/Entities/Plugins/PluginEntity.cs +++ b/src/Artemis.Storage/Entities/Plugins/PluginEntity.cs @@ -24,6 +24,6 @@ public class PluginEntity /// public class PluginFeatureEntity { - public string Type { get; set; } + public string Type { get; set; } = string.Empty; public bool IsEnabled { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Plugins/PluginSettingEntity.cs b/src/Artemis.Storage/Entities/Plugins/PluginSettingEntity.cs index 26068c503..1d604c28a 100644 --- a/src/Artemis.Storage/Entities/Plugins/PluginSettingEntity.cs +++ b/src/Artemis.Storage/Entities/Plugins/PluginSettingEntity.cs @@ -10,6 +10,6 @@ public class PluginSettingEntity public Guid Id { get; set; } public Guid PluginGuid { get; set; } - public string Name { get; set; } - public string Value { get; set; } + public string Name { get; set; } = string.Empty; + public string Value { get; set; } = string.Empty; } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/Abstract/DisplayConditionPartEntity.cs b/src/Artemis.Storage/Entities/Profile/Abstract/DisplayConditionPartEntity.cs deleted file mode 100644 index 951c09e15..000000000 --- a/src/Artemis.Storage/Entities/Profile/Abstract/DisplayConditionPartEntity.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Collections.Generic; - -namespace Artemis.Storage.Entities.Profile.Abstract; - -public abstract class DataModelConditionPartEntity -{ - public List Children { get; set; } -} \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/Abstract/RenderElementEntity.cs b/src/Artemis.Storage/Entities/Profile/Abstract/RenderElementEntity.cs index 688b202ff..f31ca23ef 100644 --- a/src/Artemis.Storage/Entities/Profile/Abstract/RenderElementEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/Abstract/RenderElementEntity.cs @@ -8,8 +8,8 @@ public abstract class RenderElementEntity public Guid Id { get; set; } public Guid ParentId { get; set; } - public List LayerEffects { get; set; } + public List LayerEffects { get; set; } = new(); - public IConditionEntity DisplayCondition { get; set; } - public TimelineEntity Timeline { get; set; } + public IConditionEntity? DisplayCondition { get; set; } + public TimelineEntity? Timeline { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/AdaptionHints/IAdaptionHintEntity.cs b/src/Artemis.Storage/Entities/Profile/AdaptionHints/IAdaptionHintEntity.cs index 03f144000..57c914786 100644 --- a/src/Artemis.Storage/Entities/Profile/AdaptionHints/IAdaptionHintEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/AdaptionHints/IAdaptionHintEntity.cs @@ -1,5 +1,3 @@ namespace Artemis.Storage.Entities.Profile.AdaptionHints; -public interface IAdaptionHintEntity -{ -} \ No newline at end of file +public interface IAdaptionHintEntity; \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/Conditions/AlwaysOnConditionEntity.cs b/src/Artemis.Storage/Entities/Profile/Conditions/AlwaysOnConditionEntity.cs index efb0a4763..549fde0b7 100644 --- a/src/Artemis.Storage/Entities/Profile/Conditions/AlwaysOnConditionEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/Conditions/AlwaysOnConditionEntity.cs @@ -2,6 +2,4 @@ namespace Artemis.Storage.Entities.Profile.Conditions; -public class AlwaysOnConditionEntity : IConditionEntity -{ -} \ No newline at end of file +public class AlwaysOnConditionEntity : IConditionEntity; \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/Conditions/EventConditionEntity.cs b/src/Artemis.Storage/Entities/Profile/Conditions/EventConditionEntity.cs index e88f854b5..fa2af4270 100644 --- a/src/Artemis.Storage/Entities/Profile/Conditions/EventConditionEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/Conditions/EventConditionEntity.cs @@ -8,6 +8,6 @@ public class EventConditionEntity : IConditionEntity public int TriggerMode { get; set; } public int OverlapMode { get; set; } public int ToggleOffMode { get; set; } - public DataModelPathEntity EventPath { get; set; } - public NodeScriptEntity Script { get; set; } + public DataModelPathEntity? EventPath { get; set; } + public NodeScriptEntity? Script { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/Conditions/IConditionEntity.cs b/src/Artemis.Storage/Entities/Profile/Conditions/IConditionEntity.cs index 206872aeb..f1f24ee14 100644 --- a/src/Artemis.Storage/Entities/Profile/Conditions/IConditionEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/Conditions/IConditionEntity.cs @@ -1,5 +1,3 @@ namespace Artemis.Storage.Entities.Profile.Abstract; -public interface IConditionEntity -{ -} \ No newline at end of file +public interface IConditionEntity; \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/Conditions/PlayOnceConditionEntity.cs b/src/Artemis.Storage/Entities/Profile/Conditions/PlayOnceConditionEntity.cs index 5b365a195..8264a58f8 100644 --- a/src/Artemis.Storage/Entities/Profile/Conditions/PlayOnceConditionEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/Conditions/PlayOnceConditionEntity.cs @@ -2,6 +2,4 @@ namespace Artemis.Storage.Entities.Profile.Conditions; -public class PlayOnceConditionEntity : IConditionEntity -{ -} \ No newline at end of file +public class PlayOnceConditionEntity : IConditionEntity; \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/Conditions/StaticConditionEntity.cs b/src/Artemis.Storage/Entities/Profile/Conditions/StaticConditionEntity.cs index 0165ed33f..2aec38205 100644 --- a/src/Artemis.Storage/Entities/Profile/Conditions/StaticConditionEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/Conditions/StaticConditionEntity.cs @@ -7,5 +7,5 @@ public class StaticConditionEntity : IConditionEntity { public int PlayMode { get; set; } public int StopMode { get; set; } - public NodeScriptEntity Script { get; set; } + public NodeScriptEntity? Script { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingEntity.cs index 338f04bcf..93517b01c 100644 --- a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingEntity.cs @@ -4,7 +4,6 @@ namespace Artemis.Storage.Entities.Profile.DataBindings; public class DataBindingEntity { - public string Identifier { get; set; } public bool IsEnabled { get; set; } - public NodeScriptEntity NodeScript { get; set; } + public NodeScriptEntity? NodeScript { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/DataModelPathEntity.cs b/src/Artemis.Storage/Entities/Profile/DataModelPathEntity.cs index ef585ce45..0558f87e6 100644 --- a/src/Artemis.Storage/Entities/Profile/DataModelPathEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/DataModelPathEntity.cs @@ -2,7 +2,7 @@ public class DataModelPathEntity { - public string Path { get; set; } - public string DataModelId { get; set; } - public string Type { get; set; } + public string Path { get; set; } = string.Empty; + public string? DataModelId { get; set; } + public string? Type { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/FolderEntity.cs b/src/Artemis.Storage/Entities/Profile/FolderEntity.cs index 939396b62..f47aa6bb8 100644 --- a/src/Artemis.Storage/Entities/Profile/FolderEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/FolderEntity.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using Artemis.Storage.Entities.Profile.Abstract; using LiteDB; @@ -7,18 +6,13 @@ namespace Artemis.Storage.Entities.Profile; public class FolderEntity : RenderElementEntity { - public FolderEntity() - { - LayerEffects = new List(); - } - public int Order { get; set; } - public string Name { get; set; } + public string? Name { get; set; } public bool IsExpanded { get; set; } public bool Suspended { get; set; } [BsonRef("ProfileEntity")] - public ProfileEntity Profile { get; set; } + public ProfileEntity Profile { get; set; } = null!; public Guid ProfileId { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/KeyframeEntity.cs b/src/Artemis.Storage/Entities/Profile/KeyframeEntity.cs index 331063ac4..48cb5e220 100644 --- a/src/Artemis.Storage/Entities/Profile/KeyframeEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/KeyframeEntity.cs @@ -6,6 +6,6 @@ public class KeyframeEntity { public TimeSpan Position { get; set; } public int Timeline { get; set; } - public string Value { get; set; } + public string Value { get; set; } = string.Empty; public int EasingFunction { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/LayerBrushEntity.cs b/src/Artemis.Storage/Entities/Profile/LayerBrushEntity.cs index b539be6b7..36496ef52 100644 --- a/src/Artemis.Storage/Entities/Profile/LayerBrushEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/LayerBrushEntity.cs @@ -2,8 +2,8 @@ public class LayerBrushEntity { - public string ProviderId { get; set; } - public string BrushType { get; set; } + public string ProviderId { get; set; } = string.Empty; + public string BrushType { get; set; } = string.Empty; - public PropertyGroupEntity PropertyGroup { get; set; } + public PropertyGroupEntity? PropertyGroup { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/LayerEffectEntity.cs b/src/Artemis.Storage/Entities/Profile/LayerEffectEntity.cs index 0e0ba6033..2ee9376ea 100644 --- a/src/Artemis.Storage/Entities/Profile/LayerEffectEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/LayerEffectEntity.cs @@ -2,11 +2,11 @@ public class LayerEffectEntity { - public string ProviderId { get; set; } - public string EffectType { get; set; } - public string Name { get; set; } + public string ProviderId { get; set; } = string.Empty; + public string EffectType { get; set; } = string.Empty; + public string Name { get; set; } = string.Empty; public bool HasBeenRenamed { get; set; } public int Order { get; set; } - public PropertyGroupEntity PropertyGroup { get; set; } + public PropertyGroupEntity? PropertyGroup { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/LayerEntity.cs b/src/Artemis.Storage/Entities/Profile/LayerEntity.cs index 30fc9ca1b..521550b34 100644 --- a/src/Artemis.Storage/Entities/Profile/LayerEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/LayerEntity.cs @@ -12,22 +12,21 @@ public class LayerEntity : RenderElementEntity { Leds = new List(); AdaptionHints = new List(); - LayerEffects = new List(); } public int Order { get; set; } - public string Name { get; set; } + public string? Name { get; set; } public bool Suspended { get; set; } public List Leds { get; set; } public List AdaptionHints { get; set; } - public PropertyGroupEntity GeneralPropertyGroup { get; set; } - public PropertyGroupEntity TransformPropertyGroup { get; set; } - public LayerBrushEntity LayerBrush { get; set; } + public PropertyGroupEntity? GeneralPropertyGroup { get; set; } + public PropertyGroupEntity? TransformPropertyGroup { get; set; } + public LayerBrushEntity? LayerBrush { get; set; } [BsonRef("ProfileEntity")] - public ProfileEntity Profile { get; set; } + public ProfileEntity Profile { get; set; } = null!; public Guid ProfileId { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/LedEntity.cs b/src/Artemis.Storage/Entities/Profile/LedEntity.cs index be4536471..da89f9d7d 100644 --- a/src/Artemis.Storage/Entities/Profile/LedEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/LedEntity.cs @@ -5,8 +5,8 @@ namespace Artemis.Storage.Entities.Profile; public class LedEntity { - public string LedName { get; set; } - public string DeviceIdentifier { get; set; } + public string LedName { get; set; } = string.Empty; + public string DeviceIdentifier { get; set; } = string.Empty; public int? PhysicalLayout { get; set; } @@ -14,7 +14,7 @@ public class LedEntity private sealed class LedEntityEqualityComparer : IEqualityComparer { - public bool Equals(LedEntity x, LedEntity y) + public bool Equals(LedEntity? x, LedEntity? y) { if (ReferenceEquals(x, y)) return true; diff --git a/src/Artemis.Storage/Entities/Profile/Nodes/NodeConnectionEntity.cs b/src/Artemis.Storage/Entities/Profile/Nodes/NodeConnectionEntity.cs index b85678d53..df21b1535 100644 --- a/src/Artemis.Storage/Entities/Profile/Nodes/NodeConnectionEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/Nodes/NodeConnectionEntity.cs @@ -20,12 +20,12 @@ public class NodeConnectionEntity TargetPinId = nodeConnectionEntity.TargetPinId; } - public string SourceType { get; set; } + public string SourceType { get; set; } = string.Empty; public Guid SourceNode { get; set; } public Guid TargetNode { get; set; } public int SourcePinCollectionId { get; set; } public int SourcePinId { get; set; } - public string TargetType { get; set; } + public string TargetType { get; set; } = string.Empty; public int TargetPinCollectionId { get; set; } public int TargetPinId { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs b/src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs index 5683e5c0f..234d3c7a7 100644 --- a/src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; @@ -28,15 +28,15 @@ public class NodeEntity } public Guid Id { get; set; } - public string Type { get; set; } + public string Type { get; set; } = string.Empty; public Guid PluginId { get; set; } - public string Name { get; set; } - public string Description { get; set; } + public string Name { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; public bool IsExitNode { get; set; } public double X { get; set; } public double Y { get; set; } - public string Storage { get; set; } + public string Storage { get; set; } = string.Empty; public List PinCollections { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/Nodes/NodeScriptEntity.cs b/src/Artemis.Storage/Entities/Profile/Nodes/NodeScriptEntity.cs index 0ca825e70..ac53e8494 100644 --- a/src/Artemis.Storage/Entities/Profile/Nodes/NodeScriptEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/Nodes/NodeScriptEntity.cs @@ -10,8 +10,8 @@ public class NodeScriptEntity Connections = new List(); } - public string Name { get; set; } - public string Description { get; set; } + public string Name { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; public List Nodes { get; set; } public List Connections { get; set; } diff --git a/src/Artemis.Storage/Entities/Profile/ProfileCategoryEntity.cs b/src/Artemis.Storage/Entities/Profile/ProfileCategoryEntity.cs index 8dfebeb96..126845b38 100644 --- a/src/Artemis.Storage/Entities/Profile/ProfileCategoryEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/ProfileCategoryEntity.cs @@ -7,7 +7,7 @@ public class ProfileCategoryEntity { public Guid Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } = string.Empty; public bool IsCollapsed { get; set; } public bool IsSuspended { get; set; } public int Order { get; set; } diff --git a/src/Artemis.Storage/Entities/Profile/ProfileConfigurationEntity.cs b/src/Artemis.Storage/Entities/Profile/ProfileConfigurationEntity.cs index 276b6ec8d..17f94580b 100644 --- a/src/Artemis.Storage/Entities/Profile/ProfileConfigurationEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/ProfileConfigurationEntity.cs @@ -5,8 +5,8 @@ namespace Artemis.Storage.Entities.Profile; public class ProfileConfigurationEntity { - public string Name { get; set; } - public string MaterialIcon { get; set; } + public string Name { get; set; } = string.Empty; + public string? MaterialIcon { get; set; } public Guid FileIconId { get; set; } public int IconType { get; set; } public bool IconFill { get; set; } @@ -14,13 +14,13 @@ public class ProfileConfigurationEntity public bool IsSuspended { get; set; } public int ActivationBehaviour { get; set; } - public NodeScriptEntity ActivationCondition { get; set; } + public NodeScriptEntity? ActivationCondition { get; set; } public int HotkeyMode { get; set; } - public ProfileConfigurationHotkeyEntity EnableHotkey { get; set; } - public ProfileConfigurationHotkeyEntity DisableHotkey { get; set; } + public ProfileConfigurationHotkeyEntity? EnableHotkey { get; set; } + public ProfileConfigurationHotkeyEntity? DisableHotkey { get; set; } - public string ModuleId { get; set; } + public string? ModuleId { get; set; } public Guid ProfileCategoryId { get; set; } public Guid ProfileId { get; set; } diff --git a/src/Artemis.Storage/Entities/Profile/ProfileEntity.cs b/src/Artemis.Storage/Entities/Profile/ProfileEntity.cs index da5bbb903..ba4e57720 100644 --- a/src/Artemis.Storage/Entities/Profile/ProfileEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/ProfileEntity.cs @@ -16,7 +16,7 @@ public class ProfileEntity public Guid Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } = string.Empty; public bool IsFreshImport { get; set; } public List Folders { get; set; } @@ -28,7 +28,7 @@ public class ProfileEntity Guid oldGuid = Id; Id = guid; - FolderEntity rootFolder = Folders.FirstOrDefault(f => f.ParentId == oldGuid); + FolderEntity? rootFolder = Folders.FirstOrDefault(f => f.ParentId == oldGuid); if (rootFolder != null) rootFolder.ParentId = Id; } diff --git a/src/Artemis.Storage/Entities/Profile/PropertyEntity.cs b/src/Artemis.Storage/Entities/Profile/PropertyEntity.cs index 21036efcc..3b4f8e833 100644 --- a/src/Artemis.Storage/Entities/Profile/PropertyEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/PropertyEntity.cs @@ -5,10 +5,10 @@ namespace Artemis.Storage.Entities.Profile; public class PropertyEntity { - public string Identifier { get; set; } - public string Value { get; set; } + public string Identifier { get; set; } = string.Empty; + public string Value { get; set; } = string.Empty; public bool KeyframesEnabled { get; set; } - public DataBindingEntity DataBinding { get; set; } + public DataBindingEntity? DataBinding { get; set; } public List KeyframeEntities { get; set; } = new(); } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/PropertyGroupEntity.cs b/src/Artemis.Storage/Entities/Profile/PropertyGroupEntity.cs index 3f4825782..e01047ee3 100644 --- a/src/Artemis.Storage/Entities/Profile/PropertyGroupEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/PropertyGroupEntity.cs @@ -4,7 +4,7 @@ namespace Artemis.Storage.Entities.Profile; public class PropertyGroupEntity { - public string Identifier { get; set; } + public string Identifier { get; set; } = string.Empty; public List Properties { get; set; } = new(); public List PropertyGroups { get; set; } = new(); } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Surface/DeviceEntity.cs b/src/Artemis.Storage/Entities/Surface/DeviceEntity.cs index b19e38c03..5075131c2 100644 --- a/src/Artemis.Storage/Entities/Surface/DeviceEntity.cs +++ b/src/Artemis.Storage/Entities/Surface/DeviceEntity.cs @@ -11,8 +11,8 @@ public class DeviceEntity Categories = new List(); } - public string Id { get; set; } - public string DeviceProvider { get; set; } + public string Id { get; set; } = string.Empty; + public string DeviceProvider { get; set; } = string.Empty; public float X { get; set; } public float Y { get; set; } public float Rotation { get; set; } @@ -24,9 +24,9 @@ public class DeviceEntity public bool IsEnabled { get; set; } public int PhysicalLayout { get; set; } - public string LogicalLayout { get; set; } - public string LayoutType { get; set; } - public string LayoutParameter { get; set; } + public string? LogicalLayout { get; set; } + public string? LayoutType { get; set; } + public string? LayoutParameter { get; set; } public List InputIdentifiers { get; set; } public List InputMappings { get; set; } @@ -41,6 +41,6 @@ public class InputMappingEntity public class DeviceInputIdentifierEntity { - public string InputProvider { get; set; } - public object Identifier { get; set; } + public string InputProvider { get; set; } = string.Empty; + public object Identifier { get; set; } = string.Empty; } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Workshop/EntryEntity.cs b/src/Artemis.Storage/Entities/Workshop/EntryEntity.cs index e2acf7922..4be84d9e8 100644 --- a/src/Artemis.Storage/Entities/Workshop/EntryEntity.cs +++ b/src/Artemis.Storage/Entities/Workshop/EntryEntity.cs @@ -10,13 +10,12 @@ public class EntryEntity public long EntryId { get; set; } public int EntryType { get; set; } - public string Author { get; set; } + public string Author { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; - public string Summary { get; set; } = string.Empty; public long ReleaseId { get; set; } - public string ReleaseVersion { get; set; } + public string ReleaseVersion { get; set; } = string.Empty; public DateTimeOffset InstalledAt { get; set; } - public Dictionary Metadata { get; set; } + public Dictionary? Metadata { get; set; } } \ No newline at end of file diff --git a/src/Artemis.Storage/Migrations/IProfileMigration.cs b/src/Artemis.Storage/Migrations/IProfileMigration.cs new file mode 100644 index 000000000..d48cab32b --- /dev/null +++ b/src/Artemis.Storage/Migrations/IProfileMigration.cs @@ -0,0 +1,11 @@ +using LiteDB; +using Newtonsoft.Json.Linq; + +namespace Artemis.Storage.Migrations; + +internal interface IProfileMigration +{ + int Version { get; } + void Migrate(JObject profileJson); + void Migrate(BsonDocument profileBson); +} \ No newline at end of file diff --git a/src/Artemis.Storage/Migrations/Interfaces/IStorageMigration.cs b/src/Artemis.Storage/Migrations/IStorageMigration.cs similarity index 100% rename from src/Artemis.Storage/Migrations/Interfaces/IStorageMigration.cs rename to src/Artemis.Storage/Migrations/IStorageMigration.cs diff --git a/src/Artemis.Storage/Migrations/Profile/M0001NodeProviders.cs b/src/Artemis.Storage/Migrations/Profile/M0001NodeProviders.cs new file mode 100644 index 000000000..9e8f62f1f --- /dev/null +++ b/src/Artemis.Storage/Migrations/Profile/M0001NodeProviders.cs @@ -0,0 +1,97 @@ +using LiteDB; +using Newtonsoft.Json.Linq; + +namespace Artemis.Storage.Migrations.Profile; + +/// +/// Migrates nodes to be provider-based. +/// This requires giving them a ProviderId and updating the their namespaces to match the namespace of the new plugin. +/// +internal class M0001NodeProviders : IProfileMigration +{ + /// + public int Version => 1; + + /// + public void Migrate(JObject profileJson) + { + JArray? folders = (JArray?) profileJson["Folders"]?["$values"]; + JArray? layers = (JArray?) profileJson["Layers"]?["$values"]; + + if (folders != null) + { + foreach (JToken folder in folders) + { + MigrateProfileElement(folder); + } + } + + if (layers != null) + { + foreach (JToken layer in layers) + { + MigrateProfileElement(layer); + MigratePropertyGroup(layer["GeneralPropertyGroup"]); + MigratePropertyGroup(layer["TransformPropertyGroup"]); + MigratePropertyGroup(layer["LayerBrush"]?["PropertyGroup"]); + } + } + } + + /// + public void Migrate(BsonDocument profileBson) + { + throw new System.NotImplementedException(); + } + + private void MigrateProfileElement(JToken profileElement) + { + JArray? layerEffects = (JArray?) profileElement["LayerEffects"]?["$values"]; + if (layerEffects != null) + { + foreach (JToken layerEffect in layerEffects) + MigratePropertyGroup(layerEffect["PropertyGroup"]); + } + + JToken? displayCondition = profileElement["DisplayCondition"]; + if (displayCondition != null) + MigrateNodeScript(displayCondition["Script"]); + } + + private void MigratePropertyGroup(JToken? propertyGroup) + { + if (propertyGroup == null || !propertyGroup.HasValues) + return; + + JArray? properties = (JArray?) propertyGroup["Properties"]?["$values"]; + JArray? propertyGroups = (JArray?) propertyGroup["PropertyGroups"]?["$values"]; + + if (properties != null) + { + foreach (JToken property in properties) + MigrateNodeScript(property["DataBinding"]?["NodeScript"]); + } + + if (propertyGroups != null) + { + foreach (JToken childPropertyGroup in propertyGroups) + MigratePropertyGroup(childPropertyGroup); + } + } + + private void MigrateNodeScript(JToken? nodeScript) + { + if (nodeScript == null || !nodeScript.HasValues) + return; + + JArray? nodes = (JArray?) nodeScript["Nodes"]?["$values"]; + if (nodes == null) + return; + + foreach (JToken node in nodes) + { + node["Type"] = node["Type"]?.Value()?.Replace("Artemis.VisualScripting.Nodes", "Artemis.Plugins.Nodes.General.Nodes"); + node["ProviderId"] = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78"; + } + } +} \ No newline at end of file diff --git a/src/Artemis.Storage/Migrations/M0020AvaloniaReset.cs b/src/Artemis.Storage/Migrations/Storage/M0020AvaloniaReset.cs similarity index 100% rename from src/Artemis.Storage/Migrations/M0020AvaloniaReset.cs rename to src/Artemis.Storage/Migrations/Storage/M0020AvaloniaReset.cs diff --git a/src/Artemis.Storage/Migrations/M0021GradientNodes.cs b/src/Artemis.Storage/Migrations/Storage/M0021GradientNodes.cs similarity index 87% rename from src/Artemis.Storage/Migrations/M0021GradientNodes.cs rename to src/Artemis.Storage/Migrations/Storage/M0021GradientNodes.cs index dba1e8956..a6ebcac3e 100644 --- a/src/Artemis.Storage/Migrations/M0021GradientNodes.cs +++ b/src/Artemis.Storage/Migrations/Storage/M0021GradientNodes.cs @@ -12,9 +12,9 @@ public class M0021GradientNodes : IStorageMigration { private void MigrateDataBinding(PropertyEntity property) { - NodeScriptEntity script = property.DataBinding.NodeScript; - NodeEntity exitNode = script.Nodes.FirstOrDefault(s => s.IsExitNode); - if (exitNode == null) + NodeScriptEntity? script = property.DataBinding?.NodeScript; + NodeEntity? exitNode = script?.Nodes.FirstOrDefault(s => s.IsExitNode); + if (script == null || exitNode == null) return; // Create a new node at the same position of the exit node @@ -59,8 +59,11 @@ public class M0021GradientNodes : IStorageMigration exitNode.Y += 30; } - private void MigrateDataBinding(PropertyGroupEntity propertyGroup) + private void MigrateDataBinding(PropertyGroupEntity? propertyGroup) { + if (propertyGroup == null) + return; + foreach (PropertyGroupEntity propertyGroupPropertyGroup in propertyGroup.PropertyGroups) MigrateDataBinding(propertyGroupPropertyGroup); @@ -80,7 +83,7 @@ public class M0021GradientNodes : IStorageMigration foreach (ProfileEntity profileEntity in profiles) { foreach (LayerEntity layer in profileEntity.Layers.Where(le => le.LayerBrush != null)) - MigrateDataBinding(layer.LayerBrush.PropertyGroup); + MigrateDataBinding(layer.LayerBrush?.PropertyGroup); repository.Update(profileEntity); } diff --git a/src/Artemis.Storage/Migrations/M0022TransitionNodes.cs b/src/Artemis.Storage/Migrations/Storage/M0022TransitionNodes.cs similarity index 89% rename from src/Artemis.Storage/Migrations/M0022TransitionNodes.cs rename to src/Artemis.Storage/Migrations/Storage/M0022TransitionNodes.cs index 3258a6d10..6256c097d 100644 --- a/src/Artemis.Storage/Migrations/M0022TransitionNodes.cs +++ b/src/Artemis.Storage/Migrations/Storage/M0022TransitionNodes.cs @@ -10,7 +10,7 @@ namespace Artemis.Storage.Migrations; public class M0022TransitionNodes : IStorageMigration { - private void MigrateNodeScript(NodeScriptEntity nodeScript) + private void MigrateNodeScript(NodeScriptEntity? nodeScript) { if (nodeScript == null) return; @@ -28,7 +28,7 @@ public class M0022TransitionNodes : IStorageMigration } } - private void MigratePropertyGroup(PropertyGroupEntity propertyGroup) + private void MigratePropertyGroup(PropertyGroupEntity? propertyGroup) { if (propertyGroup == null) return; @@ -39,7 +39,7 @@ public class M0022TransitionNodes : IStorageMigration MigrateNodeScript(property.DataBinding?.NodeScript); } - private void MigrateDisplayCondition(IConditionEntity conditionEntity) + private void MigrateDisplayCondition(IConditionEntity? conditionEntity) { if (conditionEntity is EventConditionEntity eventConditionEntity) MigrateNodeScript(eventConditionEntity.Script); @@ -70,14 +70,14 @@ public class M0022TransitionNodes : IStorageMigration MigratePropertyGroup(layer.GeneralPropertyGroup); MigratePropertyGroup(layer.TransformPropertyGroup); foreach (LayerEffectEntity layerEffectEntity in layer.LayerEffects) - MigratePropertyGroup(layerEffectEntity?.PropertyGroup); + MigratePropertyGroup(layerEffectEntity.PropertyGroup); MigrateDisplayCondition(layer.DisplayCondition); } foreach (FolderEntity folder in profileEntity.Folders) { foreach (LayerEffectEntity folderLayerEffect in folder.LayerEffects) - MigratePropertyGroup(folderLayerEffect?.PropertyGroup); + MigratePropertyGroup(folderLayerEffect.PropertyGroup); MigrateDisplayCondition(folder.DisplayCondition); } diff --git a/src/Artemis.Storage/Migrations/M0023LayoutProviders.cs b/src/Artemis.Storage/Migrations/Storage/M0023LayoutProviders.cs similarity index 100% rename from src/Artemis.Storage/Migrations/M0023LayoutProviders.cs rename to src/Artemis.Storage/Migrations/Storage/M0023LayoutProviders.cs diff --git a/src/Artemis.Storage/Repositories/DeviceRepository.cs b/src/Artemis.Storage/Repositories/DeviceRepository.cs index 722d85626..47a947333 100644 --- a/src/Artemis.Storage/Repositories/DeviceRepository.cs +++ b/src/Artemis.Storage/Repositories/DeviceRepository.cs @@ -25,7 +25,7 @@ internal class DeviceRepository : IDeviceRepository _repository.Delete(deviceEntity.Id); } - public DeviceEntity Get(string id) + public DeviceEntity? Get(string id) { return _repository.FirstOrDefault(s => s.Id == id); } diff --git a/src/Artemis.Storage/Repositories/EntryRepository.cs b/src/Artemis.Storage/Repositories/EntryRepository.cs index 61d3da672..81775f967 100644 --- a/src/Artemis.Storage/Repositories/EntryRepository.cs +++ b/src/Artemis.Storage/Repositories/EntryRepository.cs @@ -27,12 +27,12 @@ internal class EntryRepository : IEntryRepository _repository.Delete(entryEntity.Id); } - public EntryEntity Get(Guid id) + public EntryEntity? Get(Guid id) { return _repository.FirstOrDefault(s => s.Id == id); } - public EntryEntity GetByEntryId(long entryId) + public EntryEntity? GetByEntryId(long entryId) { return _repository.FirstOrDefault(s => s.EntryId == entryId); } diff --git a/src/Artemis.Storage/Repositories/Interfaces/IDeviceRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IDeviceRepository.cs index 1cfa237f5..50fd1df86 100644 --- a/src/Artemis.Storage/Repositories/Interfaces/IDeviceRepository.cs +++ b/src/Artemis.Storage/Repositories/Interfaces/IDeviceRepository.cs @@ -7,7 +7,7 @@ public interface IDeviceRepository : IRepository { void Add(DeviceEntity deviceEntity); void Remove(DeviceEntity deviceEntity); - DeviceEntity Get(string id); + DeviceEntity? Get(string id); List GetAll(); void Save(DeviceEntity deviceEntity); void Save(IEnumerable deviceEntities); diff --git a/src/Artemis.Storage/Repositories/Interfaces/IEntryRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IEntryRepository.cs index 1e9ecd1c5..59d610f95 100644 --- a/src/Artemis.Storage/Repositories/Interfaces/IEntryRepository.cs +++ b/src/Artemis.Storage/Repositories/Interfaces/IEntryRepository.cs @@ -8,8 +8,8 @@ public interface IEntryRepository : IRepository { void Add(EntryEntity entryEntity); void Remove(EntryEntity entryEntity); - EntryEntity Get(Guid id); - EntryEntity GetByEntryId(long entryId); + EntryEntity? Get(Guid id); + EntryEntity? GetByEntryId(long entryId); List GetAll(); void Save(EntryEntity entryEntity); void Save(IEnumerable entryEntities); diff --git a/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs index 12a9c797b..c180ee33f 100644 --- a/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs +++ b/src/Artemis.Storage/Repositories/Interfaces/IPluginRepository.cs @@ -6,12 +6,12 @@ namespace Artemis.Storage.Repositories.Interfaces; public interface IPluginRepository : IRepository { void AddPlugin(PluginEntity pluginEntity); - PluginEntity GetPluginByGuid(Guid pluginGuid); + PluginEntity? GetPluginByGuid(Guid pluginGuid); void SavePlugin(PluginEntity pluginEntity); void AddSetting(PluginSettingEntity pluginSettingEntity); - PluginSettingEntity GetSettingByGuid(Guid pluginGuid); - PluginSettingEntity GetSettingByNameAndGuid(string name, Guid pluginGuid); + PluginSettingEntity? GetSettingByGuid(Guid pluginGuid); + PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid); void SaveSetting(PluginSettingEntity pluginSettingEntity); void RemoveSettings(Guid pluginGuid); } \ No newline at end of file diff --git a/src/Artemis.Storage/Repositories/Interfaces/IProfileCategoryRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IProfileCategoryRepository.cs index bdb1b93cd..878040e2c 100644 --- a/src/Artemis.Storage/Repositories/Interfaces/IProfileCategoryRepository.cs +++ b/src/Artemis.Storage/Repositories/Interfaces/IProfileCategoryRepository.cs @@ -10,8 +10,8 @@ public interface IProfileCategoryRepository : IRepository void Add(ProfileCategoryEntity profileCategoryEntity); void Remove(ProfileCategoryEntity profileCategoryEntity); List GetAll(); - ProfileCategoryEntity Get(Guid id); - Stream GetProfileIconStream(Guid id); + ProfileCategoryEntity? Get(Guid id); + Stream? GetProfileIconStream(Guid id); void SaveProfileIconStream(ProfileConfigurationEntity profileConfigurationEntity, Stream stream); ProfileCategoryEntity IsUnique(string name, Guid? id); void Save(ProfileCategoryEntity profileCategoryEntity); diff --git a/src/Artemis.Storage/Repositories/Interfaces/IProfileRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IProfileRepository.cs index 155bef645..8430b82c4 100644 --- a/src/Artemis.Storage/Repositories/Interfaces/IProfileRepository.cs +++ b/src/Artemis.Storage/Repositories/Interfaces/IProfileRepository.cs @@ -9,6 +9,6 @@ public interface IProfileRepository : IRepository void Add(ProfileEntity profileEntity); void Remove(ProfileEntity profileEntity); List GetAll(); - ProfileEntity Get(Guid id); + ProfileEntity? Get(Guid id); void Save(ProfileEntity profileEntity); } \ No newline at end of file diff --git a/src/Artemis.Storage/Repositories/Interfaces/IRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IRepository.cs index 3220cae2e..cd3328434 100644 --- a/src/Artemis.Storage/Repositories/Interfaces/IRepository.cs +++ b/src/Artemis.Storage/Repositories/Interfaces/IRepository.cs @@ -1,5 +1,3 @@ namespace Artemis.Storage.Repositories.Interfaces; -public interface IRepository -{ -} \ No newline at end of file +public interface IRepository; \ No newline at end of file diff --git a/src/Artemis.Storage/Repositories/PluginRepository.cs b/src/Artemis.Storage/Repositories/PluginRepository.cs index 6d659af47..9c278b607 100644 --- a/src/Artemis.Storage/Repositories/PluginRepository.cs +++ b/src/Artemis.Storage/Repositories/PluginRepository.cs @@ -21,7 +21,7 @@ internal class PluginRepository : IPluginRepository _repository.Insert(pluginEntity); } - public PluginEntity GetPluginByGuid(Guid pluginGuid) + public PluginEntity? GetPluginByGuid(Guid pluginGuid) { return _repository.FirstOrDefault(p => p.Id == pluginGuid); } @@ -37,12 +37,12 @@ internal class PluginRepository : IPluginRepository _repository.Insert(pluginSettingEntity); } - public PluginSettingEntity GetSettingByGuid(Guid pluginGuid) + public PluginSettingEntity? GetSettingByGuid(Guid pluginGuid) { return _repository.FirstOrDefault(p => p.PluginGuid == pluginGuid); } - public PluginSettingEntity GetSettingByNameAndGuid(string name, Guid pluginGuid) + public PluginSettingEntity? GetSettingByNameAndGuid(string name, Guid pluginGuid) { return _repository.FirstOrDefault(p => p.Name == name && p.PluginGuid == pluginGuid); } diff --git a/src/Artemis.Storage/Repositories/ProfileCategoryRepository.cs b/src/Artemis.Storage/Repositories/ProfileCategoryRepository.cs index 71517929f..8e1f44ecf 100644 --- a/src/Artemis.Storage/Repositories/ProfileCategoryRepository.cs +++ b/src/Artemis.Storage/Repositories/ProfileCategoryRepository.cs @@ -34,7 +34,7 @@ internal class ProfileCategoryRepository : IProfileCategoryRepository return _repository.Query().ToList(); } - public ProfileCategoryEntity Get(Guid id) + public ProfileCategoryEntity? Get(Guid id) { return _repository.FirstOrDefault(p => p.Id == id); } @@ -52,7 +52,7 @@ internal class ProfileCategoryRepository : IProfileCategoryRepository _repository.Upsert(profileCategoryEntity); } - public Stream GetProfileIconStream(Guid id) + public Stream? GetProfileIconStream(Guid id) { if (!_profileIcons.Exists(id)) return null; diff --git a/src/Artemis.Storage/Repositories/ProfileRepository.cs b/src/Artemis.Storage/Repositories/ProfileRepository.cs index a890f2ee0..738099a32 100644 --- a/src/Artemis.Storage/Repositories/ProfileRepository.cs +++ b/src/Artemis.Storage/Repositories/ProfileRepository.cs @@ -31,7 +31,7 @@ internal class ProfileRepository : IProfileRepository return _repository.Query().ToList(); } - public ProfileEntity Get(Guid id) + public ProfileEntity? Get(Guid id) { return _repository.FirstOrDefault(p => p.Id == id); } From 313b4a0deaebdde295e76ccaef8450554c977555 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 23 Feb 2024 17:41:11 +0100 Subject: [PATCH 10/12] Core - Fix node related warnings --- src/Artemis.Core/Plugins/Nodes/NodeProvider.cs | 5 +++++ src/Artemis.Core/VisualScripting/Interfaces/INode.cs | 2 +- src/Artemis.Core/VisualScripting/NodeData.cs | 2 -- src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs | 4 ++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Artemis.Core/Plugins/Nodes/NodeProvider.cs b/src/Artemis.Core/Plugins/Nodes/NodeProvider.cs index 64acd5612..24506297e 100644 --- a/src/Artemis.Core/Plugins/Nodes/NodeProvider.cs +++ b/src/Artemis.Core/Plugins/Nodes/NodeProvider.cs @@ -63,6 +63,11 @@ public abstract class NodeProvider : PluginFeature NodeTypeStore.Add(nodeData); } + /// + /// Adds a color for lines of the provided type. + /// + /// The color to add. + /// The type to use the color for. protected TypeColorRegistration RegisterTypeColor(SKColor color) { return NodeTypeStore.AddColor(typeof(T), color, this); diff --git a/src/Artemis.Core/VisualScripting/Interfaces/INode.cs b/src/Artemis.Core/VisualScripting/Interfaces/INode.cs index abe7ecedd..98e1e31ac 100644 --- a/src/Artemis.Core/VisualScripting/Interfaces/INode.cs +++ b/src/Artemis.Core/VisualScripting/Interfaces/INode.cs @@ -18,7 +18,7 @@ public interface INode : INotifyPropertyChanged, IBreakableModel /// /// Gets /// - NodeData? NodeData { get; set; } + NodeData NodeData { get; set; } /// /// Gets the name of the node diff --git a/src/Artemis.Core/VisualScripting/NodeData.cs b/src/Artemis.Core/VisualScripting/NodeData.cs index 05359dba0..dff2a5a2d 100644 --- a/src/Artemis.Core/VisualScripting/NodeData.cs +++ b/src/Artemis.Core/VisualScripting/NodeData.cs @@ -149,7 +149,5 @@ public class NodeData /// public Type? OutputType { get; } - private readonly Func _create; - #endregion } \ No newline at end of file diff --git a/src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs b/src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs index a321f3f2e..cec7d2601 100644 --- a/src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs +++ b/src/Artemis.Storage/Entities/Profile/Nodes/NodeEntity.cs @@ -28,8 +28,8 @@ public class NodeEntity } public Guid Id { get; set; } - public string Type { get; set; } - public string ProviderId { get; set; } + public string Type { get; set; } = string.Empty; + public string ProviderId { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; From 49ed0205b7223c41808e67fce03c37ba7045f4e4 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 23 Feb 2024 20:58:32 +0100 Subject: [PATCH 11/12] Move migrations to storage, add Storage migration for nodes change --- .../DryIoc/ContainerExtensions.cs | 4 +- .../Storage/Interfaces/IProfileMigration.cs | 9 -- .../ProfileMigrators/M0001NodeProviders.cs | 90 ---------------- .../Services/Storage/ProfileService.cs | 5 +- .../Migrations/IProfileMigration.cs | 4 +- .../Migrations/IStorageMigration.cs | 2 +- .../Migrations/Profile/M0001NodeProviders.cs | 9 -- .../Migrations/Storage/M0020AvaloniaReset.cs | 3 +- .../Migrations/Storage/M0021GradientNodes.cs | 3 +- .../Storage/M0022TransitionNodes.cs | 3 +- .../Storage/M0023LayoutProviders.cs | 3 +- .../Migrations/Storage/M0024NodeProviders.cs | 100 ++++++++++++++++++ .../StorageMigrationService.cs | 2 +- 13 files changed, 112 insertions(+), 125 deletions(-) delete mode 100644 src/Artemis.Core/Services/Storage/Interfaces/IProfileMigration.cs delete mode 100644 src/Artemis.Core/Services/Storage/ProfileMigrators/M0001NodeProviders.cs create mode 100644 src/Artemis.Storage/Migrations/Storage/M0024NodeProviders.cs diff --git a/src/Artemis.Core/DryIoc/ContainerExtensions.cs b/src/Artemis.Core/DryIoc/ContainerExtensions.cs index 337fb1def..8aa35b65f 100644 --- a/src/Artemis.Core/DryIoc/ContainerExtensions.cs +++ b/src/Artemis.Core/DryIoc/ContainerExtensions.cs @@ -5,7 +5,7 @@ using Artemis.Core.DryIoc.Factories; using Artemis.Core.Providers; using Artemis.Core.Services; using Artemis.Storage; -using Artemis.Storage.Migrations.Interfaces; +using Artemis.Storage.Migrations; using Artemis.Storage.Repositories.Interfaces; using DryIoc; @@ -36,7 +36,7 @@ public static class ContainerExtensions // Bind migrations container.RegisterMany(storageAssembly, type => type.IsAssignableTo(), Reuse.Singleton, nonPublicServiceTypes: true); - container.RegisterMany(coreAssembly, type => type.IsAssignableTo(), Reuse.Singleton, nonPublicServiceTypes: true); + container.RegisterMany(storageAssembly, type => type.IsAssignableTo(), Reuse.Singleton, nonPublicServiceTypes: true); container.RegisterMany(coreAssembly, type => type.IsAssignableTo(), Reuse.Singleton); container.Register(Reuse.Singleton); diff --git a/src/Artemis.Core/Services/Storage/Interfaces/IProfileMigration.cs b/src/Artemis.Core/Services/Storage/Interfaces/IProfileMigration.cs deleted file mode 100644 index 7365014e8..000000000 --- a/src/Artemis.Core/Services/Storage/Interfaces/IProfileMigration.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json.Linq; - -namespace Artemis.Core.Services; - -internal interface IProfileMigration -{ - int Version { get; } - void Migrate(JObject profileJson); -} \ No newline at end of file diff --git a/src/Artemis.Core/Services/Storage/ProfileMigrators/M0001NodeProviders.cs b/src/Artemis.Core/Services/Storage/ProfileMigrators/M0001NodeProviders.cs deleted file mode 100644 index c55fde0a9..000000000 --- a/src/Artemis.Core/Services/Storage/ProfileMigrators/M0001NodeProviders.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Newtonsoft.Json.Linq; - -namespace Artemis.Core.Services.ProfileMigrators; - -/// -/// Migrates nodes to be provider-based. -/// This requires giving them a ProviderId and updating the their namespaces to match the namespace of the new plugin. -/// -internal class M0001NodeProviders : IProfileMigration -{ - /// - public int Version => 1; - - /// - public void Migrate(JObject profileJson) - { - JArray? folders = (JArray?) profileJson["Folders"]?["$values"]; - JArray? layers = (JArray?) profileJson["Layers"]?["$values"]; - - if (folders != null) - { - foreach (JToken folder in folders) - { - MigrateProfileElement(folder); - } - } - - if (layers != null) - { - foreach (JToken layer in layers) - { - MigrateProfileElement(layer); - MigratePropertyGroup(layer["GeneralPropertyGroup"]); - MigratePropertyGroup(layer["TransformPropertyGroup"]); - MigratePropertyGroup(layer["LayerBrush"]?["PropertyGroup"]); - } - } - } - - private void MigrateProfileElement(JToken profileElement) - { - JArray? layerEffects = (JArray?) profileElement["LayerEffects"]?["$values"]; - if (layerEffects != null) - { - foreach (JToken layerEffect in layerEffects) - MigratePropertyGroup(layerEffect["PropertyGroup"]); - } - - JToken? displayCondition = profileElement["DisplayCondition"]; - if (displayCondition != null) - MigrateNodeScript(displayCondition["Script"]); - } - - private void MigratePropertyGroup(JToken? propertyGroup) - { - if (propertyGroup == null || !propertyGroup.HasValues) - return; - - JArray? properties = (JArray?) propertyGroup["Properties"]?["$values"]; - JArray? propertyGroups = (JArray?) propertyGroup["PropertyGroups"]?["$values"]; - - if (properties != null) - { - foreach (JToken property in properties) - MigrateNodeScript(property["DataBinding"]?["NodeScript"]); - } - - if (propertyGroups != null) - { - foreach (JToken childPropertyGroup in propertyGroups) - MigratePropertyGroup(childPropertyGroup); - } - } - - private void MigrateNodeScript(JToken? nodeScript) - { - if (nodeScript == null || !nodeScript.HasValues) - return; - - JArray? nodes = (JArray?) nodeScript["Nodes"]?["$values"]; - if (nodes == null) - return; - - foreach (JToken node in nodes) - { - node["Type"] = node["Type"]?.Value()?.Replace("Artemis.VisualScripting.Nodes", "Artemis.Plugins.Nodes.General.Nodes"); - node["ProviderId"] = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78"; - } - } -} \ No newline at end of file diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs index e49230003..90b25ea5f 100644 --- a/src/Artemis.Core/Services/Storage/ProfileService.cs +++ b/src/Artemis.Core/Services/Storage/ProfileService.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading.Tasks; using Artemis.Core.Modules; using Artemis.Storage.Entities.Profile; +using Artemis.Storage.Migrations; using Artemis.Storage.Repositories.Interfaces; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -523,10 +524,10 @@ internal class ProfileService : IProfileService public async Task OverwriteProfile(MemoryStream archiveStream, ProfileConfiguration profileConfiguration) { ProfileConfiguration imported = await ImportProfile(archiveStream, profileConfiguration.Category, true, true, null, profileConfiguration.Order + 1); - + DeleteProfile(profileConfiguration); SaveProfileCategory(imported.Category); - + return imported; } diff --git a/src/Artemis.Storage/Migrations/IProfileMigration.cs b/src/Artemis.Storage/Migrations/IProfileMigration.cs index d48cab32b..1bb41c022 100644 --- a/src/Artemis.Storage/Migrations/IProfileMigration.cs +++ b/src/Artemis.Storage/Migrations/IProfileMigration.cs @@ -1,11 +1,9 @@ -using LiteDB; using Newtonsoft.Json.Linq; namespace Artemis.Storage.Migrations; -internal interface IProfileMigration +public interface IProfileMigration { int Version { get; } void Migrate(JObject profileJson); - void Migrate(BsonDocument profileBson); } \ No newline at end of file diff --git a/src/Artemis.Storage/Migrations/IStorageMigration.cs b/src/Artemis.Storage/Migrations/IStorageMigration.cs index dbee4bcba..4382a837d 100644 --- a/src/Artemis.Storage/Migrations/IStorageMigration.cs +++ b/src/Artemis.Storage/Migrations/IStorageMigration.cs @@ -1,6 +1,6 @@ using LiteDB; -namespace Artemis.Storage.Migrations.Interfaces; +namespace Artemis.Storage.Migrations; public interface IStorageMigration { diff --git a/src/Artemis.Storage/Migrations/Profile/M0001NodeProviders.cs b/src/Artemis.Storage/Migrations/Profile/M0001NodeProviders.cs index 9e8f62f1f..0dfab33a2 100644 --- a/src/Artemis.Storage/Migrations/Profile/M0001NodeProviders.cs +++ b/src/Artemis.Storage/Migrations/Profile/M0001NodeProviders.cs @@ -1,4 +1,3 @@ -using LiteDB; using Newtonsoft.Json.Linq; namespace Artemis.Storage.Migrations.Profile; @@ -21,9 +20,7 @@ internal class M0001NodeProviders : IProfileMigration if (folders != null) { foreach (JToken folder in folders) - { MigrateProfileElement(folder); - } } if (layers != null) @@ -38,12 +35,6 @@ internal class M0001NodeProviders : IProfileMigration } } - /// - public void Migrate(BsonDocument profileBson) - { - throw new System.NotImplementedException(); - } - private void MigrateProfileElement(JToken profileElement) { JArray? layerEffects = (JArray?) profileElement["LayerEffects"]?["$values"]; diff --git a/src/Artemis.Storage/Migrations/Storage/M0020AvaloniaReset.cs b/src/Artemis.Storage/Migrations/Storage/M0020AvaloniaReset.cs index 741ba35b0..293fc1ff7 100644 --- a/src/Artemis.Storage/Migrations/Storage/M0020AvaloniaReset.cs +++ b/src/Artemis.Storage/Migrations/Storage/M0020AvaloniaReset.cs @@ -1,9 +1,8 @@ using System.Collections.Generic; using System.Linq; -using Artemis.Storage.Migrations.Interfaces; using LiteDB; -namespace Artemis.Storage.Migrations; +namespace Artemis.Storage.Migrations.Storage; public class M0020AvaloniaReset : IStorageMigration { diff --git a/src/Artemis.Storage/Migrations/Storage/M0021GradientNodes.cs b/src/Artemis.Storage/Migrations/Storage/M0021GradientNodes.cs index b41e7a983..2bb90a45c 100644 --- a/src/Artemis.Storage/Migrations/Storage/M0021GradientNodes.cs +++ b/src/Artemis.Storage/Migrations/Storage/M0021GradientNodes.cs @@ -3,10 +3,9 @@ using System.Collections.Generic; using System.Linq; using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile.Nodes; -using Artemis.Storage.Migrations.Interfaces; using LiteDB; -namespace Artemis.Storage.Migrations; +namespace Artemis.Storage.Migrations.Storage; public class M0021GradientNodes : IStorageMigration { diff --git a/src/Artemis.Storage/Migrations/Storage/M0022TransitionNodes.cs b/src/Artemis.Storage/Migrations/Storage/M0022TransitionNodes.cs index 6256c097d..791b95ea9 100644 --- a/src/Artemis.Storage/Migrations/Storage/M0022TransitionNodes.cs +++ b/src/Artemis.Storage/Migrations/Storage/M0022TransitionNodes.cs @@ -3,10 +3,9 @@ using Artemis.Storage.Entities.Profile; using Artemis.Storage.Entities.Profile.Abstract; using Artemis.Storage.Entities.Profile.Conditions; using Artemis.Storage.Entities.Profile.Nodes; -using Artemis.Storage.Migrations.Interfaces; using LiteDB; -namespace Artemis.Storage.Migrations; +namespace Artemis.Storage.Migrations.Storage; public class M0022TransitionNodes : IStorageMigration { diff --git a/src/Artemis.Storage/Migrations/Storage/M0023LayoutProviders.cs b/src/Artemis.Storage/Migrations/Storage/M0023LayoutProviders.cs index 5914b01c2..5296d5842 100644 --- a/src/Artemis.Storage/Migrations/Storage/M0023LayoutProviders.cs +++ b/src/Artemis.Storage/Migrations/Storage/M0023LayoutProviders.cs @@ -1,8 +1,7 @@ using System.Collections.Generic; -using Artemis.Storage.Migrations.Interfaces; using LiteDB; -namespace Artemis.Storage.Migrations; +namespace Artemis.Storage.Migrations.Storage; public class M0023LayoutProviders : IStorageMigration { diff --git a/src/Artemis.Storage/Migrations/Storage/M0024NodeProviders.cs b/src/Artemis.Storage/Migrations/Storage/M0024NodeProviders.cs new file mode 100644 index 000000000..4d0a4211e --- /dev/null +++ b/src/Artemis.Storage/Migrations/Storage/M0024NodeProviders.cs @@ -0,0 +1,100 @@ +using System.Collections.Generic; +using Artemis.Storage.Entities.Profile; +using LiteDB; + +namespace Artemis.Storage.Migrations.Storage; + +public class M0024NodeProviders : IStorageMigration +{ + public int UserVersion => 24; + + public void Apply(LiteRepository repository) + { + List profileCategories = repository.Query().ToList(); + foreach (ProfileCategoryEntity profileCategory in profileCategories) + { + foreach (ProfileConfigurationEntity profileConfigurationEntity in profileCategory.ProfileConfigurations) + { + profileConfigurationEntity.Version = 1; + } + repository.Update(profileCategory); + } + + ILiteCollection collection = repository.Database.GetCollection("ProfileEntity"); + foreach (BsonDocument profileBson in collection.FindAll()) + { + BsonArray? folders = profileBson["Folders"]?.AsArray; + BsonArray? layers = profileBson["Layers"]?.AsArray; + + if (folders != null) + { + foreach (BsonValue folder in folders) + MigrateProfileElement(folder.AsDocument); + } + + if (layers != null) + { + foreach (BsonValue layer in layers) + { + MigrateProfileElement(layer.AsDocument); + MigratePropertyGroup(layer.AsDocument["GeneralPropertyGroup"].AsDocument); + MigratePropertyGroup(layer.AsDocument["TransformPropertyGroup"].AsDocument); + MigratePropertyGroup(layer.AsDocument["LayerBrush"]?["PropertyGroup"].AsDocument); + } + } + + collection.Update(profileBson); + } + } + + private void MigrateProfileElement(BsonDocument profileElement) + { + BsonArray? layerEffects = profileElement["LayerEffects"]?.AsArray; + if (layerEffects != null) + { + foreach (BsonValue layerEffect in layerEffects) + MigratePropertyGroup(layerEffect.AsDocument["PropertyGroup"].AsDocument); + } + + BsonValue? displayCondition = profileElement["DisplayCondition"]; + if (displayCondition != null) + MigrateNodeScript(displayCondition.AsDocument["Script"].AsDocument); + } + + private void MigratePropertyGroup(BsonDocument? propertyGroup) + { + if (propertyGroup == null || propertyGroup.Keys.Count == 0) + return; + + BsonArray? properties = propertyGroup["Properties"]?.AsArray; + BsonArray? propertyGroups = propertyGroup["PropertyGroups"]?.AsArray; + + if (properties != null) + { + foreach (BsonValue property in properties) + MigrateNodeScript(property.AsDocument["DataBinding"]?["NodeScript"]?.AsDocument); + } + + if (propertyGroups != null) + { + foreach (BsonValue childPropertyGroup in propertyGroups) + MigratePropertyGroup(childPropertyGroup.AsDocument); + } + } + + private void MigrateNodeScript(BsonDocument? nodeScript) + { + if (nodeScript == null || nodeScript.Keys.Count == 0) + return; + + BsonArray? nodes = nodeScript["Nodes"]?.AsArray; + if (nodes == null) + return; + + foreach (BsonValue node in nodes) + { + node.AsDocument["Type"] = node.AsDocument["Type"]?.AsString?.Replace("Artemis.VisualScripting.Nodes", "Artemis.Plugins.Nodes.General.Nodes"); + node.AsDocument["ProviderId"] = "Artemis.Plugins.Nodes.General.GeneralNodesProvider-d9e1ee78"; + } + } +} \ No newline at end of file diff --git a/src/Artemis.Storage/StorageMigrationService.cs b/src/Artemis.Storage/StorageMigrationService.cs index 169144e5c..cf728023b 100644 --- a/src/Artemis.Storage/StorageMigrationService.cs +++ b/src/Artemis.Storage/StorageMigrationService.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Artemis.Storage.Migrations.Interfaces; +using Artemis.Storage.Migrations; using LiteDB; using Serilog; From bcf0b74fcc23db59bc5d3c9f5f0c32eaf1cacc70 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 23 Feb 2024 21:15:34 +0100 Subject: [PATCH 12/12] Clean up --- .../VisualScripting/Interfaces/INode.cs | 4 +- .../VisualScripting/Nodes/Node.cs | 2 +- .../Nodes/NodeTStorageTViewModel.cs | 2 + .../Screens/VisualScripting/NodeViewModel.cs | 63 +++++++++---------- 4 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/Artemis.Core/VisualScripting/Interfaces/INode.cs b/src/Artemis.Core/VisualScripting/Interfaces/INode.cs index 98e1e31ac..4ce40a0ab 100644 --- a/src/Artemis.Core/VisualScripting/Interfaces/INode.cs +++ b/src/Artemis.Core/VisualScripting/Interfaces/INode.cs @@ -16,9 +16,9 @@ public interface INode : INotifyPropertyChanged, IBreakableModel Guid Id { get; set; } /// - /// Gets + /// Gets or sets the node data with information about this node /// - NodeData NodeData { get; set; } + NodeData? NodeData { get; set; } /// /// Gets the name of the node diff --git a/src/Artemis.Core/VisualScripting/Nodes/Node.cs b/src/Artemis.Core/VisualScripting/Nodes/Node.cs index 3780e6e07..8d4a40d3d 100644 --- a/src/Artemis.Core/VisualScripting/Nodes/Node.cs +++ b/src/Artemis.Core/VisualScripting/Nodes/Node.cs @@ -42,7 +42,7 @@ public abstract class Node : BreakableModel, INode } /// - public NodeData NodeData { get; set; } + public NodeData? NodeData { get; set; } private string _name; diff --git a/src/Artemis.Core/VisualScripting/Nodes/NodeTStorageTViewModel.cs b/src/Artemis.Core/VisualScripting/Nodes/NodeTStorageTViewModel.cs index 2b84a619e..79e858644 100644 --- a/src/Artemis.Core/VisualScripting/Nodes/NodeTStorageTViewModel.cs +++ b/src/Artemis.Core/VisualScripting/Nodes/NodeTStorageTViewModel.cs @@ -25,6 +25,8 @@ public abstract class Node : Node, ICustomViewMo /// public virtual TViewModel GetViewModel(NodeScript nodeScript) { + if (NodeData == null) + throw new ArtemisCoreException("Nodes without node data (default nodes or exit nodes) cannot have custom view models"); return NodeData.Provider.Plugin.Container.Resolve(args: new object[] {this, nodeScript}); } diff --git a/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs b/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs index db39dd1f2..f1ff6dbb3 100644 --- a/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs +++ b/src/Artemis.UI/Screens/VisualScripting/NodeViewModel.cs @@ -141,41 +141,9 @@ public partial class NodeViewModel : ActivatableViewModelBase // Set up the custom node VM if needed SetupCustomNodeViewModel(); - }); } - private void SetupCustomNodeViewModel() - { - if (Node is not ICustomViewModelNode customViewModelNode) - return; - - try - { - CustomNodeViewModel = customViewModelNode.GetCustomViewModel(NodeScriptViewModel.NodeScript); - } - catch (Exception e) - { - _logger.Error(e, "Failed to instantiate custom node view model"); - } - - if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.AbovePins) - DisplayCustomViewModelAbove = true; - else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BelowPins) - DisplayCustomViewModelBelow = true; - else - { - DisplayCustomViewModelBetween = true; - - if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop) - CustomViewModelVerticalAlignment = VerticalAlignment.Top; - else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop) - CustomViewModelVerticalAlignment = VerticalAlignment.Center; - else - CustomViewModelVerticalAlignment = VerticalAlignment.Bottom; - } - } - public bool IsStaticNode => _isStaticNode?.Value ?? true; public bool HasInputPins => _hasInputPins?.Value ?? false; public bool HasOutputPins => _hasOutputPins?.Value ?? false; @@ -226,4 +194,35 @@ public partial class NodeViewModel : ActivatableViewModelBase if (Node.BrokenState != null && Node.BrokenStateException != null) _windowService.ShowExceptionDialog(Node.BrokenState, Node.BrokenStateException); } + + private void SetupCustomNodeViewModel() + { + if (Node is not ICustomViewModelNode customViewModelNode) + return; + + try + { + CustomNodeViewModel = customViewModelNode.GetCustomViewModel(NodeScriptViewModel.NodeScript); + } + catch (Exception e) + { + _logger.Error(e, "Failed to instantiate custom node view model"); + } + + if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.AbovePins) + DisplayCustomViewModelAbove = true; + else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BelowPins) + DisplayCustomViewModelBelow = true; + else + { + DisplayCustomViewModelBetween = true; + + if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop) + CustomViewModelVerticalAlignment = VerticalAlignment.Top; + else if (customViewModelNode.ViewModelPosition == CustomNodeViewModelPosition.BetweenPinsTop) + CustomViewModelVerticalAlignment = VerticalAlignment.Center; + else + CustomViewModelVerticalAlignment = VerticalAlignment.Bottom; + } + } } \ No newline at end of file