If people didn't need ordering guarantees, then "passive", "focus" and observer "priorities" wouldn't be there. <div><br></div><div>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).</div>
<div><br></div><div>Julien.<br><br><div class="gmail_quote">On Mon, Apr 4, 2011 at 3:18 PM, tom fogal <span dir="ltr"><<a href="mailto:tfogal@sci.utah.edu">tfogal@sci.utah.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
I was trying to constify that code recently, and I don't think either of the explanations is accurate.<br>
<br>
The actual ordering appears to be:<br>
<br>
1. invoke all "passive" observers (which cannot change system state)<br>
2. invoke "focus" observers<br>
3. invoke anything not invoked by the above<br>
<br>
(see InvokeEvent for full info)<br>
<br>
I'd say it's better to make the order undefined... do people really need ordering guarantees (what's a use case?)?<br><font color="#888888">
<br>
-tom</font><div><div></div><div class="h5"><br>
<br>
On 04/04/2011 12:18 PM, Julien Finet wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The question here is:<br>
<br>
1) do we change the documentation and claim the order of callbacks is<br>
undefined (fix documentation) or<br>
2) do we enforce that the observers are called in the order they were added<br>
(fix bug).<br>
<br>
What are benefits of the later and former solution ?<br>
<br>
While 1) is definitely safer, I doubt that it can be a safe long-term<br>
solution.<br>
Moreover, I believe that 2) has a somewhat limited impact.<br>
<br>
Please let us know what you think,<br>
<br>
Thanks,<br>
Julien.<br>
p.s. For information, the Qt framework was documenting an arbitrary order<br>
until the last versions 4.5, they are now (since 4.6) following the order<br>
when the connections are added.<br>
<br>
<br>
On Mon, Apr 4, 2011 at 2:15 PM, Mantis Bug Tracker<<br>
<a href="mailto:mantis@public.kitware.com" target="_blank">mantis@public.kitware.com</a>> wrote:<br>
<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<br>
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<br>
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,<br>
void<br>
*callData) {<br>
std::cout<< "modified1"<< std::endl;<br>
}<br>
<br>
void objectModified2(vtkObject *caller,unsigned long eid, void *clientData,<br>
void<br>
*callData) {<br>
std::cout<< "modified2"<< std::endl;<br>
}<br>
<br>
void objectModified3(vtkObject *caller,unsigned long eid, void *clientData,<br>
void<br>
*callData) {<br>
std::cout<< "modified3"<< std::endl;<br>
}<br>
<br>
void objectModified4(vtkObject *caller,unsigned long eid, void *clientData,<br>
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>
//----------------------------------------------------------------------------<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<br>
<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>
<br>
</blockquote>
<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>
<br>
</div></div></blockquote></div><br></div>