Skip to content

Settings_Engine: Add central settings management #3131

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from 6 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
10 changes: 8 additions & 2 deletions BHoM_Engine.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.1684
# Visual Studio Version 17
VisualStudioVersion = 17.6.33801.468
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BHoM_Engine", "BHoM_Engine\BHoM_Engine.csproj", "{AEAF161D-8206-40B8-93A7-67ABEBF2EE19}"
EndProject
Expand Down Expand Up @@ -53,6 +53,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Structure_Engine", "Structu
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Versioning_Engine", "Versioning_Engine\Versioning_Engine.csproj", "{28D7ABDA-43DC-4A63-8C5F-D3B137E0CD21}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Settings_Engine", "Settings_Engine\Settings_Engine.csproj", "{EFCA10EB-D1A0-48B6-8E2D-07986B2AE171}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -159,6 +161,10 @@ Global
{28D7ABDA-43DC-4A63-8C5F-D3B137E0CD21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{28D7ABDA-43DC-4A63-8C5F-D3B137E0CD21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{28D7ABDA-43DC-4A63-8C5F-D3B137E0CD21}.Release|Any CPU.Build.0 = Release|Any CPU
{EFCA10EB-D1A0-48B6-8E2D-07986B2AE171}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EFCA10EB-D1A0-48B6-8E2D-07986B2AE171}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EFCA10EB-D1A0-48B6-8E2D-07986B2AE171}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EFCA10EB-D1A0-48B6-8E2D-07986B2AE171}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
74 changes: 74 additions & 0 deletions Settings_Engine/Compute/LoadSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2023, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.Engine.Base;
using BH.oM.Base;
using BH.oM.Base.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;

namespace BH.Engine.Settings
{
public static partial class Compute
{
[Description("Load all the JSON settings stored within the provided folder into memory. If no folder is provided, the default folder of %ProgramData%/BHoM/Settings is used instead. All JSON files are scraped within the directory (including subdirectories) and deserialised to ISettings objects.")]
[Input("settingsFolder", "Optional input to determine where to load settings from. Defaults to %ProgramData%/BHoM/Settings if no folder is provided.")]
public static void LoadSettings(string settingsFolder = null)
{
if (string.IsNullOrEmpty(settingsFolder))
settingsFolder = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData), "BHoM", "Settings"); //Defaults to C:/ProgramData/BHoM/Settings if no folder is provided

var settingsFiles = Directory.EnumerateFiles(settingsFolder, "*.json", SearchOption.AllDirectories);

foreach (var file in settingsFiles)
{
string contents = "";
try
{
contents = File.ReadAllText(file);
}
catch (Exception ex)
{
BH.Engine.Base.Compute.RecordError(ex, $"Error when trying to read settings file: {file}.");
}

if (string.IsNullOrEmpty(contents))
continue;

try
{
ISettings settings = BH.Engine.Serialiser.Convert.FromJson(contents) as ISettings;
Type type = settings.GetType();
Global.BHoMSettings[type] = settings;
Global.BHoMSettingsFilePaths[type] = file;
}
catch (Exception ex)
{
BH.Engine.Base.Compute.RecordWarning(ex, $"Cannot deserialise the contents of {file} to an ISettings object.");
}
}
}
}
}
101 changes: 101 additions & 0 deletions Settings_Engine/Compute/SaveSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2023, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.oM.Base;
using BH.oM.Base.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;

namespace BH.Engine.Settings
{
public static partial class Compute
{
[Description("Save a single instance of settings to the specified file path. If no file path is provided, it will default to %ProgramData%/BHoM/Settings/{settingsType}.json - if a file with that name already exists, it will be overwritten.")]
[Input("settings", "The settings object to save as JSON in the specified file path.")]
[Input("run", "Boolean toggle to determine whether to run the method. Useful for Visual Programming to prevent settings being saved/overwritten before providing a file path if desired.")]
[Input("filePath", "Optional file path of where to save the file. If the file already exists, it will be overwritten.")]
[Output("success", "True if the settings have been successfully saved, false otherwise.")]
public static bool SaveSettings(ISettings settings, bool run = false, string filePath = null)
{
if (!run)
return false;

if(settings == null)
{
BH.Engine.Base.Compute.RecordError($"Cannot save null settings.");
return false;
}

if(string.IsNullOrEmpty(filePath))
filePath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData), "BHoM", "Settings", $"{settings.GetType()}.json");

var json = BH.Engine.Serialiser.Convert.ToJson(settings);
try
{
System.IO.File.WriteAllText(filePath, json);
}
catch(Exception ex)
{
BH.Engine.Base.Compute.RecordError(ex, $"Error occurred when trying to save settings of type {settings.GetType()} to file path {filePath}.");
return false;
}

return true;
}

[Description("Saves all settings in memory to their respective files. Settings are saved back to the same file they were loaded from, overwriting them if they've changed. If settings were added during runtime and do not have an associated file, then a new file will be created with the name {settingsType}.json. If no folder is specified, the default of %ProgramData%/BHoM/Settings/{settingsType}.json will be used.")]
[Input("outputDirectory", "Optional input to specify where to save settings file to. If the provided output directory differs from the saved load directory, settings will be saved in the provided output directory and not where they were originally loaded from.")]
[Input("run", "Boolean toggle to determine whether to run the method. Useful for Visual Programming to prevent settings being saved/overwritten before providing a file path if desired.")]
[Output("success", "True if the settings have been successfully saved, false otherwise.")]
public static bool SaveSettings(string outputDirectory = null, bool run = false)
{
if (!run)
return false;

if (string.IsNullOrEmpty(outputDirectory))
outputDirectory = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData), "BHoM", "Settings");

bool allSuccess = true;
foreach(var kvp in Global.BHoMSettings)
{
string loadedFrom = "";
if(Global.BHoMSettingsFilePaths.ContainsKey(kvp.Key) && Global.BHoMSettingsFilePaths[kvp.Key].Contains(outputDirectory))
loadedFrom = Global.BHoMSettingsFilePaths[kvp.Key]; //Save to the loaded file path if one is stored, and the output directory matches the load path. If the output directory does not match the load path, then this is skipped and the default below is used.

if (string.IsNullOrEmpty(loadedFrom))
loadedFrom = Path.Combine(outputDirectory, $"{kvp.Value.GetType()}.json");

if (!SaveSettings(kvp.Value, true, loadedFrom))
{
BH.Engine.Base.Compute.RecordError($"Settings of type {kvp.Key} could not be saved to {loadedFrom}.");
allSuccess = false;
}
}

return allSuccess;
}
}
}
48 changes: 48 additions & 0 deletions Settings_Engine/Modify/UpdateSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2023, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.oM.Base;
using BH.oM.Base.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;

namespace BH.Engine.Settings
{
public static partial class Modify
{
[Description("Update settings in memory with the provided settings object. If the settings already exist in memory, they will be updated to the ones provided. If they do not exist in memory, they will be added.")]
[Input("settings", "New settings to update or add to memory.")]
public static void UpdateSettings(ISettings settings)
{
if (settings == null)
{
BH.Engine.Base.Compute.RecordError("Cannot update null settings.");
return;
}

Type type = settings.GetType();
Global.BHoMSettings[settings.GetType()] = settings;
}
}
}
41 changes: 41 additions & 0 deletions Settings_Engine/Objects/Global.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2023, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.oM.Base;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;

namespace BH.Engine.Settings
{
internal static class Global
{
/***************************************************/
/**** Internal properties - collections ****/
/***************************************************/
internal static ConcurrentDictionary<Type, ISettings> BHoMSettings { get; set; } = new ConcurrentDictionary<Type, ISettings>();
internal static ConcurrentDictionary<Type, string> BHoMSettingsFilePaths { get; set; } = new ConcurrentDictionary<Type, string>(); //Store where settings came from for saving on shut down
}
}


50 changes: 50 additions & 0 deletions Settings_Engine/Query/GetSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2023, the respective contributors. All rights reserved.
*
* Each contributor holds copyright over their respective contributions.
* The project versioning (Git) records all such contribution source information.
*
*
* The BHoM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* The BHoM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this code. If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
*/

using BH.oM.Base;
using BH.oM.Base.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Management;
using System.Text;

namespace BH.Engine.Settings
{
public static partial class Query
{
[Description("Obtain settings of the specified type if they exist in memory.")]
[Input("type", "The type of settings you want to obtain.")]
[Output("settings", "The requested settings if they exist in memory. If they don't exist, a default is returned instead.")]
public static object GetSettings(Type type)
{
ISettings settings = null;
if (!Global.BHoMSettings.TryGetValue(type, out settings))
{
BH.Engine.Base.Compute.RecordWarning($"Could not find settings of type {type} loaded in memory. Returning a default instance of the settings object instead.");
return Activator.CreateInstance(type);
}

return settings;
}
}
}
28 changes: 28 additions & 0 deletions Settings_Engine/Settings_Engine.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Description>https://github.com/BHoM/BHoM_Engine</Description>
<FileVersion>6.3.0.0</FileVersion>
<AssemblyVersion>6.0.0.0</AssemblyVersion>
<RootNamespace>BH.Engine.Settings</RootNamespace>
</PropertyGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy &quot;$(TargetDir)$(TargetFileName)&quot; &quot;C:\ProgramData\BHoM\Assemblies&quot; /Y" />
</Target>

<ItemGroup>
<ProjectReference Include="..\BHoM_Engine\BHoM_Engine.csproj" />
<ProjectReference Include="..\Serialiser_Engine\Serialiser_Engine.csproj" />
</ItemGroup>

<ItemGroup>
<Reference Include="BHoM">
<HintPath>$(ProgramData)\BHoM\Assemblies\BHoM.dll</HintPath>
<Private>False</Private>
<SpecificVersion>False</SpecificVersion>
</Reference>
</ItemGroup>

</Project>