Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/dotnet-manual.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net

name: .NET (Manual Build)
permissions:
contents: read

on:
workflow_dispatch: # Manual trigger only
inputs:
branch:
description: 'Branch to build'
required: false
default: ''
type: string

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.branch || github.ref_name }}

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.x

- name: Install Mono
run: |
sudo apt-get update
sudo apt-get install -y mono-devel

- name: Run Configure setup
shell: pwsh
run: |
Write-Host "Running Configure.ps1..."
echo "1" | pwsh ./Configure.ps1 setup -Verbose

- name: Restore dependencies
working-directory: CatalystUI
run: dotnet restore

- name: Build
working-directory: CatalystUI
run: dotnet build --no-restore

- name: Test
working-directory: CatalystUI
run: dotnet test --no-build --verbosity normal
27 changes: 23 additions & 4 deletions .scripts/Setup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,40 @@ $projectsList = @(
Projects = @(
@{ Folder = "Core"; Name = "CatalystUI.Attributes" },
@{ Folder = "Core"; Name = "CatalystUI.Collections" },
@{ Folder = "Core"; Name = "CatalystUI.Mathematics" },
@{ Folder = "Core"; Name = "CatalystUI.Threading" },
@{ Folder = "Tooling"; Name = "CatalystUI.Analyzers" },
@{ Folder = "Tooling"; Name = "CatalystUI.CodeFix" },
@{ Folder = "Core"; Name = "CatalystUI.Core" }
@{ Folder = "Core"; Name = "CatalystUI.Core" },
@{ Folder = "Core"; Name = "CatalystUI.Debug" },
@{ Folder = "Core"; Name = "CatalystUI.Supplementary" }
)
PromptIgnore = $true
PromptIgnore = $false
Depends = @()
},
@{
Module = "Arcane"
Projects = @(
@{ Folder = "Modules/Arcane"; Name = "CatalystUI.Modules.Arcane.Core" }
)
PromptIgnore = $false
Depends = @("Core")
},
@{
Module = "Arcane.Ini"
Project = @(
@{ Folder = "Modules/Arcane"; Name = "CatalystUI.Modules.Arcane.Ini" }
)
PromptIgnore = $false
Depends = @("Arcane")
}
)

# Build prompt options
$promptOptions = @("All") + (
$projectsList |
Where-Object { -not $_.PromptIgnore -and $_.Module -ne "All" } |
Select-Object -ExpandProperty Module -Unique |
Sort-Object
Select-Object -ExpandProperty Module -Unique
)

# Prompt user for module selection
Expand Down
46 changes: 46 additions & 0 deletions CatalystUI/CatalystUI.sln
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,24 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatalystUI.Attributes", "Co
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatalystUI.CodeFix", "Tooling\CatalystUI.CodeFix\CatalystUI.CodeFix.csproj", "{E5319DB6-E93C-4A7D-9B3B-F219206BBC54}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatalystUI.Debug", "Core\CatalystUI.Debug\CatalystUI.Debug.csproj", "{39CD2850-CB5B-4F3C-81AB-9430506F3BD7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatalystUI.Supplementary", "Core\CatalystUI.Supplementary\CatalystUI.Supplementary.csproj", "{33B1D211-9C3A-4AA8-95DE-75D9122CC968}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatalystUI.Mathematics", "Core\CatalystUI.Mathematics\CatalystUI.Mathematics.csproj", "{E2B3A13C-9AE6-44D8-8456-58723ABBC343}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Modules", "Modules", "{9C3F6A00-82F5-4900-9D6C-07ACBBAAE823}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Crystal", "Crystal", "{41BEF490-7005-4D10-9958-22D636F9DE38}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Arcane", "Arcane", "{C8B02B42-826B-4EDE-B72F-F4F97C1A088D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Veilstone", "Veilstone", "{0E1F2B64-37D9-4C24-9CED-9A44D7CDBB8C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatalystUI.Modules.Arcane.Ini", "Modules\Arcane\CatalystUI.Modules.Arcane.Ini\CatalystUI.Modules.Arcane.Ini.csproj", "{C02600D7-087B-4190-9B47-F15184C19B2D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatalystUI.Modules.Arcane.Core", "Modules\Arcane\CatalystUI.Modules.Arcane.Core\CatalystUI.Modules.Arcane.Core.csproj", "{047744B0-87DC-4808-99C4-5AC1F8A1EB4D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -52,6 +70,26 @@ Global
{E5319DB6-E93C-4A7D-9B3B-F219206BBC54}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E5319DB6-E93C-4A7D-9B3B-F219206BBC54}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E5319DB6-E93C-4A7D-9B3B-F219206BBC54}.Release|Any CPU.Build.0 = Release|Any CPU
{39CD2850-CB5B-4F3C-81AB-9430506F3BD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{39CD2850-CB5B-4F3C-81AB-9430506F3BD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39CD2850-CB5B-4F3C-81AB-9430506F3BD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39CD2850-CB5B-4F3C-81AB-9430506F3BD7}.Release|Any CPU.Build.0 = Release|Any CPU
{33B1D211-9C3A-4AA8-95DE-75D9122CC968}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33B1D211-9C3A-4AA8-95DE-75D9122CC968}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33B1D211-9C3A-4AA8-95DE-75D9122CC968}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33B1D211-9C3A-4AA8-95DE-75D9122CC968}.Release|Any CPU.Build.0 = Release|Any CPU
{E2B3A13C-9AE6-44D8-8456-58723ABBC343}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E2B3A13C-9AE6-44D8-8456-58723ABBC343}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E2B3A13C-9AE6-44D8-8456-58723ABBC343}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E2B3A13C-9AE6-44D8-8456-58723ABBC343}.Release|Any CPU.Build.0 = Release|Any CPU
{C02600D7-087B-4190-9B47-F15184C19B2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C02600D7-087B-4190-9B47-F15184C19B2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C02600D7-087B-4190-9B47-F15184C19B2D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C02600D7-087B-4190-9B47-F15184C19B2D}.Release|Any CPU.Build.0 = Release|Any CPU
{047744B0-87DC-4808-99C4-5AC1F8A1EB4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{047744B0-87DC-4808-99C4-5AC1F8A1EB4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{047744B0-87DC-4808-99C4-5AC1F8A1EB4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{047744B0-87DC-4808-99C4-5AC1F8A1EB4D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{68F496AC-9438-40F1-9DF8-97363033D661} = {7EC51871-49A8-4991-BDAF-F43A4E9B8C9D}
Expand All @@ -61,5 +99,13 @@ Global
{A3936CB7-DC31-414B-9E40-CB9436391068} = {5D38F696-8C11-4C9A-B50E-2C33AA7FAA6C}
{44E8E3D2-FE47-49EA-A397-EB680E33AA2E} = {7EC51871-49A8-4991-BDAF-F43A4E9B8C9D}
{E5319DB6-E93C-4A7D-9B3B-F219206BBC54} = {5D38F696-8C11-4C9A-B50E-2C33AA7FAA6C}
{39CD2850-CB5B-4F3C-81AB-9430506F3BD7} = {7EC51871-49A8-4991-BDAF-F43A4E9B8C9D}
{33B1D211-9C3A-4AA8-95DE-75D9122CC968} = {7EC51871-49A8-4991-BDAF-F43A4E9B8C9D}
{E2B3A13C-9AE6-44D8-8456-58723ABBC343} = {7EC51871-49A8-4991-BDAF-F43A4E9B8C9D}
{41BEF490-7005-4D10-9958-22D636F9DE38} = {9C3F6A00-82F5-4900-9D6C-07ACBBAAE823}
{C8B02B42-826B-4EDE-B72F-F4F97C1A088D} = {9C3F6A00-82F5-4900-9D6C-07ACBBAAE823}
{0E1F2B64-37D9-4C24-9CED-9A44D7CDBB8C} = {9C3F6A00-82F5-4900-9D6C-07ACBBAAE823}
{C02600D7-087B-4190-9B47-F15184C19B2D} = {C8B02B42-826B-4EDE-B72F-F4F97C1A088D}
{047744B0-87DC-4808-99C4-5AC1F8A1EB4D} = {C8B02B42-826B-4EDE-B72F-F4F97C1A088D}
EndGlobalSection
EndGlobal
146 changes: 146 additions & 0 deletions CatalystUI/Core/CatalystUI.Core/Builders/CatalystAppBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// -------------------------------------------------------------------------------------------------
// CatalystUI Framework for .NET Core - https://catalystui.org/
// Copyright (c) 2025 CatalystUI LLC. All rights reserved.
//
// This file is part of CatalystUI and is provided as part of an early-access release.
// Unauthorized commercial use, distribution, or modification is strictly prohibited.
//
// This software is not open source and is not publicly licensed.
// For full terms, see the LICENSE and NOTICE files in the project root.
// -------------------------------------------------------------------------------------------------

using Catalyst.Connectors;
using Catalyst.Domains;
using Catalyst.Layers;
using System;
using System.ComponentModel;
using System.Threading.Tasks;

namespace Catalyst.Builders {

/// <summary>
/// Builder class for creating a Catalyst application.
/// </summary>
public sealed class CatalystAppBuilder {

/// <summary>
/// Constructs a new <see cref="CatalystAppBuilder"/>.
/// </summary>
public CatalystAppBuilder() {
// ...
}

/// <summary>
/// Makes a layer available for use in the CatalystUI application.
/// </summary>
/// <remarks>
/// <para>
/// The added layer is registered with the <see cref="ModelRegistry"/>,
/// which allows it to be used globally across the application.
/// </para>
/// <para>
/// Layers are the building blocks of the CatalystUI application,
/// providing a way to organize and manage different parts of the application.
/// Inserting a layer into the application allows it to add additional functionality
/// such as data handling, UI components, or other features. To connect the functionality
/// of multiple layers, you can use connectors.
/// </para>
/// </remarks>
/// <seealso cref="AddConnector{TConnector}"/>
/// <param name="layer">The layer to add.</param>
/// <typeparam name="TLayer">The type of the layer to add.</typeparam>
/// <returns>The current instance of the <see cref="CatalystAppBuilder"/>.</returns>
public CatalystAppBuilder AddLayer<TLayer>(TLayer layer) where TLayer : ILayer<IDomain> {
ModelRegistry.RegisterLayer(layer);
return this;
}

/// <summary>
/// Makes a connector available for use in the CatalystUI application.
/// </summary>
/// <remarks>
/// <para>
/// The added connector is registered with the <see cref="ModelRegistry"/>,
/// which allows it to be used globally across the application.
/// </para>
/// <para>
/// Connectors allow different layers to communicate with each other,
/// and for their underlying domains to interact seamlessly. To add
/// new functionality to the application, you can insert a layer
/// and connect it to existing layers using connectors.
/// </para>
/// </remarks>
/// <seealso cref="AddLayer{TLayer}"/>
/// <param name="connector">The connector to add.</param>
/// <typeparam name="TConnector">The type of the connector to add.</typeparam>
/// <returns>The current instance of the <see cref="CatalystAppBuilder"/>.</returns>
public CatalystAppBuilder AddConnector<TConnector>(TConnector connector) where TConnector : IConnector<ILayer<IDomain>, ILayer<IDomain>> {
ModelRegistry.RegisterConnector(connector);
return this;
}

/// <summary>
/// Builds the CatalystUI Application.
/// </summary>
/// <remarks>
/// <para>
/// <b>Building a Catalyst application will capture the thread on which it is called.</b>
/// This thread should be the main thread of the application to ensure proper operation.
/// Failure to do so may result in unexpected behavior and occasional crashes.
/// </para>
/// <para>
/// The resulting run method will be executed on a separate thread. If the caller needs
/// to perform work on the main thread, it should use the <see cref="CatalystApp.Dispatcher"/>
/// to schedule work on the main thread.
/// </para>
/// <para>
/// The application will not exit until the run method completes or the <see cref="CatalystApp.Exit(int)"/> method is called.
/// To keep an application running indefinitely, you would do as you would in a typical
/// application, such as using a loop or waiting for user input.
/// </para>
/// </remarks>
/// <param name="runMethod">The method to run when the application starts.</param>
/// <returns>A new instance of a CatalystUI application.</returns>
public void Build(Func<CatalystApp, int> runMethod) {
_ = new CatalystApp(runMethod);
}

/// <inheritdoc cref="Build(System.Func{CatalystApp, int})"/>
public void Build(Action<CatalystApp> runMethod) {
_ = new CatalystApp(app => {
runMethod(app);
return 0; // Default exit code
});
}

/// <inheritdoc cref="Build(System.Func{CatalystApp, int})"/>
public void Build(Func<CatalystApp, Task> runMethod) {
_ = new CatalystApp(app => {
runMethod(app).GetAwaiter().GetResult();
return 0; // Default exit code
});
}

/// <inheritdoc cref="Build(System.Func{CatalystApp, int})"/>
public void Build(Func<CatalystApp, Task<int>> runMethod) {
_ = new CatalystApp(app => runMethod(app).GetAwaiter().GetResult());
}

/// <remarks>
/// When building a Catalyst application, it is recommended to use the overloads that accept a <see cref="Func{T}"/> or <see cref="Action"/> as the run method,
/// which allows the application to capture the main thread and prevent issues during asynchronous operations.
/// This method is provided for advanced use cases only and should be used with caution,
/// as some functionality may cause unexpected behavior if the main thread is not captured correctly.
/// MacOS and Linux seem to be particularly sensitive to this, as they require the main thread to be
/// captured for proper system-level operations and UI interactions.
/// </remarks>
/// <inheritdoc cref="Build(System.Action{CatalystApp})"/>
[Obsolete("Use Build(Action) or Build(Func<Task>) whenever possible. This method is provided for advanced use cases only.")]
[EditorBrowsable(EditorBrowsableState.Advanced)]
public void Build() {
_ = new CatalystApp();
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// -------------------------------------------------------------------------------------------------
// CatalystUI Framework for .NET Core - https://catalystui.org/
// Copyright (c) 2025 CatalystUI LLC. All rights reserved.
//
// This file is part of CatalystUI and is provided as part of an early-access release.
// Unauthorized commercial use, distribution, or modification is strictly prohibited.
//
// This software is not open source and is not publicly licensed.
// For full terms, see the LICENSE and NOTICE files in the project root.
// -------------------------------------------------------------------------------------------------

namespace Catalyst.Builders.Extensions {

/// <summary>
/// The following class doesn't provide any functionality itself,
/// but it provides the namespace for extension methods,
/// so conditional compilation doesn't yell at end-users
/// if they need it during a debug build but not a release build.
/// </summary>
public static class CatalystAppBuilderExtensions {

// ...

}

}
Loading
Loading