-
Notifications
You must be signed in to change notification settings - Fork 15
Adapter Actions
After covering the basics in Introduction to BHoM_Adapter, we can now better explain the Adapter Actions.
After reading this you should be all set to develop your own Toolkit.
Before reading this page, make sure you have read the Introduction to BHoM_Adapter.
There is a whole series of issues that the BHoM takes care of behind the curtains. For example, the BHoM checks for whether an object has been created already in the connected software, for ID duplication, if a certain action is allowed, etc.
A very common paradigm that describes all the possible action types is CRUD. This paradigm says that, regardless of the connection being made, the connection actions can be always categorized as:
- Create
- Read
- Update
- Delete
Let's do some first considerations on those actions:
-
Read and Delete are quite self-explanatory; regardless of the context, they are usually quite straightforward to implement.
-
Create and Update, on the other hand, can sometimes overlap.
Let's consider for example the case where we are pushing BHoM objects from Grasshopper to an external software. The first time those objects are pushed, we expect them to be created in the external software. The following times we expect the existing objects to be updated with the parameters specified in the new ones.
The CRUD methods are the actual methods have to be implemented in the specific Toolkits. Their scope has to be kept strictly to a minimum, as explained below.
Create must take care only of Creating, or exporting, the objects. Anything else is out of its scope.
For example, a logic that takes care of checking whether some object already exists in the External model – and, based on that, decides whether to export or not – cannot sit in the Create method, but has rather to be included in the Push. This very case (checking existing object) is actually already covered by the Push logic, as we will see later.
The main point is: keep the Create simple. It will be called when appropriate by the Push, as we will see later.
The Read has to take care of importing objects from the outside program. There are many available overloads for the Read, all of them called as appropriate by the Pull, and also by the Push, as we will see later.
The Update has to take care of copying properties from from a new version of an object (typically, the one currently being Pushed) to an old version of an object (typically, the one that has been Read from the external model).
The update will be called when appropriate by the Push, as we will see later.
The Update has to take care of deleting an object from an external model. The Delete is called when activating the Remove Adapter Action, or by the Push as we will see later.
By default, an object with multiple tags on it will not be deleted; it only will get that tag removed from itself.
This guaranties that elements created by other people/teams will not be damaged by your delete.
We can now fully understand the Adapter Actions, as we can draw the relationships with their backing CRUD methods.
The Push action is defined as follows:
public virtual List<object> Push(IEnumerable<object> objects, string tag = "", PushType pushType = PushType.AdapterDefault, ActionConfig actionConfig = null)
This method Pushes input objects using different combinations of the CRUD methods as appropriate, depending on the PushType
input.
The Push will either create, update or even delete some objects based on the category they fall in.
Let's look at the Venn diagram between the new objects being pushed and the objects with that tag already existing in the external software.
The new objects that are not found in the software will simply be created. The objects that are both found in the new and the existing set will be replaced (= Update
d). Finally, the objects that are not found in the new set are simply deleted. All objects without the matching tag will be ignored.
You can find more info on Tags in their related section of the Adapter Actions - Advanced parameters wiki page.
In practice, things are a bit complicated, since we also need to take care of merging objects that are the same even if they don't share a tag. This is why we provide a series of helper functions for the push so those implementing a new adapter don't have to solve this problem again. Since a picture is worth a thousand words, to explain this we provide a complete flow diagram of the Push below.
If you click on the image below you can find an extensive Flow Diagram that explains the whole Push.

The Pull action is defined as follows:
public virtual IEnumerable<object> Pull(IRequest request, PullType pullType = PullType.AdapterDefault, ActionConfig actionConfig = null)
This is essentially a simple call to Read and that grab all the objects corresponding to a query (IRequest
). There is some additional logic related to technicalities, for instance how we deal with different IRequests and different object types (IBHoMObject vs IObjects vs IResults, etc).
This method essentially provides a way to get objects from the external software based on a specific Request (which is essentially a query). You can find more info on Requests in their related section of the Adapter Actions - Advanced parameters wiki page.
Note that the method returns a list of object
, because the pulled objects are not necessarily BHoM objects (such as strings, numbers, but also any other type, really).
Move performs a Pull and then a Push.
It's greatly helpful in converting a model from a software to another without having to load all the data in the UI (i.e., doing separately a Pull and then a Push), which would prove too computationally heavy for larger models.
The Remove action is defined as follows:
int Remove(IRequest request, ActionConfig config = null);
This method simply calls Delete.
You might find some Toolkits that, prior to calling Delete, add some logic to the Action, for example to deal with a particular input Request.
The method returns the number of elements that have been removed from the external model.
The Execute is defined as follows:
public virtual Output<List<object>, bool> Execute(IExecuteCommand command, ActionConfig actionConfig = null)
The Execute method provides a way to ask your software to do things that are not covered by the other methods. A few possible cases are asking the tool to run some calculations, print a report, save,... A dictionary of parameters is also provided if needed. In the case of print for example, it might be the folder where the file needs to be saved and the name given to the file.
The method returns true if the command was executed successfully.
Read on our guide to build a BHoM Toolkit.
-
Introduction to the BHoM:
What is the BHoM for?
Structure of the BHoM
Technical Philosophy of the BHoM -
Getting Started:
Installing the BHoM
Using the BHoM
Submitting an Issue
Getting started for developers -
Use GitHub & Visual Studio:
Using the SCRUM Board
Resolving an Issue
Avoiding Conflicts
Creating a new Repository
Using Visual Studio
Using Visual Studio Code -
Contribute:
The oM
The Engine
The Adapter
The Toolkit
The UI
The Tests -
Guidelines:
Unit convention
Geometry
BHoM_Engine Classes
The IImmutable Interface
Handling Exceptional Events
BHoM Structural Conventions
BHoM View Quality Conventions
Code Versioning
Wiki Style
Coding Style
Null Handling
Code Attributes
Creating Icons
Changelog
Releases and Versioning
Open Sourcing Procedure
Dataset guidelines -
Foundational Interfaces:
IElement Required Extension Methods -
Continuous Integration:
Introduction
Check-PR-Builds
Check-Core
Check-Installer -
Code Compliance:
Compliance -
Further Reading:
FAQ
Structural Adapters
Mongo_Toolkit
Socket_Toolkit