Storing two archivable dictionaries as plugin data


#1

Hello
I am trying to read plugin data like this:

private ArchivableDictionary _docGlobalDatabase;
private ArchivableDictionary _docLocalDatabase;

    public ShipWizardPlugIn()
    {
        _docGlobalDatabase = new ArchivableDictionary(1, "GlobalDatabase");
        _docLocalDatabase = new ArchivableDictionary(1, LocalDatabase");
        Instance = this;
    }
    ///<summary>Gets the only instance of the SPlugIn plug-in.</summary>
    public static SPlugIn Instance
    {
        get;
        private set;
    }
    // You can override methods here to change the plug-in behavior on
    // loading and shut down, add options pages to the Rhino _Option command
    // and mantain plug-in wide options in a document.
    protected override Rhino.PlugIns.LoadReturnCode OnLoad(ref string errorMessage)
    {
        //Register DefaultPanel
        System.Type panelType = typeof(DefaultPanel);
        Rhino.UI.Panels.RegisterPanel(this, panelType, "S", System.Drawing.SystemIcons.Question);
        //Document user data preparation
        Rhino.RhinoDoc.NewDocument += new EventHandler<DocumentEventArgs>(RhinoDoc_NewDocument);
        Rhino.RhinoDoc.BeginOpenDocument += new EventHandler<DocumentOpenEventArgs>(RhinoDoc_BeginOpenDocument);
        return Rhino.PlugIns.LoadReturnCode.Success;
    }
    private void RhinoDoc_BeginOpenDocument(object sender, DocumentOpenEventArgs e)
    {
        // A new document is being created, so clear out our string table
        _docGlobalDatabase.Clear();
        _docLocalDatabase.Clear();
    }
    private void RhinoDoc_NewDocument(object sender, DocumentEventArgs e)
    {
        // A new document is being opened, so clear out our string table
        _docGlobalDatabase.Clear();
        _docLocalDatabase.Clear();
    }
    /// <summary>
    /// The tabbed dockbar user control
    /// </summary>
    public DefaultPanel UserControl
    {
        get;
        set;
    }
    #region Document user data overrides
    protected override bool ShouldCallWriteDocument(FileWriteOptions options)
    {
        // Only write document data if there is something to write
        bool rc = (_docGlobalDatabase != null || _docLocalDatabase != null) ? true : false;
        return rc;
    }
    protected override void WriteDocument(RhinoDoc doc, BinaryArchiveWriter archive, FileWriteOptions options)
    {
        // Write plug-in document dictionary
        archive.WriteDictionary(_docGlobalDatabase);
        archive.WriteDictionary(_docLocalDatabase);
    }
    protected override void ReadDocument(RhinoDoc doc, BinaryArchiveReader archive, FileReadOptions options)
    {
        // Read plug-in document data.
        //Read only if not opening new file, otherwise clear dictionary
        bool bKeepData = (options.NewMode || options.OpenMode) ? true : false;
        if (bKeepData == true)
        {
            _docGlobalDatabase.Clear();
            _docLocalDatabase.Clear();
        }
        _docGlobalDatabase = archive.ReadDictionary();
        _docLocalDatabase = archive.ReadDictionary();
    }

It works provided that I have only GlobaDatabase. If I add LocalDatabase it crashes when opening new file.
It gives exception:

An exception of type ‘Rhino.FileIO.BinaryArchiveException’ occurred in RhinoCommon.dll but was not handled in user code

Additional information: ReadDictionary failed

I just realized that I try to read the same dictionary twice. Is it even possible to store 2 different dictionaries or should I make a third one containing 2 others just for writing to file and then split it when reading?


(Dale Fugier) #2

Hi Mike,

I cooked up a similar scenario here and it seems to work (see attached).

TestKillwater.zip (4.2 KB)

– Dale


#3

Hello Dale
Thank you very much. Your example works indeed.
I have been trying to find the bug and it turned out that a few of my testing 3dm files got corrupted which is very worrying. When I opened them, ignored the error and saved them everything started to work fine…