Skip to content
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

Add Priority Types For Push #393

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from
Open
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
91 changes: 91 additions & 0 deletions Adapter_Engine/Query/GetPrioritySortedObjects.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@

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

/*This file is part of the Buildings and Habitats object Model (BHoM)
* Copyright (c) 2015 - 2024, 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.Engine.Base;
using BH.oM.Data;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using BH.oM.Adapter;
using BH.oM.Base.Attributes;
using BH.Engine.Reflection;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace BH.Engine.Adapter
{
public static partial class Query
{
/***************************************************/
/**** Push Support methods ****/
/***************************************************/
// These are support methods required by other methods in the Push process.

[Description("Groups of objects are sorted by priority order.")]
[Input("objects", "Objects to group and sort by priority order.")]
[Input("pushType", "PushType provided in the Push.")]
[Input("bHoMAdapter", "The PriorityTypes that define the order of the output will be gathered from this Adapter instance.")]
public static List<Tuple<Type, PushType, IEnumerable<object>>> GetPrioritySortedObjects(this List<Tuple<Type, PushType, IEnumerable<object>>> objects, PushType pushType, IBHoMAdapter bHoMAdapter)
{
List<Type> priorityTypes = bHoMAdapter?.PriorityTypes;

if(objects == null || objects.Count = 0 || priorityTypes == null || priorityTypes.Count == 0)
return objects;

List<Tuple<Type, PushType, IEnumerable<object>>> prioritySortedObjects = objects.ToList();

//Loop through the priority types backwards to ensure the first one in the list is moved to the top
for (int i = priorityTypes.Count - 1; i >= 0; i--)
{
Type current = priorityTypes[i];
//Loop through the object list backwards to keep previous sorting intact
//Intentionally skipping index 0 (j >= 1) as object will be moved there anyway
for (int j = prioritySortedObjects.Count - 1; j >= 1; j--)
{
if (prioritySortedObjects[j].Item1 == current)
{
var temp = prioritySortedObjects[j];
prioritySortedObjects.RemoveAt(j);
prioritySortedObjects.Insert(0, temp);
j++; //Increment index to test against the same index again (counteracting the j-- in the for loop) as list will have been shifted
}
}
}

return prioritySortedObjects;
}

/***************************************************/
}
}



2 changes: 2 additions & 0 deletions Adapter_oM/IBHoMAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using BH.oM.Base;
using BH.oM.Data.Requests;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
Expand All @@ -37,6 +38,7 @@ public interface IBHoMAdapter
ModuleSet AdapterModules { get; }
Dictionary<Type, object> AdapterComparers { get; }
Dictionary<Type, List<Type>> DependencyTypes { get; }
List<Type> PriorityTypes {get;}
Guid AdapterGuid { get; }

List<object> Push(IEnumerable<object> objects, string tag = "", PushType pushType = PushType.AdapterDefault, ActionConfig actionConfig = null);
Expand Down
1 change: 1 addition & 0 deletions Adapter_oM/Settings-Config/AdapterSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public class AdapterSettings : IObject

[Description("If your adapter does not define DependencyTypes, this can be set to false for performance.")]
public virtual bool HandleDependencies { get; set; } = true;
public virtual bool HandlePriorities { get; set; } = false;
GCRA101 marked this conversation as resolved.
Show resolved Hide resolved
public virtual bool UseAdapterId { get; set; } = true;
public virtual bool UseHashComparerAsDefault { get; set; } = false;
public virtual bool ProcessInMemory { get; set; } = false;
Expand Down
5 changes: 5 additions & 0 deletions BHoM_Adapter/AdapterActions/Push.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,15 @@ public virtual List<object> Push(IEnumerable<object> objects, string tag = "", P
List<Tuple<Type, PushType, IEnumerable<object>>> orderedObjects;

if(m_AdapterSettings.HandleDependencies)
{
orderedObjects = Engine.Adapter.Query.GetDependencySortedObjects(objectsToPush, pushType, this);
}
else
orderedObjects = objectsToPush.GroupBy(x => x.GetType()).Select(x => new Tuple<Type, PushType, IEnumerable<object>>(x.Key, pushType, x.Cast<object>())).ToList();


if (m_AdapterSettings.HandlePriorities)
orderedObjects = Engine.Adapter.Query.GetPrioritySortedObjects(orderedObjects, pushType, this);
// We now have objects grouped per type, and the groups are sorted following the dependency order.
foreach (var group in orderedObjects)
{
Expand Down
9 changes: 9 additions & 0 deletions BHoM_Adapter/BHoMAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ public abstract partial class BHoMAdapter : IBHoMAdapter
// {typeof(Bar), new List<Type> { typeof(ISectionProperty), typeof(Node) } }
};

public List<Type> PriorityTypes { get; protected set; } = new List<Type>()
{
// If you are using the dependency types, this only needs to cover cases that are not already handled by this system
// e.g., if Bars are set to have a dependency on Nodes, then there is no need to add them in order in the priority types
// In your adapter constructor, populate this with values like:
// {typeof(Level), typeof(Node), typeof(Bar), ...}

};

public Guid AdapterGuid { get; set; } = Guid.NewGuid();

/***************************************************/
Expand Down