Can BeforeSolveInstance prevent SolveInstance from executing?

I’m doing an Auth check in an abstract class that inherits from GH_Component, and I’d like to use BeforeSolveInstance to do the Auth check and then prevent the component from solving if Auth does not pass.

Sub-question: Is there any way to “extend” the SolveInstance using an abstract class – that is, put some code in the abstract class that will always execute at the beginning of SolveInstance without getting completely overriden by the component’s SolveInstance method? This sounds like a stupid question, but I’m going to be brave and hit the send button anyway. :slight_smile:

Thanks,
Marc

1 Like

Would this do the trick for you?

private bool m_IsAuthorized;

private void BeforeSolveInstance()
{
    m_IsAuthorized = DoTheAuthorizationCheck();
}

private void SolveInstance(... DA)
{
    if (!m_IsAuthorized) return;
    // Auth passed...
}

// Rolf

Trying to prevent SolveInstance from executing without any code in SolveInstance at all. The solution you posted is more or less the current workaround that I am using!

Cheers,
Marc

What is wrong with your current approach? I’m not sure it’s still possible to prevent SolveInstance once the component is already running. You may be able to get somewhere by throwing exceptions, but that is definitely not a better approach than aborting on a bool.

There’s nothing technically wrong with the current approach. It’s just additional code that needs to be added to every component that derives from my abstract class. I wrote the Auth check late in the game, and and had to copy paste that bool return code into 45 components, so it triggered me to ask whether or not there was a way to accomplish it in the abstract class itself.

The reason for the sub-question is this: My auth check in the abstract class happens in BeforeSolveInstance, but I have a number of components that have to override BSI for their own purposes, which wipes out the Auth check and forces me to copy paste that in for that component specifically. I know this is more a fundamental C# question, but I was looking for a way to “extend” the method as opposed to wiping it out completely.

Cheers,
Marc

I made my own superclass for Component (RILComponent) which I inherit from in Visual Studio although this still requires to actually call the base class’ method like so:

        protected override void SolveInstance(IGH_DataAccess DA)
        {
            base.SolveInstance(DA);

But, since SolveInstance doesn’t return any value, an override won’t solve your problem anyway (even if the superclass’ SolveInstance method can break, that doesn’t mean it breaks out of the overridden subclass’ SolveInstance method).

// Rolf

1 Like

This is great! Thanks for the tip. I’ve never quite grokked what base.MethodName() was doing, this makes a lot of sense. It doesn’t help for my original question re: breaking in SolveInstance, but it does help for a lot of other things.

Thanks!

Marc

So implement SolveInstance in your base class, check the bool, and if the test passes invoke an abstract protected method which will be implemented by all your derived classes. I usually append “Internal” to such a method:

protected override sealed void SolveInstance(IGH_DataAccess da)
{
  if (! validated)
    return;

  SolveInternal(da);
}

protected abstract void SolveInternal(IGH_DataAccess da);
1 Like

Interesting – thanks, I’ll have to play with this!

Cheers,
Marc

Necroposting, but found a solution @marcsyp was looking for.

Instead of overriding BeforeSolveInstance(), you can override ComputeData(). In my example the behaviour on authentication fail should be exactly the same as if the component was disabled (Locked in SDK lingo), plus helpful message.

public override void ComputeData()
{
    if (UserIsNotAuthenticated)
    {
        this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "This component is for authenticated users only");
        this.Phase = GH_SolutionPhase.Computed;
        foreach (IGH_Param param in this.Params)
        {
            param.Phase = GH_SolutionPhase.Computed;
        }
        return;
    }
    base.ComputeData();
}
2 Likes