Best place for a document-specific object store to live

For every object in the scene I want to keep a corresponding instance of MyClass in memory. When new objects are added, deleted, or existing objects are changed, I want to update the corresponding instance.
Right now I have a dict with RhinoObject Guid’s as keys, and MyClass as values. That part works great.

Where is the best place for such a store to live? On the Plugin instance? How should I handle RhinoDoc changes then? Especially I saw a comment in the docs, mentioning RhinoDoc could change on Mac: when does this happen?
How can I ensure my store is scene/document-specific?

Follow up question: am I correct in accessing such a store on the Plugin instance like so:

public class MyOtherClass {
    public MyPlugin MyPlugin;
    public MyStore MyStore { get => MyPlugIn.MyStore; }

    public MyOtherClass() {
        // Find the Plugin instance
        Guid guid = PlugIn.IdFromName("MyPluginName");
        MyPlugIn = (MyPlugin)PlugIn.Find(guid);
    }
}

Hi @aske,

You have several options.

You’ve mentioned the first one, which is to store your data on your plug-in object.

Or, you can use a singleton. For example:

public class MyDataTable
{
  /// <summary>
  /// Private constructor
  /// </summary>
  private MyDataTable() {}

  /// <summary>
  /// The one and only MyDataTable object
  /// </summary>
  private static MyDataTable g_my_table;

  /// <summary>
  /// Returns the one and only MyDataTable object
  /// </summary>
  public static MyDataTable Instance => g_my_table ?? (g_my_table = new MyDataTable());
}

Or, you can store your table in the Rhino document runtime dictionary. For example:

public class MyDataTable
{
  /// <summary>
  /// Public constructor
  /// </summary>
  public MyDataTable(uint documentSerialNumber)
  {
    DocumentSerialNumber = documentSerialNumber;
  }

  /// <summary>
  /// The runtime serial number of the document that owns this table.
  /// </summary>
  public uint DocumentSerialNumber { get; }

  /// <summary>
  /// The document that owns this table.
  /// </summary>
  public RhinoDoc Document => RhinoDoc.FromRuntimeSerialNumber(DocumentSerialNumber);
}

//...

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
  var my_table = doc.RuntimeData.GetValue(typeof(MyDataTable), rhinoDoc => new MyDataTable(rhinoDoc.RuntimeSerialNumber));
  if (null != my_table)
  {
    // TODO...
  }
  return Result.Success;
}

Their may be other ways too.

There are a number of document-related events you can subscribe to.

The Mac support multiple documents. So if you intend your plug-in to run in Rhino for Mac, then you need to ensure your plug-in data takes multiple documents into account. A good way of doing this is to store your data in the document’s runtime dictionary (as I have shown above).

Does this help?

– Dale

1 Like

Thanks for the great writeup Dale!
I did my quick and dirty implementation on the plugin. I’ll move it to the runtime dictionary as suggested.