Skip to content

Commit

Permalink
feat: build and serializers
Browse files Browse the repository at this point in the history
  • Loading branch information
Rikarin committed Oct 31, 2023
1 parent f3a3950 commit 550315f
Show file tree
Hide file tree
Showing 55 changed files with 5,631 additions and 60 deletions.
77 changes: 77 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# ------------------------------------------------------------------------------
# <auto-generated>
#
# This code was generated.
#
# - To turn off auto-generation set:
#
# [GitHubActions (AutoGenerate = false)]
#
# - To trigger manual generation invoke:
#
# nuke --generate-configuration GitHubActions_ci --host GitHubActions
#
# </auto-generated>
# ------------------------------------------------------------------------------

name: ci

on:
push:
branches:
- master
- dev
- 'release/**'
pull_request:
branches:
- 'release/**'

jobs:
ubuntu-latest:
name: ubuntu-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: 'Cache: .nuke/temp, ~/.nuget/packages'
uses: actions/cache@v3
with:
path: |
.nuke/temp
~/.nuget/packages
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
- name: 'Run: Compile, Test'
run: ./build.cmd Compile Test
macos-latest:
name: macos-latest
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: 'Cache: .nuke/temp, ~/.nuget/packages'
uses: actions/cache@v3
with:
path: |
.nuke/temp
~/.nuget/packages
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
- name: 'Run: Compile, Test'
run: ./build.cmd Compile Test
windows-latest:
name: windows-latest
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: 'Cache: .nuke/temp, ~/.nuget/packages'
uses: actions/cache@v3
with:
path: |
.nuke/temp
~/.nuget/packages
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
- name: 'Run: Compile, Test'
run: ./build.cmd Compile Test
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 Rikarin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Create game engine with requirements:
## Features

- Entity Component System (Arch)
- Serialization & InputSystem is based on the Stride Engine


## Used libraries
Expand Down
6 changes: 3 additions & 3 deletions Rin.BuildEngine.Common/BuildStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,12 @@ internal void RegisterResult(IExecuteContext executeContext, ResultStatus status
if (StepProcessed != null) {
try {
var outputObjectsGroups = executeContext.GetOutputObjectsGroups();
MicrothreadLocalDatabases.MountDatabase(outputObjectsGroups);
StepProcessed(this, new BuildStepEventArgs(this, executeContext.Logger));
MicroThreadLocalDatabases.MountDatabase(outputObjectsGroups);
StepProcessed(this, new(this, executeContext.Logger));
} catch (Exception ex) {
executeContext.Logger.Error(ex, "Exception in command {Command}", this);
} finally {
MicrothreadLocalDatabases.UnmountDatabase();
MicroThreadLocalDatabases.UnmountDatabase();
}
}
}
Expand Down
1 change: 1 addition & 0 deletions Rin.BuildEngine.Common/Command.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Rin.Core.Serialization;
using Rin.Core.Serialization.Binary;
using Rin.Core.Serialization.Storage;
using Rin.Core.Storage;
using Rin.Core.TODO;
using System.Reflection;
Expand Down
11 changes: 6 additions & 5 deletions Rin.BuildEngine.Common/CommandBuildStep.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Rin.Core.IO;
using Rin.Core.Storage;
using Rin.Core.TODO;

Expand Down Expand Up @@ -104,15 +105,15 @@ public override async Task<ResultStatus> Execute(IExecuteContext executeContext,
if (stepInProgress != null) {
Monitor.Exit(executeContext);
monitorExited = true;
executeContext.Logger.Debug($"Command {Command} delayed because it is currently running...");
executeContext.Logger.Debug("Command {Command} delayed because it is currently running...", Command);
status = (await stepInProgress.ExecutedAsync()).Status;
matchingResult = stepInProgress.Result;
} else {
executeContext.NotifyCommandBuildStepStarted(this, commandHash);
Monitor.Exit(executeContext);
monitorExited = true;

executeContext.Logger.Debug($"Command {Command} scheduled...");
executeContext.Logger.Debug("Command {Command} scheduled...", Command);

// Register the cancel callback
var cancellationTokenSource = executeContext.CancellationTokenSource;
Expand Down Expand Up @@ -206,7 +207,7 @@ BuilderContext builderContext
// Merge results from prerequisites
// TODO: This will prevent us from overwriting this asset with different content as it will result in a write conflict
// At some point we _might_ want to get rid of WaitBuildStep/ListBuildStep system and write a fully stateless input/output-based system; probably need further discussions
var fileProvider = MicrothreadLocalDatabases.DatabaseFileProvider;
var fileProvider = MicroThreadLocalDatabases.DatabaseFileProvider;
if (fileProvider != null) {
var assetIndexMap = fileProvider.ContentIndexMap;
foreach (var prerequisiteStep in PrerequisiteSteps) {
Expand Down Expand Up @@ -256,11 +257,11 @@ internal bool ShouldExecute(
out CommandResultEntry matchingResult
) {
var outputObjectsGroups = executeContext.GetOutputObjectsGroups();
MicrothreadLocalDatabases.MountDatabase(outputObjectsGroups);
MicroThreadLocalDatabases.MountDatabase(outputObjectsGroups);
try {
matchingResult = FindMatchingResult(executeContext, previousResultCollection);
} finally {
MicrothreadLocalDatabases.UnmountDatabase();
MicroThreadLocalDatabases.UnmountDatabase();
}

if (matchingResult == null || Command.ShouldForceExecution()) {
Expand Down
11 changes: 6 additions & 5 deletions Rin.BuildEngine.Common/FileVersionStorage.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Rin.Core.Serialization;
using Rin.Core.Serialization.Serializers;
using Rin.Core.Storage;
using System.Text;

Expand Down Expand Up @@ -35,8 +37,7 @@ public static bool Compact(string storagePath) {
new Dictionary<string, KeyValuePair<FileVersionKey, ObjectId>>(StringComparer.OrdinalIgnoreCase);
foreach (var keyValue in localTracker.GetValues()) {
var filePath = keyValue.Key.Path;
KeyValuePair<FileVersionKey, ObjectId> previousKeyValue;
if (!latestVersion.TryGetValue(filePath, out previousKeyValue)
if (!latestVersion.TryGetValue(filePath, out var previousKeyValue)
|| keyValue.Key.LastModifiedDate > previousKeyValue.Key.LastModifiedDate) {
latestVersion[filePath] = keyValue;
}
Expand Down Expand Up @@ -68,21 +69,21 @@ protected override List<KeyValuePair<FileVersionKey, ObjectId>> ReadEntries(Stre
var key = new FileVersionKey { Path = values[0] };
if (!long.TryParse(values[1], out var dateTime)) {
throw new InvalidOperationException(
"Unable to decode datetime [{0}] when reading file version index".ToFormat(values[1])
$"Unable to decode datetime [{values[1]}] when reading file version index"
);
}

key.LastModifiedDate = new(dateTime);
if (!long.TryParse(values[2], out key.FileSize)) {
throw new InvalidOperationException(
"Unable to decode filesize [{0}] when reading file version index".ToFormat(values[2])
$"Unable to decode filesize [{values[2]}] when reading file version index"
);
}

var objectIdStr = values[3];
if (!ObjectId.TryParse(objectIdStr, out ObjectId objectId)) {
throw new InvalidOperationException(
"Unable to decode objectid [{0}] when reading file version index".ToFormat(objectIdStr)
$"Unable to decode ObjectId [{objectIdStr}] when reading file version index"
);
}

Expand Down
1 change: 1 addition & 0 deletions Rin.BuildEngine.Common/FileVersionTracker.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Rin.Core.Storage;
using Serilog;

namespace Rin.BuildEngine.Common;
Expand Down
109 changes: 109 additions & 0 deletions Rin.BuildEngine.Common/MicroThreadLocalDatabases.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using Rin.Core.TODO;

namespace Rin.BuildEngine.Common;

/// <summary>
/// A static class that allows to have a different <see cref="ObjectDatabase" /> on each <see cref="MicroThread" />.
/// Objects can still be shared
/// between micro-threads by using the <see cref="AddToSharedGroup" /> method.
/// </summary>
public static class MicroThreadLocalDatabases {
static readonly Dictionary<ObjectUrl, OutputObject> SharedOutputObjects = new();
static readonly MicroThreadLocal<DatabaseFileProvider> MicroThreadLocalDatabaseFileProvider;

public static IDatabaseFileProviderService ProviderService { get; }

/// <summary>
/// Gets a value indicating whether this instance has a valid database file provider.
/// </summary>
/// <value><c>true</c> if this instance has database file provider; otherwise, <c>false</c>.</value>
public static bool HasValidDatabaseFileProvider => MicroThreadLocalDatabaseFileProvider.Value != null;

/// <summary>
/// Gets the currently mounted microthread-local database provider.
/// </summary>
public static DatabaseFileProvider DatabaseFileProvider => MicroThreadLocalDatabaseFileProvider.Value;

static MicroThreadLocalDatabases() {
MicroThreadLocalDatabaseFileProvider = new MicroThreadLocal<DatabaseFileProvider>();

ProviderService = new MicroThreadLocalProviderService();
}

/// <summary>
/// Merges the given dictionary of build output objects into the shared group. Objects merged here will be integrated
/// to every database.
/// </summary>
/// <param name="outputObjects">The dictionary containing the <see cref="OutputObject" /> to merge into the shared group.</param>
public static void AddToSharedGroup(IReadOnlyDictionary<ObjectUrl, OutputObject> outputObjects) {
lock (SharedOutputObjects) {
foreach (var outputObject in outputObjects) {
SharedOutputObjects[outputObject.Key] = outputObject.Value;
}
}
}

/// <summary>
/// Gets a <see cref="MicroThreadLocalDatabaseFileProvider" /> containing only objects from the shared group.
/// The shared group is a group of objects registered via <see cref="AddToSharedGroup" /> and shared amongst all
/// databases.
/// </summary>
/// <returns>A <see cref="MicroThreadLocalDatabaseFileProvider" /> that can provide objects from the common group.</returns>
public static DatabaseFileProvider GetSharedDatabase() => CreateDatabase(CreateTransaction(null));

/// <summary>
/// Creates and mounts a database containing the given output object groups and the shared group in the
/// microthread-local
/// <see cref="MicroThreadLocalDatabaseFileProvider" />.
/// </summary>
/// <param name="outputObjectsGroups">A collection of dictionaries representing a group of output object.</param>
public static void MountDatabase(IEnumerable<IReadOnlyDictionary<ObjectUrl, OutputObject>> outputObjectsGroups) {
MountDatabase(CreateTransaction(outputObjectsGroups));
}

/// <summary>
/// Creates and mounts a database containing output objects from the shared group in the microthread-local
/// <see cref="MicroThreadLocalDatabaseFileProvider" />.
/// </summary>
public static void MountCommonDatabase() {
MicroThreadLocalDatabaseFileProvider.Value = CreateDatabase(CreateTransaction(null));
}

/// <summary>
/// Unmounts the currently mounted microthread-local database.
/// </summary>
public static void UnmountDatabase() {
MicroThreadLocalDatabaseFileProvider.ClearValue();
}

public static IEnumerable<IReadOnlyDictionary<ObjectUrl, OutputObject>> GetOutputObjectsGroups(
IEnumerable<IReadOnlyDictionary<ObjectUrl, OutputObject>> transactionOutputObjectsGroups
) {
if (transactionOutputObjectsGroups != null) {
foreach (var outputObjects in transactionOutputObjectsGroups) {
yield return outputObjects;
}
}

yield return SharedOutputObjects;
}

static DatabaseFileProvider CreateDatabase(BuildTransaction transaction) =>
new DatabaseFileProvider(new BuildTransaction.DatabaseContentIndexMap(transaction), Builder.ObjectDatabase);

internal static void MountDatabase(BuildTransaction transaction) {
MicroThreadLocalDatabaseFileProvider.Value = CreateDatabase(transaction);
}

internal static BuildTransaction CreateTransaction(
IEnumerable<IReadOnlyDictionary<ObjectUrl, OutputObject>> transactionOutputObjectsGroups
) =>
new BuildTransaction(
Builder.ObjectDatabase.ContentIndexMap,
GetOutputObjectsGroups(transactionOutputObjectsGroups)
);

class MicroThreadLocalProviderService : IDatabaseFileProviderService {
public DatabaseFileProvider FileProvider => MicroThreadLocalDatabaseFileProvider.Value;
}
}
2 changes: 2 additions & 0 deletions Rin.BuildEngine.Common/Rin.BuildEngine.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Rin.Core.IO\Rin.Core.IO.csproj" />
<ProjectReference Include="..\Rin.Core.Serialization\Rin.Core.Serialization.csproj" />
<ProjectReference Include="..\Rin.Core\Rin.Core.csproj" />
</ItemGroup>
</Project>
Loading

0 comments on commit 550315f

Please sign in to comment.