Skip to content
Alessio Lombardi edited this page Feb 18, 2020 · 36 revisions

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.


⚠️ Note ⚠️

Before reading this page, make sure you have read the Introduction to BHoM_Adapter.




Contents




How the Adapter Actions work

The CRUD paradigm

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.

CRUD methods description

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

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.

Read

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.

Update

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.

Delete

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.

Note: Deletion of objects with tag

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.

Adapter actions: description in terms of CRUD

We can now fully understand the Adapter Actions, as we can draw the relationships with their backing CRUD methods.

Push

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.

image

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 (= Updated). 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.

Complete flow diagram of the Push

If you click on the image below you can find an extensive Flow Diagram that explains the whole Push.

Pull

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).

image

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

Move performs a Pull and then a Push.

image

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.

image

Remove

The Remove action is defined as follows:

int Remove(IRequest request, ActionConfig config = null);

This method simply calls Delete.

image

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.

Execute

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.

How to Create Your Own Adapter?

Read on our guide to build a BHoM Toolkit.

Clone this wiki locally