still trying to figure things out...

This commit is contained in:
Michael Becker 2024-10-13 18:39:59 -04:00
parent f92c2040d8
commit 675dddbc0a
8 changed files with 194 additions and 96 deletions

View File

@ -49,6 +49,8 @@ namespace Mocha.Core
private NanoId _ID; private NanoId _ID;
private bool isNotEmpty; private bool isNotEmpty;
public Guid GlobalIdentifier;
public InstanceHandle GetHandle() { return this; } public InstanceHandle GetHandle() { return this; }
public static InstanceHandle Create() public static InstanceHandle Create()

View File

@ -0,0 +1,47 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
public class InstanceReference
{
public InstanceReference(Guid globalIdentifier)
{
GlobalIdentifier = globalIdentifier;
}
public Guid GlobalIdentifier { get; }
public static bool operator==(InstanceReference left, InstanceReference right)
{
return left.Equals(right);
}
public static bool operator!=(InstanceReference left, InstanceReference right)
{
return !left.Equals(right);
}
public override bool Equals(object? obj)
{
if (obj is InstanceReference)
{
return ((InstanceReference)obj).GlobalIdentifier.Equals(this.GlobalIdentifier);
}
return false;
}
public override int GetHashCode()
{
return GlobalIdentifier.GetHashCode();
}
}

View File

@ -266,6 +266,7 @@ public abstract class Oms
{ {
if (TryGetInstance(globalIdentifier, out InstanceHandle ih)) if (TryGetInstance(globalIdentifier, out InstanceHandle ih))
{ {
ih.GlobalIdentifier = globalIdentifier;
return ih; return ih;
} }
throw new KeyNotFoundException(String.Format("inst not found: {0}", globalIdentifier)); throw new KeyNotFoundException(String.Format("inst not found: {0}", globalIdentifier));
@ -1212,7 +1213,7 @@ public abstract class Oms
// to do its second pass "linking" the objects // to do its second pass "linking" the objects
lib.Link(); lib.Link();
InitializeLibraryInternal(lh, lib); InitializeLibrary(lh, lib);
return lh; return lh;
} }
@ -1270,7 +1271,7 @@ public abstract class Oms
// to do its second pass "linking" the objects // to do its second pass "linking" the objects
lib.Link(); lib.Link();
InitializeLibraryInternal(lh, lib); InitializeLibrary(lh, lib);
return lh; return lh;
} }
@ -1284,12 +1285,17 @@ public abstract class Oms
{ {
LibraryHandle lh = LoadLibrary(st); LibraryHandle lh = LoadLibrary(st);
_libraryFileNames[lh] = manifestResourceStreamName; _libraryFileNames[lh] = manifestResourceStreamName;
_libraries[manifestResourceStreamName] = lh;
return lh; return lh;
} }
throw new KeyNotFoundException(String.Format("manifest resource stream named '{0}' not found", manifestResourceStreamName)); throw new KeyNotFoundException(String.Format("manifest resource stream named '{0}' not found", manifestResourceStreamName));
} }
protected abstract void InitializeLibraryInternal(LibraryHandle lh, Library lib); protected abstract void InitializeLibraryInternal(LibraryHandle lh, Library lib);
private void InitializeLibrary(LibraryHandle lh, Library lib)
{
InitializeLibraryInternal(lh, lib);
}
public string? GetTenantName(TenantHandle tenant) public string? GetTenantName(TenantHandle tenant)
{ {

View File

@ -0,0 +1,38 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using Mocha.Core.OmsImplementations;
namespace Mocha.Core.OmsImplementations;
public class EmbeddedMiniOms : MemoryOms
{
public string SystemLibraryResourceName { get; set; } = "Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl";
protected override void InitializeInternal()
{
base.InitializeInternal();
TenantHandle th = CreateTenant("super");
SelectTenant(th);
if (SystemLibraryResourceName != null)
{
LibraryHandle lh = LoadLibrary(typeof(EmbeddedMiniOms), SystemLibraryResourceName);
AddLibraryReference(lh);
}
}
}

View File

@ -25,6 +25,12 @@ public class MemoryOms : Oms
{ {
private class _Tenant private class _Tenant
{ {
private MemoryOms oms;
public _Tenant(MemoryOms oms)
{
this.oms = oms;
}
private Dictionary<Guid, InstanceHandle> _instancesByGuid = new Dictionary<Guid, InstanceHandle>(); private Dictionary<Guid, InstanceHandle> _instancesByGuid = new Dictionary<Guid, InstanceHandle>();
private Dictionary<InstanceHandle, Guid> _guidsByInstance = new Dictionary<InstanceHandle, Guid>(); private Dictionary<InstanceHandle, Guid> _guidsByInstance = new Dictionary<InstanceHandle, Guid>();
@ -43,6 +49,12 @@ public class MemoryOms : Oms
{ {
return _guidsByInstance[instance]; return _guidsByInstance[instance];
} }
foreach (LibraryHandle lh in _libraryReferences)
{
Guid gid = oms._libraries[lh].GetGlobalIdentifier(instance);
if (gid != Guid.Empty)
return gid;
}
return Guid.Empty; return Guid.Empty;
} }
public InstanceKey GetInstanceKey(InstanceHandle instance) public InstanceKey GetInstanceKey(InstanceHandle instance)
@ -61,6 +73,20 @@ public class MemoryOms : Oms
ih = _instancesByGuid[globalIdentifier]; ih = _instancesByGuid[globalIdentifier];
return true; return true;
} }
foreach (LibraryHandle lh in _libraryReferences)
{
if (oms._libraries.ContainsKey(lh))
{
if (oms._libraries[lh].TryGetInstance(globalIdentifier, out ih))
{
// LibraryInst_g g = new LibraryInst_g() { InstanceHandle = ih, SourceLibrary = lh, GlobalIdentifier = globalIdentifier };
// _libraries[lh]._libraryInst_gs[globalIdentifier] = g;
// _libraries[lh]._libraryInst_is[ih] = g;
return true;
}
}
}
ih = InstanceHandle.Empty; ih = InstanceHandle.Empty;
return false; return false;
} }
@ -84,6 +110,8 @@ public class MemoryOms : Oms
public InstanceHandle CreateInstance(Guid guid) public InstanceHandle CreateInstance(Guid guid)
{ {
InstanceHandle ir = InstanceHandle.Create(); InstanceHandle ir = InstanceHandle.Create();
ir.GlobalIdentifier = guid;
_instancesByGuid[guid] = ir; _instancesByGuid[guid] = ir;
_guidsByInstance[ir] = guid; _guidsByInstance[ir] = guid;
return ir; return ir;
@ -139,6 +167,18 @@ public class MemoryOms : Oms
return list2.ToArray(); return list2.ToArray();
} }
} }
foreach (LibraryHandle lh in _libraryReferences)
{
if (oms._libraries.ContainsKey(lh))
{
IReadOnlyCollection<InstanceHandle> insts2 = oms._libraries[lh].GetRelatedInstances(source, relationship, effectiveDate);
if (insts2.Count > 0)
{
return insts2;
}
}
}
return new InstanceHandle[0]; return new InstanceHandle[0];
} }
@ -161,7 +201,7 @@ public class MemoryOms : Oms
return false; return false;
} }
public object GetAttributeValue(InstanceHandle source, InstanceHandle attribute, DateTime effectiveDate) public object? GetAttributeValue(InstanceHandle source, InstanceHandle attribute, DateTime effectiveDate)
{ {
if (_Attributes.ContainsKey(source)) if (_Attributes.ContainsKey(source))
{ {
@ -182,6 +222,18 @@ public class MemoryOms : Oms
} }
} }
} }
foreach (LibraryHandle lh in _libraryReferences)
{
if (oms._libraries.ContainsKey(lh))
{
object? value = oms._libraries[lh].GetAttributeValue(source, attribute, effectiveDate);
if (value != null)
{
return value;
}
}
}
return null; return null;
} }
public void SetAttributeValue(InstanceHandle source, InstanceHandle attribute, object value, DateTime effectiveDate) public void SetAttributeValue(InstanceHandle source, InstanceHandle attribute, object value, DateTime effectiveDate)
@ -203,7 +255,23 @@ public class MemoryOms : Oms
} }
list.Add(new AttributeValue(effectiveDate, value)); list.Add(new AttributeValue(effectiveDate, value));
} }
}
private List<LibraryHandle> _libraryReferences = new List<LibraryHandle>();
public void AddLibraryReference(LibraryHandle library)
{
if (!_libraryReferences.Contains(library))
{
// please don't reference the same library multiple times
_libraryReferences.Add(library);
}
}
public void RemoveLibraryReference(LibraryHandle library)
{
if (_libraryReferences.Contains(library))
_libraryReferences.Remove(library);
}
}
private Dictionary<TenantHandle, _Tenant> _tenantData = new Dictionary<TenantHandle, _Tenant>(); private Dictionary<TenantHandle, _Tenant> _tenantData = new Dictionary<TenantHandle, _Tenant>();
@ -215,7 +283,7 @@ public class MemoryOms : Oms
protected override TenantHandle CreateTenantInternal(string tenantName) protected override TenantHandle CreateTenantInternal(string tenantName)
{ {
TenantHandle th = TenantHandle.Create(); TenantHandle th = TenantHandle.Create();
_tenantData[th] = new _Tenant(); _tenantData[th] = new _Tenant(this);
return th; return th;
} }
protected override bool SelectTenantInternal(TenantHandle tenant) protected override bool SelectTenantInternal(TenantHandle tenant)
@ -229,53 +297,32 @@ public class MemoryOms : Oms
_CurrentTenantData = null; _CurrentTenantData = null;
} }
private Dictionary<TenantHandle, List<LibraryHandle>> _libraryReferences = new Dictionary<TenantHandle, List<LibraryHandle>>();
protected override void AddLibraryReferenceInternal(LibraryHandle library) protected override void AddLibraryReferenceInternal(LibraryHandle library)
{ {
if (!_libraryReferences.ContainsKey(_CurrentTenant)) if (_CurrentTenantData != null)
{ {
_libraryReferences[_CurrentTenant] = new List<LibraryHandle>(); _CurrentTenantData.AddLibraryReference(library);
}
if (!_libraryReferences[_CurrentTenant].Contains(library))
{
// please don't reference the same library multiple times
_libraryReferences[_CurrentTenant].Add(library);
} }
} }
protected override void RemoveLibraryReferenceInternal(LibraryHandle library) protected override void RemoveLibraryReferenceInternal(LibraryHandle library)
{ {
if (_libraryReferences.ContainsKey(_CurrentTenant)) if (_CurrentTenantData != null)
{ {
if (_libraryReferences[_CurrentTenant].Contains(library)) _CurrentTenantData.RemoveLibraryReference(library);
{
_libraryReferences[_CurrentTenant].Remove(library);
}
} }
} }
public void __Test_AddLibraryReference_1(LibraryHandle lhWeb, LibraryHandle lhSystem)
{
_libraries[lhWeb].AddLibraryReference(lhSystem);
}
protected override Guid GetGlobalIdentifierInternal(InstanceHandle instance) protected override Guid GetGlobalIdentifierInternal(InstanceHandle instance)
{ {
if (_CurrentTenantData == null) if (_CurrentTenantData == null)
throw new InvalidOperationException("Please select a tenant first."); throw new InvalidOperationException("Please select a tenant first.");
Guid gid = _CurrentTenantData.GetGlobalIdentifier(instance); Guid gid = _CurrentTenantData.GetGlobalIdentifier(instance);
if (gid == Guid.Empty)
{
if (_libraryReferences.ContainsKey(_CurrentTenant))
{
foreach (LibraryHandle lh in _libraryReferences[_CurrentTenant])
{
gid = _libraries[lh].GetGlobalIdentifier(instance);
if (gid != Guid.Empty)
return gid;
}
}
// if (_libraryInst_is.ContainsKey(instance))
// {
// gid = _libraryInst_is[instance].GlobalIdentifier;
// }
}
return gid; return gid;
} }
protected override InstanceKey GetInstanceKeyInternal(InstanceHandle instance) protected override InstanceKey GetInstanceKeyInternal(InstanceHandle instance)
@ -315,7 +362,7 @@ public class MemoryOms : Oms
protected override void InitializeLibraryInternal(LibraryHandle lh, Library data) protected override void InitializeLibraryInternal(LibraryHandle lh, Library data)
{ {
_Tenant lib = new _Tenant(); _Tenant lib = new _Tenant(this);
foreach (LibraryInstance inst in data.Instances) foreach (LibraryInstance inst in data.Instances)
{ {
InstanceHandle ih = lib.CreateInstance(inst.InstanceGuid); InstanceHandle ih = lib.CreateInstance(inst.InstanceGuid);
@ -357,33 +404,6 @@ public class MemoryOms : Oms
throw new InvalidOperationException("Please select a tenant first."); throw new InvalidOperationException("Please select a tenant first.");
bool v = _CurrentTenantData.TryGetInstance(globalIdentifier, out ih); bool v = _CurrentTenantData.TryGetInstance(globalIdentifier, out ih);
if (!v)
{
// if (_libraryInst_gs.ContainsKey(globalIdentifier))
// {
// ih = _libraryInst_gs[globalIdentifier].InstanceHandle;
// return true;
// }
// else
// {
if (_libraryReferences.ContainsKey(_CurrentTenant))
{
foreach (LibraryHandle lh in _libraryReferences[_CurrentTenant])
{
if (_libraries.ContainsKey(lh))
{
if (_libraries[lh].TryGetInstance(globalIdentifier, out ih))
{
// LibraryInst_g g = new LibraryInst_g() { InstanceHandle = ih, SourceLibrary = lh, GlobalIdentifier = globalIdentifier };
// _libraries[lh]._libraryInst_gs[globalIdentifier] = g;
// _libraries[lh]._libraryInst_is[ih] = g;
return true;
}
}
}
}
// }
}
return v; return v;
} }
protected override bool TryGetInstanceInternal(InstanceKey ik, out InstanceHandle ih) protected override bool TryGetInstanceInternal(InstanceKey ik, out InstanceHandle ih)
@ -432,20 +452,6 @@ public class MemoryOms : Oms
throw new InvalidOperationException("Please select a tenant first."); throw new InvalidOperationException("Please select a tenant first.");
IReadOnlyCollection<InstanceHandle> insts = _CurrentTenantData.GetRelatedInstances(source, relationship, effectiveDate); IReadOnlyCollection<InstanceHandle> insts = _CurrentTenantData.GetRelatedInstances(source, relationship, effectiveDate);
if (insts.Count == 0)
{
foreach (LibraryHandle lh in _libraryReferences[_CurrentTenant])
{
if (_libraries.ContainsKey(lh))
{
IReadOnlyCollection<InstanceHandle> insts2 = _libraries[lh].GetRelatedInstances(source, relationship, effectiveDate);
if (insts2.Count > 0)
{
return insts2;
}
}
}
}
return insts; return insts;
} }
@ -462,20 +468,6 @@ public class MemoryOms : Oms
throw new InvalidOperationException("Please select a tenant first."); throw new InvalidOperationException("Please select a tenant first.");
object value = _CurrentTenantData.GetAttributeValue(source, attribute, effectiveDate); object value = _CurrentTenantData.GetAttributeValue(source, attribute, effectiveDate);
if (value == null)
{
foreach (LibraryHandle lh in _libraryReferences[_CurrentTenant])
{
if (_libraries.ContainsKey(lh))
{
value = _libraries[lh].GetAttributeValue(source, attribute, effectiveDate);
if (value != null)
{
return value;
}
}
}
}
return value; return value;
} }
protected override void SetAttributeValueInternal(InstanceHandle source, InstanceHandle attribute, object value, DateTime effectiveDate) protected override void SetAttributeValueInternal(InstanceHandle source, InstanceHandle attribute, object value, DateTime effectiveDate)

View File

@ -26,7 +26,7 @@ using MBS.Core;
/// </summary> /// </summary>
public class HardcodedMiniOms : MemoryOms public class HardcodedMiniOms : MemoryOms
{ {
private HardcodedMiniOms() public HardcodedMiniOms()
{ {
} }

View File

@ -4,14 +4,18 @@ namespace Mocha.Core.Tests;
public class EmbeddedMiniOms : MemoryOms public class EmbeddedMiniOms : MemoryOms
{ {
public string? SystemLibraryResourceName { get; set; } = "Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl";
protected override void InitializeInternal() protected override void InitializeInternal()
{ {
base.InitializeInternal(); base.InitializeInternal();
LibraryHandle lh = LoadLibrary(typeof(EmbeddedMiniOms), "Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl");
TenantHandle th = CreateTenant("super"); TenantHandle th = CreateTenant("super");
SelectTenant(th); SelectTenant(th);
AddLibraryReference(lh); if (SystemLibraryResourceName != null)
{
LibraryHandle lh = LoadLibrary(typeof(EmbeddedMiniOms), SystemLibraryResourceName);
AddLibraryReference(lh);
}
} }
} }

View File

@ -16,7 +16,7 @@
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>. // along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Mocha.Core.OmsImplementations;
using Mocha.Core.OmsImplementations.Mini; using Mocha.Core.OmsImplementations.Mini;
namespace Mocha.Core.Tests; namespace Mocha.Core.Tests;
@ -31,8 +31,12 @@ public class LibraryLoaderTests : OmsTestsBase
base.AfterSetup(); base.AfterSetup();
// add a reference to the other library // add a reference to the other library
LibraryHandle lhSystem = Oms.GetLibrary("Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl");
lhWeb = Oms.LoadLibrary(typeof(LibraryLoaderTests), "Mocha.Core.Tests.Resources.net.alcetech.Mocha.Web.mcl"); lhWeb = Oms.LoadLibrary(typeof(LibraryLoaderTests), "Mocha.Core.Tests.Resources.net.alcetech.Mocha.Web.mcl");
Oms.AddLibraryReference(lhWeb); Oms.AddLibraryReference(lhWeb);
((MemoryOms)Oms).__Test_AddLibraryReference_1(lhWeb, lhSystem);
} }
[Test] [Test]
@ -67,6 +71,11 @@ public class LibraryLoaderTests : OmsTestsBase
[Test] [Test]
public void Parent_Class_referenced_from_One_library_Accessible_from_Another() public void Parent_Class_referenced_from_One_library_Accessible_from_Another()
{ {
//! THIS WON'T WORK BECAUSE...
//! Parent Class referenced from another library requires a LibraryReference to the other library on the current library
//! BUT... there is no way right now to represent that in _Tenant
//! FIXME: add LibraryReferences to _Tenant and fix GetRelatedInstances etc. so that libraries can reference other libraries
// First we make sure that Class (defined in Mocha.System, which we are known to have) loads // First we make sure that Class (defined in Mocha.System, which we are known to have) loads
InstanceHandle ihClass = Oms.GetInstance(KnownInstanceGuids.Classes.Class); InstanceHandle ihClass = Oms.GetInstance(KnownInstanceGuids.Classes.Class);
Assert.That(ihClass, Is.Not.EqualTo(InstanceHandle.Empty)); Assert.That(ihClass, Is.Not.EqualTo(InstanceHandle.Empty));