Grasshopper

algorithmic modeling for Rhino

Ensure Singleton component - Place only one instance of the component at a time on the canvas

Dear all,

I am wondering what is the best way to ensure a Singleton component, that is a component which the user can only place on the canvas once, unless they delete it from the canvas and place it again.

At the moment I have the following code where I use a true or false flag to determine,whether or not the component is on the canvas.

public override void RemovedFromDocument(GH_Document document)
{
// Remove object count, so now can create another object
this.instantiated = false;

base.RemovedFromDocument(document);
}

public override void AddedToDocument(GH_Document document)
{
if (this.instantiated == true)
{
MessageBox.Show("You cannot add this component more than one " + "...");

document = this.OnPingDocument();

document.RemoveObject(this, true);
}

else
{
this.instantiated = true;

base.AddedToDocument(document);
}
}
}

However this only partially works because in the section

{
MessageBox.Show("You cannot add this component more than one " + "...");

document = this.OnPingDocument();

document.RemoveObject(this, true);
}

I cannot stop the constructor for the component from being called, so I simply have to let it be called and then remove the component afterwards.

How can I stop the constructor of the component from being called? Furthermore is there a better way of doing this?

Views: 611

Replies to This Discussion

Thanks for the advice Tom,

I'm not sure entirely what you mean but basically I am using an abstract class that inherits from GH_Param where I implement my own custom functionality then all my components inherit from this abstract class.

You cannot stop constructors from being called, although you could throw exceptions in constructors. I really wouldn't recommend that though unless you're happy about potentially crashing peoples computers.

What you need to do is detect when a component occurs more than once in a document and flag it as such when that happens. You can either override the display and draw a thick red border around it, or just use standard error messaging.

I need to deal with some administrative stuff in town today but when I get back I can write an example for you.

Thanks David!

The attached component checks for other copies of its own type whenever it solves itself. This means that an old component won't reflect the invalid state when a new component is added to the file, only the new component will show it.

This is potentially a problem and you want to make sure that this state of invalidness is shared amongst all of them.

Incidentally I also changed the attributes so that a thick coloured border is drawn around the component if all is well (just to give it something to do) and a hatched border is drawn if there's more than one component.

Attachments:

Public Function IsSingle() as Boolean
For Each obj As IGH_DocumentObject In Grasshopper.Instances.ActiveCanvas.Document 
Dim comp As GH_Component = TryCast(obj, GH_Component)
If comp IsNot Nothing Then
If comp.InstanceGuid < > Me.InstanceGuid Then
If comp.ComponentGuid = GuidsBase.Anemone04.OutOfCoreInput Then
Return False
End If
End If
End If
Next
Return True
End Sub

You can put it in the overriden BeforeSolveInstance so it runs only once instead of every instance.

You want to be careful with this:

For Each obj As IGH_DocumentObject In Grasshopper.Instances.ActiveCanvas.Document 

It's better to get the specific document your component is in:

Dim doc As GH_Document = OnPingDocument()

RSS

About

Translate

Search

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service