improvements to SS - Select from Instance Set Method

This commit is contained in:
Michael Becker 2025-10-17 23:02:50 -04:00
parent ce7dd5f949
commit c648b3c6ad
3 changed files with 86 additions and 27 deletions

View File

@ -462,6 +462,7 @@ namespace Mocha.Core
{
public static Guid Minimum { get; } = new Guid("{1ff7be8c-fe48-4154-9028-8ee84b7dc367}");
public static Guid Maximum { get; } = new Guid("{dda6c31d-5bea-41a9-a6bc-0e5c189784da}");
public static Guid First { get; } = new Guid("{4a196b8f-ca55-4f3a-a443-f960bfdb3bc6}");
}
public static class RelationalOperators
{

View File

@ -15,9 +15,6 @@
// 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 System.ComponentModel.Design;
using Mocha.Core.Oop;
namespace Mocha.Core.MethodImplementations;
public class SelectFromInstanceSetMethodImplementation : MethodImplementation
@ -27,10 +24,16 @@ public class SelectFromInstanceSetMethodImplementation : MethodImplementation
public string Order;
public object Data;
}
private struct OrderableData<T>
{
public string Order;
public T Data;
}
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.SelectFromInstanceSetMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{
//! FIXME !
Guid methodId = oms.GetGlobalIdentifier(method);
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));
@ -43,32 +46,31 @@ public class SelectFromInstanceSetMethodImplementation : MethodImplementation
}
InstanceHandle usesInstanceSet = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Select_from_Instance_Set_Method__uses__Executable_returning_Instance_Set));
object? instanceSetValues = context.GetWorkData(usesInstanceSet);
// object? instanceSetValues = context.GetWorkData(usesInstanceSet);
object? instanceSetValues = oms.Evaluate(context, usesInstanceSet, InstanceHandle.Empty);
InstanceHandle selectionFunction = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Select_from_Instance_Set_Method__uses__Selection_Function));
InstanceHandle setFunction = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Select_from_Instance_Set_Method__uses__Set_Function));
InstanceHandle orderAttribute = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Select_from_Instance_Set_Method__uses_order__Executable_returning_Attribute));
List<OrderableData> list = new List<OrderableData>();
List<OrderableData<IInstanceReference>> list = new List<OrderableData<IInstanceReference>>();
if (instanceSetValues is IEnumerable<InstanceHandle>)
if (instanceSetValues is System.Collections.IEnumerable ie)
{
}
else if (instanceSetValues is IEnumerable<InstanceWrapper>)
{
IEnumerable<InstanceWrapper> vals = (IEnumerable<InstanceWrapper>)instanceSetValues;
foreach (InstanceWrapper inst in vals)
// here we use the non-generic IEnumerable so we can handle cases where
// you would pass in an IEnumerable<IInstanceReference>, IEnumerable<InstanceHandle>,
// or IEnumerable<InstanceWrapper>. Hell, you could even pass in an IEnumerable<object>
// as long as each element in the IEnumerable was some sort of IInstanceReference!
foreach (object o in ie)
{
if (inst != null)
if (o is IInstanceReference ir)
{
OrderableData od = new OrderableData();
od.Data = inst.GetHandle();
OrderableData<IInstanceReference> od = new OrderableData<IInstanceReference>();
od.Data = ir.GetHandle();
if (orderAttribute != InstanceHandle.Empty)
{
InstanceHandle ihWorkData = oms.Execute(context, orderAttribute, inst.GetHandle());
string order = context.GetWorkData<string>(ihWorkData);
InstanceHandle ihWorkData = oms.Execute(context, orderAttribute, ir.GetHandle());
string order = context.GetWorkData<string>(ihWorkData, String.Empty);
od.Order = order;
}
else
@ -79,23 +81,40 @@ public class SelectFromInstanceSetMethodImplementation : MethodImplementation
}
else
{
// throw new NotSupportedException();
// design decision: should we silently exclude non-IInstanceReference items since we could
// theoretically support IEnumerable<object>? or should we force users to do the Right Thing(tm)?
}
}
list.Sort((c, d) => c.Order.CompareTo(d.Order));
}
list.Sort((c, d) => c.Order.CompareTo(d.Order));
if (list.Count > 0)
{
// FIXME: this assumes a hardcoded singular work set
if (selectionFunction == oms.GetInstance(KnownInstanceGuids.SelectionFunctions.Minimum))
bool returnsWorkSetIsSingular = oms.GetAttributeValue<bool>(returnsWorkSet, oms.GetInstance(KnownAttributeGuids.Boolean.Singular));
IEnumerable<InstanceHandle> retval = [ ];
if (selectionFunction == oms.GetInstance(KnownInstanceGuids.SelectionFunctions.First))
{
context.SetWorkData(returnsWorkSet, list[0].Data);
retval = [ list.First().Data.GetHandle() ];
}
// FIXME: this assumes a hardcoded singular work set
else if (selectionFunction == oms.GetInstance(KnownInstanceGuids.SelectionFunctions.Minimum))
{
retval = [ list.First().Data.GetHandle() ];
}
else if (selectionFunction == oms.GetInstance(KnownInstanceGuids.SelectionFunctions.Maximum))
{
context.SetWorkData(returnsWorkSet, list[list.Count - 1].Data);
retval = [ list.Last().Data.GetHandle() ];
}
if (returnsWorkSetIsSingular)
{
context.SetWorkData(returnsWorkSet, retval.First());
}
else
{
context.SetWorkData(returnsWorkSet, retval);
}
}
return returnsWorkSet;

View File

@ -30,7 +30,7 @@ public class SelectFromInstanceSetMethodTests : MethodTestsBase
// MethodReturningInstanceSet m_Access_Modifier__get__Most_Restrictive_from_Set = (MethodReturningInstanceSet) Oms.GetMethod(c_AccessModifier, "get", "Most Restrictive from Set");
InstanceHandle a_Order = Oms.GetInstance(KnownAttributeGuids.Text.Order);
WorkSet ws_Access_Modifier__Nonsingular = Oms.CreateWorkSet("Access Modifier [Nonsingular]", false);
WorkSet ws_Access_Modifier__Singular = Oms.CreateWorkSet("Access Modifier [Singular]", true);
@ -38,7 +38,7 @@ public class SelectFromInstanceSetMethodTests : MethodTestsBase
GetAttributeMethod get_Order = methodBuilder.CreateGetAttributeMethod(c_AccessModifier, "get", "Order", a_Order);
SelectFromInstanceSetMethod m_Access_Modifier__get__Most_Restrictive_from_Set = methodBuilder.CreateSelectFromInstanceSetMethod(c_AccessModifier, "get", "Most Restrictive from Set", AccessModifier.Public, true, ws_Access_Modifier__Singular, ws_Access_Modifier__Nonsingular, null, Oms.GetInstance(KnownInstanceGuids.SelectionFunctions.Minimum), get_Order.GetHandle());
if (m_Access_Modifier__get__Most_Restrictive_from_Set != null)
{
ReturnInstanceSetMethodBinding rsmb = m_Access_Modifier__get__Most_Restrictive_from_Set.CreateMethodBinding(Oms);
@ -59,4 +59,43 @@ public class SelectFromInstanceSetMethodTests : MethodTestsBase
Assert.That((InstanceHandle?)value, Is.EqualTo(AccessModifier.Private.GetHandle()));
}
}
[Test]
public void Element__get__First_Element_Content()
{
Class c_Element = Oms.GetInstance<Class>(KnownInstanceGuids.Classes.Element);
Class c_ElementContent = Oms.GetInstance<Class>(KnownInstanceGuids.Classes.ElementContent);
GetRelationshipMethod m_Element__get__Element_Contents = Oms.MethodBuilder.CreateGetRelationshipMethod(c_Element, "get", "Element Contents", AccessModifier.Public, Oms.GetInstance(KnownRelationshipGuids.Element__has__Element_Content));
ReturnInstanceSetMethodBinding Element__get__Element_Contents = m_Element__get__Element_Contents.CreateMethodBinding(Oms);
GetAttributeMethod m_getOrder = Oms.MethodBuilder.CreateGetAttributeMethod(c_ElementContent, "get", "Order", Oms.GetInstance(KnownAttributeGuids.Text.Order));
ReturnAttributeMethodBinding Element_Content__get__Order = m_getOrder.CreateMethodBinding(Oms);
WorkSet wsE = Oms.CreateWorkSet("Returned Element Content [Singular]");
Oms.SetAttributeValue(wsE, Oms.GetInstance(KnownAttributeGuids.Boolean.Singular), true);
SelectFromInstanceSetMethod m_getFirstElementContent = Oms.MethodBuilder.CreateSelectFromInstanceSetMethod(c_Element, "get", "First Element Content", AccessModifier.Public, false, wsE, Element__get__Element_Contents, null, Oms.GetInstance(KnownInstanceGuids.SelectionFunctions.First), Element_Content__get__Order);
ReturnInstanceSetMethodBinding getFirstElementContent = m_getFirstElementContent.CreateMethodBinding(Oms);
InstanceHandle element = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.Element));
InstanceHandle ec1 = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.ElementContent));
InstanceHandle ec2 = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.ElementContent));
InstanceHandle ec3 = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.ElementContent));
InstanceHandle ec4 = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.ElementContent));
InstanceHandle ec5 = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.ElementContent));
Oms.AssignRelationship(element, Oms.GetInstance(KnownRelationshipGuids.Element__has__Element_Content), new InstanceHandle[]
{
ec1, ec2, ec3, ec4, ec5
});
OmsContext context = Oms.CreateContext();
context.SetWorkData(c_Element, element);
InstanceHandle ws = Oms.Execute(context, getFirstElementContent);
object? obj = context.GetWorkData(ws);
Assert.That(obj, Is.EqualTo(ec1));
}
}