The question here is:<div><br></div><div>1) do we change the documentation and claim the order of callbacks is undefined (fix documentation) or</div><div>2) do we enforce that the observers are called in the order they were added (fix bug).</div>

<div><br></div><div>What are benefits of the later and former solution ?</div><div><br></div><div>While 1) is definitely safer, I doubt that it can be a safe long-term solution.</div><div>Moreover, I believe that 2) has a somewhat limited impact.</div>

<div><br></div><div>Please let us know what you think,</div><div><br></div><div>Thanks,</div><div>Julien.</div><div>p.s. For information, the Qt framework was documenting an arbitrary order until the last versions 4.5, they are now (since 4.6) following the order when the connections are added.</div>

<div><br></div><br><div class="gmail_quote">On Mon, Apr 4, 2011 at 2:15 PM, Mantis Bug Tracker <span dir="ltr"><<a href="mailto:mantis@public.kitware.com">mantis@public.kitware.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<br>
The following issue has been SUBMITTED.<br>
======================================================================<br>
<a href="http://public.kitware.com/Bug/view.php?id=12044" target="_blank">http://public.kitware.com/Bug/view.php?id=12044</a><br>
======================================================================<br>
Reported By:                Julien Finet<br>
Assigned To:<br>
======================================================================<br>
Project:                    VTK<br>
Issue ID:                   12044<br>
Category:                   (No Category)<br>
Reproducibility:            always<br>
Severity:                   major<br>
Priority:                   normal<br>
Status:                     new<br>
======================================================================<br>
Date Submitted:             2011-04-04 14:15 EDT<br>
Last Modified:              2011-04-04 14:15 EDT<br>
======================================================================<br>
Summary:                    Order of called observers<br>
Description:<br>
Nightly build documentation of vtkObject::AddObserver() says: "When events are<br>
invoked, the observers are called in the order they were added."<br>
<br>
However the first observer of any given priority (default 0. included) is always<br>
called last.<br>
For observers added in the following order:<br>
observer1<br>
observer2<br>
observer3<br>
observer4<br>
<br>
The actual calling order is:<br>
observer2<br>
observer3<br>
observer4<br>
observer1  <- notice how the first observer is called last<br>
<br>
<br>
Steps to Reproduce:<br>
void objectModified1(vtkObject *caller,unsigned long eid, void *clientData, void<br>
*callData) {<br>
  std::cout << "modified1" << std::endl;<br>
}<br>
<br>
void objectModified2(vtkObject *caller,unsigned long eid, void *clientData, void<br>
*callData) {<br>
  std::cout << "modified2" << std::endl;<br>
}<br>
<br>
void objectModified3(vtkObject *caller,unsigned long eid, void *clientData, void<br>
*callData) {<br>
  std::cout << "modified3" << std::endl;<br>
}<br>
<br>
void objectModified4(vtkObject *caller,unsigned long eid, void *clientData, void<br>
*callData) {<br>
  std::cout << "modified4" << std::endl;<br>
}<br>
<br>
int Test(int,char *[])<br>
{<br>
  vtkObject* obj = vtkObject::New();<br>
<br>
  vtkCallbackCommand* callback1 = vtkCallbackCommand::New();<br>
  callback1->SetCallback(objectModified1);<br>
  obj->AddObserver(vtkCommand::ModifiedEvent, callback1);<br>
<br>
  vtkCallbackCommand* callback2 = vtkCallbackCommand::New();<br>
  callback2->SetCallback(objectModified2);<br>
  obj->AddObserver(vtkCommand::ModifiedEvent, callback2);<br>
<br>
  vtkCallbackCommand* callback3 = vtkCallbackCommand::New();<br>
  callback3->SetCallback(objectModified3);<br>
  obj->AddObserver(vtkCommand::ModifiedEvent, callback3);<br>
<br>
  vtkCallbackCommand* callback4 = vtkCallbackCommand::New();<br>
  callback4->SetCallback(objectModified4);<br>
  obj->AddObserver(vtkCommand::ModifiedEvent, callback4);<br>
<br>
  obj->Modified();<br>
<br>
  callback4->Delete();<br>
  callback3->Delete();<br>
  callback2->Delete();<br>
  callback1->Delete();<br>
<br>
  obj->Delete();<br>
<br>
  return 1;<br>
}<br>
<br>
Output:<br>
modified2<br>
modified3<br>
modified4<br>
modified1<br>
<br>
<br>
Additional Information:<br>
Current code (and suggested fix):<br>
//----------------------------------------------------------------------------<br>
unsigned long vtkSubjectHelper::<br>
AddObserver(unsigned long event, vtkCommand *cmd, float p)<br>
{<br>
  vtkObserver *elem;<br>
<br>
  // initialize the new observer element<br>
  elem = new vtkObserver;<br>
  elem->Priority = p;<br>
  elem->Next = NULL;<br>
  elem->Event = event;<br>
  elem->Command = cmd;<br>
  cmd->Register(0);<br>
  elem->Tag = this->Count;<br>
  this->Count++;<br>
<br>
  // now insert into the list<br>
  // if no other elements in the list then this is Start<br>
  if (!this->Start)<br>
    {<br>
    this->Start = elem;<br>
    }<br>
  else<br>
    {<br>
    // insert high priority first<br>
    vtkObserver* prev = 0;<br>
    vtkObserver* pos = this->Start;<br>
    while(pos->Priority >= elem->Priority && pos->Next)<br>
      {<br>
      prev = pos;<br>
      pos = pos->Next;<br>
      }<br>
    // pos is Start and elem should not be start<br>
    if(pos->Priority > elem->Priority)   ////////////////////////// HERE IT<br>
SHOULD BE: pos->Priority >= elem->Priority<br>
      {<br>
      pos->Next = elem;<br>
      }<br>
    else<br>
      {<br>
      if(prev)<br>
        {<br>
        prev->Next = elem;<br>
        }<br>
      elem->Next = pos;<br>
      // check to see if the new element is the start<br>
      if(pos == this->Start)<br>
        {<br>
        this->Start = elem;<br>
        }<br>
      }<br>
    }<br>
  return elem->Tag;<br>
}<br>
======================================================================<br>
<br>
Issue History<br>
Date Modified    Username       Field                    Change<br>
======================================================================<br>
2011-04-04 14:15 Julien Finet   New Issue<br>
======================================================================<br>
<br>
_______________________________________________<br>
Powered by <a href="http://www.kitware.com" target="_blank">www.kitware.com</a><br>
<br>
Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a href="http://www.vtk.org/mailman/listinfo/vtk-developers" target="_blank">http://www.vtk.org/mailman/listinfo/vtk-developers</a><br>
<br>
</blockquote></div><br>