Creating a hidden pre-computation component

I’m writing a Grasshopper c# wrapper for some cpp functions.
There are some functions that share some pre-computed data. In cpp, I can store it somewhere and call it when needed.

The question now is how to do it in the Grasshopper c# component.
If I do the pre-computation within the component, it means the computation will be conducted every time I change some parameters…

If I create a separate component, how can I pass a customised class between components?
Or is it possible to have a class that contains the necessary data behind the scene (now shown on canvas, but created and stored once I run a component for the first time).

No, it doesn’t have to be like this. It’s a matter of logic and not a language or library “feature”.

There are many ways of doing it. You can pass it over the wires or behind the scenes by e.g. a static dictionary, as a service- or by implementing certain programming patterns such as “observer”.

I’m not quite understanding what the issue is in detail. C# is as powerful as C++. You can even write the whole wrapper in C#, although this is quite advanced. There is simply not the one-right-way of doing it.

Thanks for the reply.

I guess my question is not about c#, but how this static dictionary would work in GH without exposing it – A “service” run alongside and only re-compute in certain scenario.

For instance, I have a mesh processing component with different parameters.
The precomputation is only needed to run once for the mesh, unless another mesh is used.
But the parameters can be changed freely.

I want to avoid the case that whenever I change the parameters, the precomputation is run again…

By the way you should notice the “pre-processing” component may not run BEFORE the actual computing component, without no (in)direct wires between them.

I haven’t compiled or tested the code, but it’s one way of achieving what you want. I think you get the idea…

        private static Dictionary<Guid, Mesh> _precomputedMeshes = new Dictionary<Guid, Mesh>();
       
        public void SolveInstance()
        {
            if (RequiresPrecomputation(InstanceGuid))
            {
                Precompute(InstanceGuid);
            }
            
             Mesh mesh =   GetPrecomputedMesh(InstanceGuid);
            
        }

        public bool RequiresPrecomputation(Guid componentKey)
        {
            return !_precomputedMeshes.ContainsKey(componentKey);            
        }

        public void Precompute(Guid componentKey)
        {
            //...
            _precomputedMeshes.Add(componentKey, mesh);
        }

        public Mesh GetPrecomputedMesh(Guid componentKey)
        {
            return _precomputedMeshes[componentKey];
        }

This concept is basically also known as “caching”

1 Like

Edit: There is one thing you should note here. Creating a static dictionary is a global variable. Now, depending on what you do, you are in charge of removing cached data once it’s not required anymore. Otherwise, it will stay in memory for the whole time. Therefore, a good idea is to put the whole logic into a class which is responsible for managing this cache. So in any case, its a potential candidate for a memory leak. Watch memory consumption when testing!

1 Like

So static class created by GH component will not be deleted once GH is closed?

Fortunately, it will always be freed once the hosting process is closed (=Rhino). But just imagine you process lots of data and you are not cleaning it up, then your memory consumption rises and rises…
In C# it will be sufficient to remove the mesh from the static dictionary. The GC will take care of it for you.

Unless its managed code you process, then you are also in charge of freeing the allocated memory on the heap, or if your class implements the IDisposable interface (which basically means always call the Dispose method once you are not required to use this object anymore (Streaming is one common use-case)

1 Like

What if the pre-computed class is a cpp class (customized defined)…
Is it that I have to look into the class and find a way to bring it into the c# with proper constructor?

Or more specifically, the class that I’d like to store only exist in the cpp side, I don’t need to bring it into the c#, but need to store it somewhere so that it lives in the lifecycle of the pre-compute component.

I don’t know what you are trying to do. But you should either write a bit of C# with lots of C++ or you write C++ with bits of C#. You cannot simply take a unmanaged C++ class instance and put it into a C# dictionary. So it’s not that you can flip languages just as you like without any overheat and without overcomplicating your source code. If it’s super important to write in C++ write a simple “facade”. A very slim and simple wrapper to submit and receive data from your C++ code. Again there are thousands of ways of achieving it, but I can only warn you from creating workarounds and hacks, just because you need some super fancy C++ library. You can also have a complete standalone C++ app and just use inter-process communication to communicate. It’s really up to what you do in detail. But I’m not an expert for this.

Thanks.
I got it resolved temporarily by creating a c# pointer handle to a c++ class in memory.