Keeping IUpdater Implementations from Triggering One Another

Keeping IUpdater Implementations from Triggering One Another

Anonymous
Not applicable
628 Views
3 Replies
Message 1 of 4

Keeping IUpdater Implementations from Triggering One Another

Anonymous
Not applicable

Is there a reliable and advised approach for handling interplay between multiple model updaters who are acting on one another's triggering elements? One of my overall objectives is bi-directional data flow between "bound" pairs of elements so the user can modify or delete either element in a pair and the updater effects changes to its mate. So of course within my main updater, I've already implemented a caseswitch variable as discussed here to avoid infinite looping. As I'm expanding the functionality though, I'm wanting to create more pairs that may overlap with one another e.g. {MEPFixtureA, GenericAnnotationA}, {GenericAnnotationA, ViewSheetA}. And that's opening up this scenario: "User modifies MEPFixtureA, so my updater1 makes changes to GenericAnnotationA. And then updater2 is being triggered by the changes to GenericAnnotationA and performing unneeded processing on it and ViewSheetA."
As I understand it, Updater2 is reinitialized with each trigger so there isn't any means to set its caseswitch variable within Updater1, but please tell me if I'm wrong. My next thought was to setup flags in Extensible Storage to mediate between the different updaters but that seems like overkill since there's no reason for that flag data to persist within the document file. I'm hoping there's some namespace level way to accomplish this that I'm unaware of. Or maybe I'm on the wrong track entirely by trying to setup multiple updaters: it seems like good coding practice to start modularizing into distinct updaters and further narrowing triggers' filters rather than continue to expand a single updater with logic to handle all element of interest, but is that true? I am interested in monitoring changes to several Revit-calculated parameters along the lines of the conversation here, so I'm forced into using changetypeany which contributes to the difficulty.
All guidance and advice are welcome--I'm just wanting to make sure I'm headed down the right path before I start radically restructuring the code and pushing ahead with development.

0 Likes
629 Views
3 Replies
Replies (3)
Message 2 of 4

Sean_Page
Collaborator
Collaborator

I use two methods that use a string value to disable and enable various updaters based on a lot of different cases most specifically when I am running automatic tasks on large data sets that I don't want interrupted.

You just need to store the UIControlledApp to call back to the main App. It is a very effective and lightweight approach.

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
Message 3 of 4

Anonymous
Not applicable

Sean, thank you, this sounds like the exact thing I'm after, but that doesn't help the fact that I don't know enough to go about actually implementing it based on your description. Would you mind doing me and the other novices who might read this a favor and elucidate a bit more with (pseudo-)code and where it belongs in order to accomplish what you're describing?

0 Likes
Message 4 of 4

Sean_Page
Collaborator
Collaborator

Sorry @Anonymous, I wasn't at my computer when I initially responded, so see the code snips below.

 

1. This is how I disable then enable the updaters from other classes when I want to skip whatever they are doing.

 

App.DisableUpdaters(App.ControlID.application, "sheets");
    //Do what needs to ignore the updater
App.EnableUpdaters(App.ControlID.application, "sheets");

 

2. Here is what the code in 'App' looks to enable them.

internal static Result EnableUpdaters(UIControlledApplication application, string name)
        {
            try
            {
                if (name == "view" || name == "all")
                {
                    Updaters.ViewUpdater viewUpdater = new Updaters.ViewUpdater(application.ActiveAddInId);
                    UpdaterRegistry.EnableUpdater(viewUpdater.GetUpdaterId());
                }

                if (name == "grid" || name == "all")
                {
                    Updaters.GridUpdater gridUpdater = new Updaters.GridUpdater(application.ActiveAddInId);
                    UpdaterRegistry.EnableUpdater(gridUpdater.GetUpdaterId());
                }

                if (name == "sheets" || name == "all")
                {
                    Updaters.ViewSheetUpdater sheetUpdater = new Updaters.ViewSheetUpdater(application.ActiveAddInId);
                    UpdaterRegistry.EnableUpdater(sheetUpdater.GetUpdaterId());
                }

                if (name == "doors" || name == "all")
                {
                    Updaters.DoorRatingUpdater doorRatingUpdater = new Updaters.DoorRatingUpdater(application.ActiveAddInId);
                    UpdaterRegistry.EnableUpdater(doorRatingUpdater.GetUpdaterId());
                }

                if (name == "walls" || name == "all")
                {
                    Updaters.WallRatingUpdater wallRatingUpdater = new Updaters.WallRatingUpdater(application.ActiveAddInId);
                    UpdaterRegistry.EnableUpdater(wallRatingUpdater.GetUpdaterId());
                }

                if (name == "rooms" || name == "all")
                {
                    Updaters.RoomOccupantUpdater roomUpdater = new Updaters.RoomOccupantUpdater(application.ActiveAddInId);
                    UpdaterRegistry.EnableUpdater(roomUpdater.GetUpdaterId());
                }

                return Result.Succeeded;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return Result.Failed;
            }
        }

 

3. Very similar to disable them.

internal static Result DisableUpdaters(UIControlledApplication application, string name)
        {
            try
            {
                if (name == "view" || name == "all")
                {
                    Updaters.ViewUpdater viewUpdater = new Updaters.ViewUpdater(application.ActiveAddInId);
                    UpdaterRegistry.DisableUpdater(viewUpdater.GetUpdaterId());
                }

                if (name == "grid" || name == "all")
                {
                    Updaters.GridUpdater gridUpdater = new Updaters.GridUpdater(application.ActiveAddInId);
                    UpdaterRegistry.DisableUpdater(gridUpdater.GetUpdaterId());
                }

                if (name == "sheets" || name == "all")
                {
                    Updaters.ViewSheetUpdater sheetUpdater = new Updaters.ViewSheetUpdater(application.ActiveAddInId);
                    UpdaterRegistry.DisableUpdater(sheetUpdater.GetUpdaterId());
                }

                if (name == "doors" || name == "all")
                {
                    Updaters.DoorRatingUpdater doorRatingUpdater = new Updaters.DoorRatingUpdater(application.ActiveAddInId);
                    UpdaterRegistry.DisableUpdater(doorRatingUpdater.GetUpdaterId());
                }

                if (name == "walls" || name == "all")
                {
                    Updaters.WallRatingUpdater wallRatingUpdater = new Updaters.WallRatingUpdater(application.ActiveAddInId);
                    UpdaterRegistry.DisableUpdater(wallRatingUpdater.GetUpdaterId());
                }

                if (name == "rooms" || name == "all")
                {
                    Updaters.RoomOccupantUpdater roomUpdater = new Updaters.RoomOccupantUpdater(application.ActiveAddInId);
                    UpdaterRegistry.DisableUpdater(roomUpdater.GetUpdaterId());
                }
                return Result.Succeeded;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return Result.Failed;
            }
        }

 

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
0 Likes