Modelles dialog external vs idling event

Modelles dialog external vs idling event

sonicer
Collaborator Collaborator
2,078 Views
13 Replies
Message 1 of 14

Modelles dialog external vs idling event

sonicer
Collaborator
Collaborator

Is it better use external or idling event if I have Slider component and need move with elements?

If I move with slider need immediately move with element.

 

thx.

0 Likes
Accepted solutions (1)
2,079 Views
13 Replies
Replies (13)
Message 2 of 14

jlpgy
Advocate
Advocate

Hi:

Did you mean that you have a WPF slider control? And this Slider controls the Location of an Element?

If so:

  • Element moves after user moves a Slider: You should register Slider.ValueChanged event, and call Raise() method to raise an External Event, then move the Element inside external event.
  • Slider programmatically moves after Element is moved: You should try IUpdater

 

The above was my guess. If anything misunderstood, pls don't hesitate to enlight me. 🙂

nice coding day

单身狗;代码狗;健身狗;jolinpiggy@hotmail.com
0 Likes
Message 3 of 14

Kennan.Chen
Advocate
Advocate

From my point of view, external event and idling are more or less the same thing. They are all called by Revit internal command loop.

 

A piece of fake code to show how things are working from my understanding. It definitely is more complicated.

public class RevitCommandLoop
{
  private Queue<object> _commandQueue;
  private UIApplication _app;
  public RevitCommandLoop(UIApplication app)
  {
    _app = app;
    _commandQueue = new Queue<object>();
  }

  public event EventHandler Idling;

  public void Run()
  {
    while(true)
    {
      var command = _commandQueue.Dequeue();
      if(command is IExternalEventHandler handler)
      {
        handler.Execute(_app);
      }
      if(command is IExternalCommand exCommand)
      {
        exCommand.Execute(...{parameters for IExternalCommand.Execute})
      }
      else
      {
        // no predefined commands to run, call idling event
        OnIdling();
      }
    }
  }

  private void OnIdling()
  {
    this.Idling?.Invoke(this,EventArgs.Empty);
  }

  public void AddHandler(IExternalEventHandler handler)
  {
    _commandQueue.Enqueue(handler);
  }
  
  public void AddCommand(IExternalCommand command)
  {
    _commandQueue.Enqueue(command);
  }
}

 

0 Likes
Message 4 of 14

sonicer
Collaborator
Collaborator

Tested with modals form ..work it fine.

Now if I want to use modelles form external events work not immediately.

When I move slider need move elements... External events - It's send one times value and not repeatly.

0 Likes
Message 5 of 14

Kennan.Chen
Advocate
Advocate

You need to create a new handler each time the value changes

0 Likes
Message 6 of 14

sonicer
Collaborator
Collaborator
Accepted solution

I haved wrong code translate units from metric to imperial.

 

0 Likes
Message 7 of 14

jeremytammik
Autodesk
Autodesk

You made an interesting observation: 'From my point of view, external event and idling are more or less the same thing'.

 

A couple of years ago, if I used the Idling event repeatedly, it would hog all the processing power and slow down the system by being called too frequently. To handle that, I found the external event in combination with my own timer more useful, since that setup enabled me to control the polling frequency myself.

 

Have you observed anything similar? Does the Idling event still slow down the system if you let it run continuously? Have you used a timer to implement polling with an external event?

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 8 of 14

jlpgy
Advocate
Advocate

Ah:

You mean that the ValueChanged event triggers TOO FREQUENTLY, do you?

How about counting the elapsed time?

For example, call Raise() method only 1 time within 1 second?

 

Use System.DateTime to help.

 

单身狗;代码狗;健身狗;jolinpiggy@hotmail.com
0 Likes
Message 9 of 14

jeremytammik
Autodesk
Autodesk

The Idling event triggers as often as it possibly can.

 

That is why I prefer the external event, which enables me to call Raise at intervals, just like you suggest.

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 10 of 14

Kennan.Chen
Advocate
Advocate

It's all based on my own understanding from the API naming. Idling means nothing else to do in the current command loop. If I were to design Revit, I would make idling event the way I posted. 

 

I do think idling event slows down the system because additional code runs in the main thread in every command loop. What I've posted is to show that they run in similar way but designed for different purposes so that one can choose between them to solve similar problems.

 

I seldom use idling event in production since polling is not the first choice for most problems. I do believe Revit API exposes this event as a fallback to solve those problems not being considered at design time.

0 Likes
Message 11 of 14

Sean_Page
Collaborator
Collaborator

I would add that when using Idling events, that when you are done (ie: close your modeless form) that you remove the Idling event so it doesn't just continue to run. 

 

private void Application_Idling(object sender, IdlingEventArgs args)
        {
            EnableUpdaters(ControlID.application, "all");
            //Use a similar string as adding to stop the Idling event when no longer needed.
            ControlID.application.Idling -= Application_Idling;
        }

 

Sean Page, AIA, NCARB, LEED AP
Partner, Computational Designer, Architect
0 Likes
Message 12 of 14

Anonymous
Not applicable

Hi,

Is it possible to trigger event after closing some dialog in revit ?

0 Likes
Message 13 of 14

jeremytammik
Autodesk
Autodesk

Yes. You can raise an external event after closing your own dialog box:

 

https://www.revitapidocs.com/2020/05089477-4612-35b2-81a2-89c4f44370ea.htm

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 14 of 14

Anonymous
Not applicable
Thank you.
0 Likes