[vtk-developers] [VTK 0012044]: Order of called observers

Wes Turner wes.turner at kitware.com
Mon Apr 4 15:47:05 EDT 2011


On Mon, Apr 4, 2011 at 3:43 PM, David Cole <david.cole at kitware.com> wrote:

> People who need ordering guarantees are likely using observer priorities to
> achieve a guarantee.
>
> So.... they probably don't need ordering guarantees as much as they need
> "don't change the behavior on me for no good reason" guarantees.
>
> +1


> Changing the documentation alone would at least preserve the existing
> behavior. Changing the implementation will change the behavior, and in some
> cases, probably in a not-very-nice way. (i.e. event callbacks that used to
> be called may no longer be called if the ordering changes...)
>
> You cannot document in "AddObserver" that there is any particular order
> without taking the "focus" observers into account. So if you do document an
> enforced order, make sure the documentation is thorough.
>
>
> David C.
>
>
>
> On Mon, Apr 4, 2011 at 3:39 PM, Julien Finet <julien.finet at kitware.com>wrote:
>
>> If people didn't need ordering guarantees, then "passive", "focus" and
>> observer "priorities" wouldn't be there.
>>
>> If we define the order to be arbitrary, there is a cost associated to it.
>> People would need to enforce their order by adding extra code (increased
>> number of code, extra computation time).
>>
>> Julien.
>>
>>
>> On Mon, Apr 4, 2011 at 3:18 PM, tom fogal <tfogal at sci.utah.edu> wrote:
>>
>>> I was trying to constify that code recently, and I don't think either of
>>> the explanations is accurate.
>>>
>>> The actual ordering appears to be:
>>>
>>>  1. invoke all "passive" observers (which cannot change system state)
>>>  2. invoke "focus" observers
>>>  3. invoke anything not invoked by the above
>>>
>>> (see InvokeEvent for full info)
>>>
>>> I'd say it's better to make the order undefined... do people really need
>>> ordering guarantees (what's a use case?)?
>>>
>>> -tom
>>>
>>>
>>> On 04/04/2011 12:18 PM, Julien Finet wrote:
>>>
>>>> The question here is:
>>>>
>>>> 1) do we change the documentation and claim the order of callbacks is
>>>> undefined (fix documentation) or
>>>> 2) do we enforce that the observers are called in the order they were
>>>> added
>>>> (fix bug).
>>>>
>>>> What are benefits of the later and former solution ?
>>>>
>>>> While 1) is definitely safer, I doubt that it can be a safe long-term
>>>> solution.
>>>> Moreover, I believe that 2) has a somewhat limited impact.
>>>>
>>>> Please let us know what you think,
>>>>
>>>> Thanks,
>>>> Julien.
>>>> 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.
>>>>
>>>>
>>>> On Mon, Apr 4, 2011 at 2:15 PM, Mantis Bug Tracker<
>>>> mantis at public.kitware.com>  wrote:
>>>>
>>>>
>>>>> The following issue has been SUBMITTED.
>>>>> ======================================================================
>>>>> http://public.kitware.com/Bug/view.php?id=12044
>>>>> ======================================================================
>>>>> Reported By:                Julien Finet
>>>>> Assigned To:
>>>>> ======================================================================
>>>>> Project:                    VTK
>>>>> Issue ID:                   12044
>>>>> Category:                   (No Category)
>>>>> Reproducibility:            always
>>>>> Severity:                   major
>>>>> Priority:                   normal
>>>>> Status:                     new
>>>>> ======================================================================
>>>>> Date Submitted:             2011-04-04 14:15 EDT
>>>>> Last Modified:              2011-04-04 14:15 EDT
>>>>> ======================================================================
>>>>> Summary:                    Order of called observers
>>>>> Description:
>>>>> Nightly build documentation of vtkObject::AddObserver() says: "When
>>>>> events
>>>>> are
>>>>> invoked, the observers are called in the order they were added."
>>>>>
>>>>> However the first observer of any given priority (default 0. included)
>>>>> is
>>>>> always
>>>>> called last.
>>>>> For observers added in the following order:
>>>>> observer1
>>>>> observer2
>>>>> observer3
>>>>> observer4
>>>>>
>>>>> The actual calling order is:
>>>>> observer2
>>>>> observer3
>>>>> observer4
>>>>> observer1<- notice how the first observer is called last
>>>>>
>>>>>
>>>>> Steps to Reproduce:
>>>>> void objectModified1(vtkObject *caller,unsigned long eid, void
>>>>> *clientData,
>>>>> void
>>>>> *callData) {
>>>>>  std::cout<<  "modified1"<<  std::endl;
>>>>> }
>>>>>
>>>>> void objectModified2(vtkObject *caller,unsigned long eid, void
>>>>> *clientData,
>>>>> void
>>>>> *callData) {
>>>>>  std::cout<<  "modified2"<<  std::endl;
>>>>> }
>>>>>
>>>>> void objectModified3(vtkObject *caller,unsigned long eid, void
>>>>> *clientData,
>>>>> void
>>>>> *callData) {
>>>>>  std::cout<<  "modified3"<<  std::endl;
>>>>> }
>>>>>
>>>>> void objectModified4(vtkObject *caller,unsigned long eid, void
>>>>> *clientData,
>>>>> void
>>>>> *callData) {
>>>>>  std::cout<<  "modified4"<<  std::endl;
>>>>> }
>>>>>
>>>>> int Test(int,char *[])
>>>>> {
>>>>>  vtkObject* obj = vtkObject::New();
>>>>>
>>>>>  vtkCallbackCommand* callback1 = vtkCallbackCommand::New();
>>>>>  callback1->SetCallback(objectModified1);
>>>>>  obj->AddObserver(vtkCommand::ModifiedEvent, callback1);
>>>>>
>>>>>  vtkCallbackCommand* callback2 = vtkCallbackCommand::New();
>>>>>  callback2->SetCallback(objectModified2);
>>>>>  obj->AddObserver(vtkCommand::ModifiedEvent, callback2);
>>>>>
>>>>>  vtkCallbackCommand* callback3 = vtkCallbackCommand::New();
>>>>>  callback3->SetCallback(objectModified3);
>>>>>  obj->AddObserver(vtkCommand::ModifiedEvent, callback3);
>>>>>
>>>>>  vtkCallbackCommand* callback4 = vtkCallbackCommand::New();
>>>>>  callback4->SetCallback(objectModified4);
>>>>>  obj->AddObserver(vtkCommand::ModifiedEvent, callback4);
>>>>>
>>>>>  obj->Modified();
>>>>>
>>>>>  callback4->Delete();
>>>>>  callback3->Delete();
>>>>>  callback2->Delete();
>>>>>  callback1->Delete();
>>>>>
>>>>>  obj->Delete();
>>>>>
>>>>>  return 1;
>>>>> }
>>>>>
>>>>> Output:
>>>>> modified2
>>>>> modified3
>>>>> modified4
>>>>> modified1
>>>>>
>>>>>
>>>>> Additional Information:
>>>>> Current code (and suggested fix):
>>>>>
>>>>>
>>>>> //----------------------------------------------------------------------------
>>>>> unsigned long vtkSubjectHelper::
>>>>> AddObserver(unsigned long event, vtkCommand *cmd, float p)
>>>>> {
>>>>>  vtkObserver *elem;
>>>>>
>>>>>  // initialize the new observer element
>>>>>  elem = new vtkObserver;
>>>>>  elem->Priority = p;
>>>>>  elem->Next = NULL;
>>>>>  elem->Event = event;
>>>>>  elem->Command = cmd;
>>>>>  cmd->Register(0);
>>>>>  elem->Tag = this->Count;
>>>>>  this->Count++;
>>>>>
>>>>>  // now insert into the list
>>>>>  // if no other elements in the list then this is Start
>>>>>  if (!this->Start)
>>>>>    {
>>>>>    this->Start = elem;
>>>>>    }
>>>>>  else
>>>>>    {
>>>>>    // insert high priority first
>>>>>    vtkObserver* prev = 0;
>>>>>    vtkObserver* pos = this->Start;
>>>>>    while(pos->Priority>= elem->Priority&&  pos->Next)
>>>>>      {
>>>>>      prev = pos;
>>>>>      pos = pos->Next;
>>>>>      }
>>>>>    // pos is Start and elem should not be start
>>>>>    if(pos->Priority>  elem->Priority)   ////////////////////////// HERE
>>>>> IT
>>>>> SHOULD BE: pos->Priority>= elem->Priority
>>>>>      {
>>>>>      pos->Next = elem;
>>>>>      }
>>>>>    else
>>>>>      {
>>>>>      if(prev)
>>>>>        {
>>>>>        prev->Next = elem;
>>>>>        }
>>>>>      elem->Next = pos;
>>>>>      // check to see if the new element is the start
>>>>>      if(pos == this->Start)
>>>>>        {
>>>>>        this->Start = elem;
>>>>>        }
>>>>>      }
>>>>>    }
>>>>>  return elem->Tag;
>>>>> }
>>>>> ======================================================================
>>>>>
>>>>> Issue History
>>>>> Date Modified    Username       Field                    Change
>>>>> ======================================================================
>>>>> 2011-04-04 14:15 Julien Finet   New Issue
>>>>> ======================================================================
>>>>>
>>>>> _______________________________________________
>>>>> Powered by www.kitware.com
>>>>>
>>>>> Visit other Kitware open-source projects at
>>>>> http://www.kitware.com/opensource/opensource.html
>>>>>
>>>>> Follow this link to subscribe/unsubscribe:
>>>>> http://www.vtk.org/mailman/listinfo/vtk-developers
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> Powered by www.kitware.com
>>>>
>>>> Visit other Kitware open-source projects at
>>>> http://www.kitware.com/opensource/opensource.html
>>>>
>>>> Follow this link to subscribe/unsubscribe:
>>>> http://www.vtk.org/mailman/listinfo/vtk-developers
>>>>
>>>>
>>>
>>
>> _______________________________________________
>> Powered by www.kitware.com
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.html
>>
>> Follow this link to subscribe/unsubscribe:
>> http://www.vtk.org/mailman/listinfo/vtk-developers
>>
>>
>>
>
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtk-developers
>
>
>


-- 
Wesley D. Turner, Ph.D.
Kitware, Inc.
Technical Leader
28 Corporate Drive
Clifton Park, NY 12065-8662
Phone: 518-881-4920
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtk-developers/attachments/20110404/301ff0e1/attachment.html>


More information about the vtk-developers mailing list