Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » GEF » DirectEditManger and UpdateManager
DirectEditManger and UpdateManager [message #233481] Wed, 25 April 2007 18:27 Go to next message
Jens von Pilgrim is currently offline Jens von PilgrimFriend
Messages: 313
Registered: July 2009
Senior Member
Hi,

I've implemented a GEF version using a Java3D based Draw2D version (see
http://gef3d.org). For making this work I had to change a lot of
things, of course. So far everything worked pretty fine, but now I run
into a weird problem concerning the DirectEditManager and the
UpdateManager, i.e. the DeferredUpdateManager.
I know: I'm asking a question here about the code I wrote by myself...
but maybe someone can figure out a solution because of some tricky GEF
mechanism which may be involved here.

Since Java3D uses a scenegraph (and OpenGL for rendering), there's
usually no need to really repaint a figure, since this is done by
Java3D. In some cases, e.g. layout, a figure needs to be invalidated in
order to update its layout. All these things work fine (as far as I've
tested them). I didn't changed the DeferredUpdateManager and all
repainting and invalidating stuff. Maybe I have to write my own
UpdateManager, since Java3D uses it's own update mechanism, but for a
prototype this works pretty well. But back to the problem.

So I can add new nodes, move them around, create connections and all
the things which are needed in a graphical editor. Especially
selecting nodes is working pretty well. But for some reason I don't
know yet things become weird after a direct edit was performed. Since
Java3D is AWT based and placing a widget over a 3D label doesn't looks
well, I implemented a new direct edit system. So I added a editor
figure, which is activated by my own DirectEditManager. The mechanism
is just like the original DirectEditManager, I'd thought (e.g. using
methods show and bringDown etc.) . But after editing a text, and after
the model is updated, my selection handles are not placed by the
RelativeHandleLocator anymore. That is the handles are drawn, but since
their validate method isn't called, they are not relocated. Before a
direct edit was performed this worked!

I spent quite some time on debugging this problem, and so far I managed
to get a rough image what's happening. It seems as if my
DirectEditManager somehow changes some state in an underlying class
(the update manager, the lightweight system, I don't know) but I don't
know exactly which and where. Figures are still added to the list of
invalid figures in the update manager, but no validation is actually
performed. I tried to force this (as a hack) in my direct edit manager
by calling the EditPartViewer.flush(). But since some underlying state
is false, this doesn't really helps. Selecting different nodes will
always fail after the direct edit was performed.
After adding a new node to the drawing, everything works fine again!
This is why I assume that there must be some state which becomes
invalid due to my DirectEditManager.

Since debugging all this validation and updating stuff is very
complicated, I'm wondering if someone may has an idea of what I could
have done wrong. DirectEditManager works a little bit like a Tool
without actually being a tool -- is it possible that I have to call
some method which is usually automatically called by a tool's super
class? I'm not sure but I also recognize a little odd behaviour in
"original" GEF editors, which may have the same reason: When a figure
(with text) is created and selected the very first time, direct edit is
activated by one click only, that is no double click. After editing the
text, a double click is required again.

Or is there at least any documentation about the UpdateManager (i.e.
the DeferredUpdateManager) and how all this validation and updating
works?

Jens
Re: DirectEditManger and UpdateManager [message #233518 is a reply to message #233481] Wed, 25 April 2007 22:57 Go to previous messageGo to next message
Alex Boyko is currently offline Alex BoykoFriend
Messages: 200
Registered: July 2009
Senior Member
Hi,

It's odd that invalid figures aren't validated. Once a figure becomes
invalid it's added to the list of invalid figures in the update manager
and the update manager schedules validation as an async display message.
Hence, validation will occur once this message is handled by the display
object. Once figures are validated a rectangle that needs to be repainted
is constructed based on invalid figures and paint is scheduled and invalid
figures are redrawn.
Just to verify that figures aren't validated you could debug
DeferredUpdateManager#performUpdate() to check why invalid figures aren't
validated.

Cheers,
Alex
Re: DirectEditManger and UpdateManager [message #233545 is a reply to message #233518] Thu, 26 April 2007 12:19 Go to previous messageGo to next message
Jens von Pilgrim is currently offline Jens von PilgrimFriend
Messages: 313
Registered: July 2009
Senior Member
Hi,

at least I found why figures aren't validated anymore. I assume that
the reason leading to this situation is something in my code, but I
think that there is a little bug in the DeferredUpdateManager, too.

So, what happens in a usual case:

DeferredUpdateManager.addInvalidFigure is called. This usually causes
to perform a validation.

But there are some extra conditions checked in the
DeferredUpdateManager which can cause a kind of deadlock: This happens
then
"updatedQueued" semaphore is set. I will explain that using the
sequence started after addInvalidFigure has been called. In my case,
it's the root figure of the lightweight system:

public synchronized void addInvalidFigure(IFigure f) {
if (invalidFigures.contains(f)) return; --> lwsrootfigure not in list,
no return
queueWork(); --> let's examine that:

protected void queueWork() {
if (!updateQueued) { --> ok, let's say its updatedQueued=true
sendUpdateRequest(); --> so this code is skipped!
updateQueued = true;
}
}

--> no validation was performed!

invalidFigures.add(f); --> figure is added om
addInvalidFigure
}

OK, that's the problem in the first place. But now the problem is
passed through to all following calls.
Let's perform another user action causing something to be invalid. In
my case of selecting a figure this is always the lwsrootfigure. We
start again in addInvalidFigure. Remember: This figure wasn't validated
since updateQueue was true in the previous call! So we try to validate
it in a second call:

public synchronized void addInvalidFigure(IFigure f) {
if (invalidFigures.contains(f)) return; --> UUps, lwsrootfigure is
already in the list, so return
}

OK -- and that's my problem!

Regardless of the updatedQueue-deadlock, there seems to be an odd
behaviour: A figure is validated if another figure is added as an
invalid figure. This is why everything works in my case after a new
node was added to the drawing, since here another figure becomes
invalid causing the previously invalidated figure to get validated.
Since queueWork() doesn't indicate that sending the update request
failed I cannot handle this situation from outside the
DeferredUpdateManager. So this situation isn't planned, is it?

I must admit that I don't understand all that stuff. Draw2D is said to
be non-threadsafe. By performing the validation using a asynchron call,
multiple threads are used, aren't they? Why is this done
asynchronously? And what's the idea behind "updateQueued"?

Jens
Re: DirectEditManger and UpdateManager [message #233560 is a reply to message #233545] Thu, 26 April 2007 13:37 Go to previous message
Jens von Pilgrim is currently offline Jens von PilgrimFriend
Messages: 313
Registered: July 2009
Senior Member
Hi,

ok, now I understand the mechanism of the DeferredUpdateManager.

The "updateQueued" flag indicates that there has been created an
UpdateRequest. This request is executed by Display after all GEF/Draw2D
stuff has been executed. This is the overall picture:

Display fetches events etc.
--> Draw2D/GEF stuff is called
--> DeferredUpdateManager is used and creates an UpdateRequest
Display executes UpdateRequest

So the Display "surrounds" everything happening in Draw2D/GEF, and the
UpdateRequest is finally called by the Display. The issue that Draw2D
isn't thread safe includes that Draw2D stuff is run inside this event
loop.

In my case my LightWeightSystem implementation directly listens to the
AWT events. In the special case of direct edit, the GEF methods were
called directly without using the original SWT canvas thread. I must
have found that problem when playing around with this the first time
and so I added a fatal bug in DeferredUpdateManager to create the
update request only if Display.getCurrent()!=null. So I added a bug
which causes DeferredUpdateManager to become inconsistent!

Sorry... So this is all my fault :( But at least I solved the problem
;-) Thanks for your help, Alex!

Jens
Previous Topic:Drag Position
Next Topic:asynchronous access to the current CTRL or SHIFT modifiers
Goto Forum:
  


Current Time: Fri Apr 19 20:30:42 GMT 2024

Powered by FUDForum. Page generated in 0.03976 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top