Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF "Technology" (Ecore Tools, EMFatic, etc)  » Undo of RecordingCommand is done in a strange order...
Undo of RecordingCommand is done in a strange order... [message #87167] Fri, 22 June 2007 18:11 Go to next message
Eclipse UserFriend
Originally posted by: michael.bannij.infopulse.com.ua

Hi.

I'm using RecordingCommand to catch changes in my EMF model and undo the=
m =

if needed. The model objects are also mapped to edit parts which hook em=
f =

change listeners into the model objects. When RecordingCommand is undone=
=

it issues that change events as undo is progressing. And i suddenly foun=
d =

that the order of events during undo of a bunch of EMF model changes is =
=

different to the reverse order of events that i receive when making thes=
e =

changes.

I've made some debugging and found that when i undo a RecordingCommand, =
it =

in turn undoes internal instance of CompositeChangeDescription.
CompositeChangeDescription contains list of ChangeDescription, being ask=
ed =

to undo it goes trough the list from the end and undoes each =

ChangeDescription.
This looks like correct unwinding of EMF changes, but surprisingly the =

list contains only one ChangeDescription that itself contains all the =

changes.
And the changes in list iside this single ChangeDescription are unwinded=
=

in the
order that is different from both strict and reverseing order of changes=
=

as they were performed before undoing... Well, maybe the resulting model=
=

will be ok after undoing all primitive changes in that other order, but =
=

the problem is that my edit part receives a notification during the undo=
=

and the model appears to be in wrong state at this moment.

Here is an example trace of the events. I have next structure from EMF =

objects:
topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.
Each of binding and bindingInstr objects has not-containment property =

named "type" that is set to ReferencedDesign1. ReferencedDesign1 itself =
is =

contained in a list property in the topobject. The action is to delete t=
he =

binding2 and to move it's child binding3 to bindInst1. And the action is=
=

made in signle transaction. Then the action is undone. Here are event =

lists (in format: "eventType: objectInstance.property =3D oldValue -> =

newValue):

While removing middle node:

REMOVE: instr1.bindings[0] =3D binding2 -> null
SET: binding2.parent =3D instr1 -> null

REMOVE: instr2.bindings[0] =3D binding3 -> null
ADD: instr1.bindings[0] =3D null -> binding3
SET: binding3.parent =3D instr2 -> instr1

REMOVE: binding2.instructions[0] =3D instr2 -> null
SET: instr2.type =3D ReferencedDesign1 -> null
SET: binding2.type =3D ReferencedDesign1 -> null

While undoing the remove:

SET: binding2.parent =3D null -> instr1
ADD: instr1.bindings[0] =3D null -> binding2

SET: binding3.parent =3D instr1 -> null
REMOVE: instr1.bindings[1] =3D binding3 -> null
ADD: binding2.instructions[0] =3D null -> instr2

SET: binding2.type =3D null -> ReferencedDesign1

SET: binding3.parent =3D null -> instr2
ADD: instr2.bindings[0] =3D null -> binding3

SET: instr2.type =3D null -> ReferencedDesign1


The incorrectness of undo order is obvious (binding2 on the first step o=
f =

undo is returned into containment hierarhy whereas it's type is not yet =
=

restored from null to ReferencedDesign1), please help...


PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar

-- =

Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Re: Undo of RecordingCommand is done in a strange order... [message #87200 is a reply to message #87167] Fri, 22 June 2007 19:28 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: merks.ca.ibm.com

Michael,

Please use the EMF newsgroup for questions about the transaction APIs in
the future. I've added it to the "to" list. Query, Transaction, and
Validation have graduated and are components of EMF now.

EMF's ChangeRecorder does not simply record events, it records enough
information to know the initial state and then creates a
ChangeDescription that describes how to get from the current state to
the final state. There is no guarantee that applied changes will be
done in any particular order. In general, all the changes for each
object will be batched, and if you add something and then remove it
again, nothing will happen during undo, since there is no actual change
in state. Part of the point of having a transaction is that the
intermediate state may well be invalid and it's only at the end of a
transaction that the state must be valid. Similarly during a rollback or
undo, the intermediate states are not guaranteed to be valid. Perhaps
what you really want is multiple transactions. I'm not sure if
transactions can be nested or grouped; Christian will know that best.


Michael wrote:
> Hi.
>
> I'm using RecordingCommand to catch changes in my EMF model and undo
> them if needed. The model objects are also mapped to edit parts which
> hook emf change listeners into the model objects. When
> RecordingCommand is undone it issues that change events as undo is
> progressing. And i suddenly found that the order of events during undo
> of a bunch of EMF model changes is different to the reverse order of
> events that i receive when making these changes.
>
> I've made some debugging and found that when i undo a
> RecordingCommand, it in turn undoes internal instance of
> CompositeChangeDescription.
> CompositeChangeDescription contains list of ChangeDescription, being
> asked to undo it goes trough the list from the end and undoes each
> ChangeDescription.
> This looks like correct unwinding of EMF changes, but surprisingly the
> list contains only one ChangeDescription that itself contains all the
> changes.
> And the changes in list iside this single ChangeDescription are
> unwinded in the
> order that is different from both strict and reverseing order of
> changes as they were performed before undoing... Well, maybe the
> resulting model will be ok after undoing all primitive changes in that
> other order, but the problem is that my edit part receives a
> notification during the undo and the model appears to be in wrong
> state at this moment.
>
> Here is an example trace of the events. I have next structure from EMF
> objects:
> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.
> Each of binding and bindingInstr objects has not-containment property
> named "type" that is set to ReferencedDesign1. ReferencedDesign1
> itself is contained in a list property in the topobject. The action is
> to delete the binding2 and to move it's child binding3 to bindInst1.
> And the action is made in signle transaction. Then the action is
> undone. Here are event lists (in format: "eventType:
> objectInstance.property = oldValue -> newValue):
>
> While removing middle node:
>
> REMOVE: instr1.bindings[0] = binding2 -> null
> SET: binding2.parent = instr1 -> null
>
> REMOVE: instr2.bindings[0] = binding3 -> null
> ADD: instr1.bindings[0] = null -> binding3
> SET: binding3.parent = instr2 -> instr1
>
> REMOVE: binding2.instructions[0] = instr2 -> null
> SET: instr2.type = ReferencedDesign1 -> null
> SET: binding2.type = ReferencedDesign1 -> null
>
> While undoing the remove:
>
> SET: binding2.parent = null -> instr1
> ADD: instr1.bindings[0] = null -> binding2
>
> SET: binding3.parent = instr1 -> null
> REMOVE: instr1.bindings[1] = binding3 -> null
> ADD: binding2.instructions[0] = null -> instr2
>
> SET: binding2.type = null -> ReferencedDesign1
>
> SET: binding3.parent = null -> instr2
> ADD: instr2.bindings[0] = null -> binding3
>
> SET: instr2.type = null -> ReferencedDesign1
>
>
> The incorrectness of undo order is obvious (binding2 on the first step
> of undo is returned into containment hierarhy whereas it's type is not
> yet restored from null to ReferencedDesign1), please help...
>
>
> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar
>
Re: Undo of RecordingCommand is done in a strange order... [message #87229 is a reply to message #87200] Mon, 25 June 2007 05:48 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: michael.bannij.infopulse.com.ua

Yes, but AFAIK the difference between invalid state while doing changes =
=

and invalid state while undo changes is that in first case all events ar=
e =

delayed to the end of the transaction, while in the second case - not. =

Isn't that a kind of bug?

> Michael,
> Please use the EMF newsgroup for questions about the transaction APIs=
=

> in the future. I've added it to the "to" list. Query, Transaction, a=
nd =

> Validation have graduated and are components of EMF now.
> EMF's ChangeRecorder does not simply record events, it records enough=
=

> information to know the initial state and then creates a =

> ChangeDescription that describes how to get from the current state to =
=

> the final state. There is no guarantee that applied changes will be =

> done in any particular order. In general, all the changes for each =

> object will be batched, and if you add something and then remove it =

> again, nothing will happen during undo, since there is no actual chang=
e =

> in state. Part of the point of having a transaction is that the =

> intermediate state may well be invalid and it's only at the end of a =

> transaction that the state must be valid. Similarly during a rollback =
or =

> undo, the intermediate states are not guaranteed to be valid. Perhaps=
=

> what you really want is multiple transactions. I'm not sure if =

> transactions can be nested or grouped; Christian will know that best.
> Michael wrote:
> Hi.
> I'm using RecordingCommand to catch changes in my EMF model and undo =
=

> them if needed. The model objects are also mapped to edit parts which =
=

> hook emf change listeners into the model objects. When RecordingComman=
d =

> is undone it issues that change events as undo is progressing. And i =

> suddenly found that the order of events during undo of a bunch of EMF =
=

> model changes is different to the reverse order of events that i recei=
ve =

> when making these changes.
> I've made some debugging and found that when i undo a RecordingComman=
d, =

> it in turn undoes internal instance of CompositeChangeDescription.
> CompositeChangeDescription contains list of ChangeDescription, being =

> asked to undo it goes trough the list from the end and undoes each =

> ChangeDescription.
> This looks like correct unwinding of EMF changes, but surprisingly the=
=

> list contains only one ChangeDescription that itself contains all the =
=

> changes.
> And the changes in list iside this single ChangeDescription are unwind=
ed =

> in the
> order that is different from both strict and reverseing order of chang=
es =

> as they were performed before undoing... Well, maybe the resulting mod=
el =

> will be ok after undoing all primitive changes in that other order, bu=
t =

> the problem is that my edit part receives a notification during the un=
do =

> and the model appears to be in wrong state at this moment.
> Here is an example trace of the events. I have next structure from EM=
F =

> objects:
> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.
> Each of binding and bindingInstr objects has not-containment property =
=

> named "type" that is set to ReferencedDesign1. ReferencedDesign1 itsel=
f =

> is contained in a list property in the topobject. The action is to =

> delete the binding2 and to move it's child binding3 to bindInst1. And =
=

> the action is made in signle transaction. Then the action is undone. =

> Here are event lists (in format: "eventType: objectInstance.property =3D=
=

> oldValue -> newValue):
> While removing middle node:
> REMOVE: instr1.bindings[0] =3D binding2 -> null
> SET: binding2.parent =3D instr1 -> null
> REMOVE: instr2.bindings[0] =3D binding3 -> null
> ADD: instr1.bindings[0] =3D null -> binding3
> SET: binding3.parent =3D instr2 -> instr1
> REMOVE: binding2.instructions[0] =3D instr2 -> null
> SET: instr2.type =3D ReferencedDesign1 -> null
> SET: binding2.type =3D ReferencedDesign1 -> null
> While undoing the remove:
> SET: binding2.parent =3D null -> instr1
> ADD: instr1.bindings[0] =3D null -> binding2
> SET: binding3.parent =3D instr1 -> null
> REMOVE: instr1.bindings[1] =3D binding3 -> null
> ADD: binding2.instructions[0] =3D null -> instr2
> SET: binding2.type =3D null -> ReferencedDesign1
> SET: binding3.parent =3D null -> instr2
> ADD: instr2.bindings[0] =3D null -> binding3
> SET: instr2.type =3D null -> ReferencedDesign1
> The incorrectness of undo order is obvious (binding2 on the first st=
ep =

> of undo is returned into containment hierarhy whereas it's type is not=
=

> yet restored from null to ReferencedDesign1), please help...
> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar
>



-- =

Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Re: Undo of RecordingCommand is done in a strange order... [message #87243 is a reply to message #87200] Mon, 25 June 2007 05:59 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: michael.bannij.infopulse.com.ua

> Please use the EMF newsgroup for questions about the transaction APIs in
> the future. I've added it to the "to" list. Query, Transaction, and
> Validation have graduated and are components of EMF now.

Sorry for wrong newslist, but unfortunately the "eclipse.tools.emf" is
listed neither under EMF project nor elsewhere here:
http://www.eclipse.org/newsgroups/index_all.php

So it looks like it not exists...
Re: Undo of RecordingCommand is done in a strange order... [message #87258 is a reply to message #87243] Mon, 25 June 2007 11:18 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: merks.ca.ibm.com

Michael,

I've asked Nick to look into having this fixed.


Michael wrote:
>> Please use the EMF newsgroup for questions about the transaction APIs
>> in the future. I've added it to the "to" list. Query, Transaction,
>> and Validation have graduated and are components of EMF now.
>
> Sorry for wrong newslist, but unfortunately the "eclipse.tools.emf" is
> listed neither under EMF project nor elsewhere here:
> http://www.eclipse.org/newsgroups/index_all.php
>
> So it looks like it not exists...
Re: Undo of RecordingCommand is done in a strange order... [message #87273 is a reply to message #87229] Mon, 25 June 2007 11:44 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: merks.ca.ibm.com

Michael,

If what you say is true, it does sound kind of inconsistent. I'll wait
for Christian to comment.


Michael wrote:
> Yes, but AFAIK the difference between invalid state while doing
> changes and invalid state while undo changes is that in first case all
> events are delayed to the end of the transaction, while in the second
> case - not. Isn't that a kind of bug?
>
>> Michael,
>> Please use the EMF newsgroup for questions about the transaction
>> APIs in the future. I've added it to the "to" list. Query,
>> Transaction, and Validation have graduated and are components of EMF
>> now.
>> EMF's ChangeRecorder does not simply record events, it records
>> enough information to know the initial state and then creates a
>> ChangeDescription that describes how to get from the current state to
>> the final state. There is no guarantee that applied changes will be
>> done in any particular order. In general, all the changes for each
>> object will be batched, and if you add something and then remove it
>> again, nothing will happen during undo, since there is no actual
>> change in state. Part of the point of having a transaction is that
>> the intermediate state may well be invalid and it's only at the end
>> of a transaction that the state must be valid. Similarly during a
>> rollback or undo, the intermediate states are not guaranteed to be
>> valid. Perhaps what you really want is multiple transactions. I'm
>> not sure if transactions can be nested or grouped; Christian will
>> know that best.
>> Michael wrote:
>> Hi.
>> I'm using RecordingCommand to catch changes in my EMF model and undo
>> them if needed. The model objects are also mapped to edit parts which
>> hook emf change listeners into the model objects. When
>> RecordingCommand is undone it issues that change events as undo is
>> progressing. And i suddenly found that the order of events during
>> undo of a bunch of EMF model changes is different to the reverse
>> order of events that i receive when making these changes.
>> I've made some debugging and found that when i undo a
>> RecordingCommand, it in turn undoes internal instance of
>> CompositeChangeDescription.
>> CompositeChangeDescription contains list of ChangeDescription, being
>> asked to undo it goes trough the list from the end and undoes each
>> ChangeDescription.
>> This looks like correct unwinding of EMF changes, but surprisingly
>> the list contains only one ChangeDescription that itself contains all
>> the changes.
>> And the changes in list iside this single ChangeDescription are
>> unwinded in the
>> order that is different from both strict and reverseing order of
>> changes as they were performed before undoing... Well, maybe the
>> resulting model will be ok after undoing all primitive changes in
>> that other order, but the problem is that my edit part receives a
>> notification during the undo and the model appears to be in wrong
>> state at this moment.
>> Here is an example trace of the events. I have next structure from
>> EMF objects:
>> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.
>> Each of binding and bindingInstr objects has not-containment property
>> named "type" that is set to ReferencedDesign1. ReferencedDesign1
>> itself is contained in a list property in the topobject. The action
>> is to delete the binding2 and to move it's child binding3 to
>> bindInst1. And the action is made in signle transaction. Then the
>> action is undone. Here are event lists (in format: "eventType:
>> objectInstance.property = oldValue -> newValue):
>> While removing middle node:
>> REMOVE: instr1.bindings[0] = binding2 -> null
>> SET: binding2.parent = instr1 -> null
>> REMOVE: instr2.bindings[0] = binding3 -> null
>> ADD: instr1.bindings[0] = null -> binding3
>> SET: binding3.parent = instr2 -> instr1
>> REMOVE: binding2.instructions[0] = instr2 -> null
>> SET: instr2.type = ReferencedDesign1 -> null
>> SET: binding2.type = ReferencedDesign1 -> null
>> While undoing the remove:
>> SET: binding2.parent = null -> instr1
>> ADD: instr1.bindings[0] = null -> binding2
>> SET: binding3.parent = instr1 -> null
>> REMOVE: instr1.bindings[1] = binding3 -> null
>> ADD: binding2.instructions[0] = null -> instr2
>> SET: binding2.type = null -> ReferencedDesign1
>> SET: binding3.parent = null -> instr2
>> ADD: instr2.bindings[0] = null -> binding3
>> SET: instr2.type = null -> ReferencedDesign1
>> The incorrectness of undo order is obvious (binding2 on the first
>> step of undo is returned into containment hierarhy whereas it's type
>> is not yet restored from null to ReferencedDesign1), please help...
>> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar
>>
>
>
>
Re: Undo of RecordingCommand is done in a strange order... [message #87288 is a reply to message #87273] Mon, 25 June 2007 13:44 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: michael.bannij.infopulse.com.ua

Not exactly true - i just checked and found that in my case the =

notifications are not deferred, but the code looks like there is a =

possibility of such behaviour (but i have no ideas how to connect this =

with undo - is it correct to perform undo of a transaction in other =

transaction?).

Anyway, it would be good to have some recording functionality that is =

unwinding changes exactly in the way that is reverse to the way of how t=
he =

changes were performed...

> If what you say is true, it does sound kind of inconsistent. I'll wai=
t =

> for Christian to comment.
>
>> Yes, but AFAIK the difference between invalid state while doing chang=
es =

>> and invalid state while undo changes is that in first case all events=
=

>> are delayed to the end of the transaction, while in the second case -=
=

>> not. Isn't that a kind of bug?
>>
>>> Michael,
>>> Please use the EMF newsgroup for questions about the transaction AP=
Is =

>>> in the future. I've added it to the "to" list. Query, Transaction,=
=

>>> and Validation have graduated and are components of EMF now.
>>> EMF's ChangeRecorder does not simply record events, it records enou=
gh =

>>> information to know the initial state and then creates a =

>>> ChangeDescription that describes how to get from the current state t=
o =

>>> the final state. There is no guarantee that applied changes will be=
=

>>> done in any particular order. In general, all the changes for each =
=

>>> object will be batched, and if you add something and then remove it =
=

>>> again, nothing will happen during undo, since there is no actual =

>>> change in state. Part of the point of having a transaction is that =
=

>>> the intermediate state may well be invalid and it's only at the end =
of =

>>> a transaction that the state must be valid. Similarly during a =

>>> rollback or undo, the intermediate states are not guaranteed to be =

>>> valid. Perhaps what you really want is multiple transactions. I'm =
=

>>> not sure if transactions can be nested or grouped; Christian will kn=
ow =

>>> that best.
>>> Michael wrote:
>>> Hi.
>>> I'm using RecordingCommand to catch changes in my EMF model and und=
o =

>>> them if needed. The model objects are also mapped to edit parts whic=
h =

>>> hook emf change listeners into the model objects. When =

>>> RecordingCommand is undone it issues that change events as undo is =

>>> progressing. And i suddenly found that the order of events during un=
do =

>>> of a bunch of EMF model changes is different to the reverse order of=
=

>>> events that i receive when making these changes.
>>> I've made some debugging and found that when i undo a =

>>> RecordingCommand, it in turn undoes internal instance of =

>>> CompositeChangeDescription.
>>> CompositeChangeDescription contains list of ChangeDescription, being=
=

>>> asked to undo it goes trough the list from the end and undoes each =

>>> ChangeDescription.
>>> This looks like correct unwinding of EMF changes, but surprisingly t=
he =

>>> list contains only one ChangeDescription that itself contains all th=
e =

>>> changes.
>>> And the changes in list iside this single ChangeDescription are =

>>> unwinded in the
>>> order that is different from both strict and reverseing order of =

>>> changes as they were performed before undoing... Well, maybe the =

>>> resulting model will be ok after undoing all primitive changes in th=
at =

>>> other order, but the problem is that my edit part receives a =

>>> notification during the undo and the model appears to be in wrong =

>>> state at this moment.
>>> Here is an example trace of the events. I have next structure from =
=

>>> EMF objects:
>>> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.=

>>> Each of binding and bindingInstr objects has not-containment propert=
y =

>>> named "type" that is set to ReferencedDesign1. ReferencedDesign1 =

>>> itself is contained in a list property in the topobject. The action =
is =

>>> to delete the binding2 and to move it's child binding3 to bindInst1.=
=

>>> And the action is made in signle transaction. Then the action is =

>>> undone. Here are event lists (in format: "eventType: =

>>> objectInstance.property =3D oldValue -> newValue):
>>> While removing middle node:
>>> REMOVE: instr1.bindings[0] =3D binding2 -> null
>>> SET: binding2.parent =3D instr1 -> null
>>> REMOVE: instr2.bindings[0] =3D binding3 -> null
>>> ADD: instr1.bindings[0] =3D null -> binding3
>>> SET: binding3.parent =3D instr2 -> instr1
>>> REMOVE: binding2.instructions[0] =3D instr2 -> null
>>> SET: instr2.type =3D ReferencedDesign1 -> null
>>> SET: binding2.type =3D ReferencedDesign1 -> null
>>> While undoing the remove:
>>> SET: binding2.parent =3D null -> instr1
>>> ADD: instr1.bindings[0] =3D null -> binding2
>>> SET: binding3.parent =3D instr1 -> null
>>> REMOVE: instr1.bindings[1] =3D binding3 -> null
>>> ADD: binding2.instructions[0] =3D null -> instr2
>>> SET: binding2.type =3D null -> ReferencedDesign1
>>> SET: binding3.parent =3D null -> instr2
>>> ADD: instr2.bindings[0] =3D null -> binding3
>>> SET: instr2.type =3D null -> ReferencedDesign1
>>> The incorrectness of undo order is obvious (binding2 on the first =
=

>>> step of undo is returned into containment hierarhy whereas it's type=
=

>>> is not yet restored from null to ReferencedDesign1), please help...
>>> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar
Re: Undo of RecordingCommand is done in a strange order... [message #87296 is a reply to message #87288] Mon, 25 June 2007 13:46 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: michael.bannij.infopulse.com.ua

> Not exactly true - i just checked and found that in my case the
> notifications are not deferred, but the code looks like there is a
> possibility of such behaviour (but i have no ideas how to connect this
> with undo - is it correct to perform undo of a transaction in other
> transaction?).

(I.e. not deferred to the end of the active transaction while making the
changes)

--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Re: Undo of RecordingCommand is done in a strange order... [message #87321 is a reply to message #87288] Mon, 25 June 2007 15:33 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: merks.ca.ibm.com

Michael,

It would probably be better to write your code not to depend order
because we have no plans to implement an event recording mechanism.


Michael wrote:
> Not exactly true - i just checked and found that in my case the
> notifications are not deferred, but the code looks like there is a
> possibility of such behaviour (but i have no ideas how to connect this
> with undo - is it correct to perform undo of a transaction in other
> transaction?).
>
> Anyway, it would be good to have some recording functionality that is
> unwinding changes exactly in the way that is reverse to the way of how
> the changes were performed...
>
>> If what you say is true, it does sound kind of inconsistent. I'll
>> wait for Christian to comment.
>>
>>> Yes, but AFAIK the difference between invalid state while doing
>>> changes and invalid state while undo changes is that in first case
>>> all events are delayed to the end of the transaction, while in the
>>> second case - not. Isn't that a kind of bug?
>>>
>>>> Michael,
>>>> Please use the EMF newsgroup for questions about the transaction
>>>> APIs in the future. I've added it to the "to" list. Query,
>>>> Transaction, and Validation have graduated and are components of
>>>> EMF now.
>>>> EMF's ChangeRecorder does not simply record events, it records
>>>> enough information to know the initial state and then creates a
>>>> ChangeDescription that describes how to get from the current state
>>>> to the final state. There is no guarantee that applied changes
>>>> will be done in any particular order. In general, all the changes
>>>> for each object will be batched, and if you add something and then
>>>> remove it again, nothing will happen during undo, since there is no
>>>> actual change in state. Part of the point of having a transaction
>>>> is that the intermediate state may well be invalid and it's only at
>>>> the end of a transaction that the state must be valid. Similarly
>>>> during a rollback or undo, the intermediate states are not
>>>> guaranteed to be valid. Perhaps what you really want is multiple
>>>> transactions. I'm not sure if transactions can be nested or
>>>> grouped; Christian will know that best.
>>>> Michael wrote:
>>>> Hi.
>>>> I'm using RecordingCommand to catch changes in my EMF model and
>>>> undo them if needed. The model objects are also mapped to edit
>>>> parts which hook emf change listeners into the model objects. When
>>>> RecordingCommand is undone it issues that change events as undo is
>>>> progressing. And i suddenly found that the order of events during
>>>> undo of a bunch of EMF model changes is different to the reverse
>>>> order of events that i receive when making these changes.
>>>> I've made some debugging and found that when i undo a
>>>> RecordingCommand, it in turn undoes internal instance of
>>>> CompositeChangeDescription.
>>>> CompositeChangeDescription contains list of ChangeDescription,
>>>> being asked to undo it goes trough the list from the end and undoes
>>>> each ChangeDescription.
>>>> This looks like correct unwinding of EMF changes, but surprisingly
>>>> the list contains only one ChangeDescription that itself contains
>>>> all the changes.
>>>> And the changes in list iside this single ChangeDescription are
>>>> unwinded in the
>>>> order that is different from both strict and reverseing order of
>>>> changes as they were performed before undoing... Well, maybe the
>>>> resulting model will be ok after undoing all primitive changes in
>>>> that other order, but the problem is that my edit part receives a
>>>> notification during the undo and the model appears to be in wrong
>>>> state at this moment.
>>>> Here is an example trace of the events. I have next structure from
>>>> EMF objects:
>>>> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.
>>>> Each of binding and bindingInstr objects has not-containment
>>>> property named "type" that is set to ReferencedDesign1.
>>>> ReferencedDesign1 itself is contained in a list property in the
>>>> topobject. The action is to delete the binding2 and to move it's
>>>> child binding3 to bindInst1. And the action is made in signle
>>>> transaction. Then the action is undone. Here are event lists (in
>>>> format: "eventType: objectInstance.property = oldValue -> newValue):
>>>> While removing middle node:
>>>> REMOVE: instr1.bindings[0] = binding2 -> null
>>>> SET: binding2.parent = instr1 -> null
>>>> REMOVE: instr2.bindings[0] = binding3 -> null
>>>> ADD: instr1.bindings[0] = null -> binding3
>>>> SET: binding3.parent = instr2 -> instr1
>>>> REMOVE: binding2.instructions[0] = instr2 -> null
>>>> SET: instr2.type = ReferencedDesign1 -> null
>>>> SET: binding2.type = ReferencedDesign1 -> null
>>>> While undoing the remove:
>>>> SET: binding2.parent = null -> instr1
>>>> ADD: instr1.bindings[0] = null -> binding2
>>>> SET: binding3.parent = instr1 -> null
>>>> REMOVE: instr1.bindings[1] = binding3 -> null
>>>> ADD: binding2.instructions[0] = null -> instr2
>>>> SET: binding2.type = null -> ReferencedDesign1
>>>> SET: binding3.parent = null -> instr2
>>>> ADD: instr2.bindings[0] = null -> binding3
>>>> SET: instr2.type = null -> ReferencedDesign1
>>>> The incorrectness of undo order is obvious (binding2 on the first
>>>> step of undo is returned into containment hierarhy whereas it's
>>>> type is not yet restored from null to ReferencedDesign1), please
>>>> help...
>>>> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar
Re: Undo of RecordingCommand is done in a strange order... [message #87335 is a reply to message #87288] Mon, 25 June 2007 19:24 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: cdamus.ca.ibm.com

Hi, Michael,

To respond to a few of your questions (sorry for the delay; I was away on
vacation) ...

All changes must be performed in transactions, including undo/redo of
previous changes. For undo/redo, the TransactionalCommandStack creates
transactions in which to replay the ChangeDescription that do not bother to

- record changes for undo/redo/rollback (since we already have them)
- validate changes (since we are moving between known valid states)
- execute triggers (since we are moving between known valid states)

Perhaps what you are seeing that suggests an immediate reporting of changes
to listeners is the "broadcastUnbatched(Notification)" method? This is
only used for simulating transaction post-commit events in a context where
there is no transaction. In such cases, the changes represented by
Notifications are necessarily only those that do not require a read/write
transaction, such as proxy resolution and resource loading.

Finally, regarding the ordering of changes when undoing or redoing. It is,
indeed, assumed by EMF that the ordering of changes is irrelevant to
effecting the correct change in the resource set's contents. All code
generated by EMF is consistent with this assumption, because EMF never
generates "side-effects" in the code. However, it is possible that
post-generation customizations will do this. For example, the Eclipse UML2
implementation automatically applies/unapplies Stereotypes whenever the
containment of an Element is changed, in order to proactively maintain the
integrity of stereotype applications, by customizing the
eBasicSetContainer(...) method. This has caused numerous undo/redo
problems for some applications that I know of. IMO, such side-effects are
better left to "triggers" in the EMF Transaction API (which are
specifically designed for this purpose). The nice thing about triggers is
that their changes are recorded in nested transactions and, hence, in
distinct change-descriptions within the composite. This preserves the
ordering of those changes with respect to the client's intended changes.

Cheers,

Christian


Michael wrote:

> Not exactly true - i just checked and found that in my case the
> notifications are not deferred, but the code looks like there is a
> possibility of such behaviour (but i have no ideas how to connect this
> with undo - is it correct to perform undo of a transaction in other
> transaction?).
>
> Anyway, it would be good to have some recording functionality that is
> unwinding changes exactly in the way that is reverse to the way of how the
> changes were performed...
>
>> If what you say is true, it does sound kind of inconsistent. I'll wait
>> for Christian to comment.
>>
>>> Yes, but AFAIK the difference between invalid state while doing changes
>>> and invalid state while undo changes is that in first case all events
>>> are delayed to the end of the transaction, while in the second case -
>>> not. Isn't that a kind of bug?
>>>
>>>> Michael,
>>>> Please use the EMF newsgroup for questions about the transaction APIs
>>>> in the future. I've added it to the "to" list. Query, Transaction,
>>>> and Validation have graduated and are components of EMF now.
>>>> EMF's ChangeRecorder does not simply record events, it records enough
>>>> information to know the initial state and then creates a
>>>> ChangeDescription that describes how to get from the current state to
>>>> the final state. There is no guarantee that applied changes will be
>>>> done in any particular order. In general, all the changes for each
>>>> object will be batched, and if you add something and then remove it
>>>> again, nothing will happen during undo, since there is no actual
>>>> change in state. Part of the point of having a transaction is that
>>>> the intermediate state may well be invalid and it's only at the end of
>>>> a transaction that the state must be valid. Similarly during a
>>>> rollback or undo, the intermediate states are not guaranteed to be
>>>> valid. Perhaps what you really want is multiple transactions. I'm
>>>> not sure if transactions can be nested or grouped; Christian will know
>>>> that best.
>>>> Michael wrote:
>>>> Hi.
>>>> I'm using RecordingCommand to catch changes in my EMF model and undo
>>>> them if needed. The model objects are also mapped to edit parts which
>>>> hook emf change listeners into the model objects. When
>>>> RecordingCommand is undone it issues that change events as undo is
>>>> progressing. And i suddenly found that the order of events during undo
>>>> of a bunch of EMF model changes is different to the reverse order of
>>>> events that i receive when making these changes.
>>>> I've made some debugging and found that when i undo a
>>>> RecordingCommand, it in turn undoes internal instance of
>>>> CompositeChangeDescription.
>>>> CompositeChangeDescription contains list of ChangeDescription, being
>>>> asked to undo it goes trough the list from the end and undoes each
>>>> ChangeDescription.
>>>> This looks like correct unwinding of EMF changes, but surprisingly the
>>>> list contains only one ChangeDescription that itself contains all the
>>>> changes.
>>>> And the changes in list iside this single ChangeDescription are
>>>> unwinded in the
>>>> order that is different from both strict and reverseing order of
>>>> changes as they were performed before undoing... Well, maybe the
>>>> resulting model will be ok after undoing all primitive changes in that
>>>> other order, but the problem is that my edit part receives a
>>>> notification during the undo and the model appears to be in wrong
>>>> state at this moment.
>>>> Here is an example trace of the events. I have next structure from
>>>> EMF objects:
>>>> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.
>>>> Each of binding and bindingInstr objects has not-containment property
>>>> named "type" that is set to ReferencedDesign1. ReferencedDesign1
>>>> itself is contained in a list property in the topobject. The action is
>>>> to delete the binding2 and to move it's child binding3 to bindInst1.
>>>> And the action is made in signle transaction. Then the action is
>>>> undone. Here are event lists (in format: "eventType:
>>>> objectInstance.property = oldValue -> newValue):
>>>> While removing middle node:
>>>> REMOVE: instr1.bindings[0] = binding2 -> null
>>>> SET: binding2.parent = instr1 -> null
>>>> REMOVE: instr2.bindings[0] = binding3 -> null
>>>> ADD: instr1.bindings[0] = null -> binding3
>>>> SET: binding3.parent = instr2 -> instr1
>>>> REMOVE: binding2.instructions[0] = instr2 -> null
>>>> SET: instr2.type = ReferencedDesign1 -> null
>>>> SET: binding2.type = ReferencedDesign1 -> null
>>>> While undoing the remove:
>>>> SET: binding2.parent = null -> instr1
>>>> ADD: instr1.bindings[0] = null -> binding2
>>>> SET: binding3.parent = instr1 -> null
>>>> REMOVE: instr1.bindings[1] = binding3 -> null
>>>> ADD: binding2.instructions[0] = null -> instr2
>>>> SET: binding2.type = null -> ReferencedDesign1
>>>> SET: binding3.parent = null -> instr2
>>>> ADD: instr2.bindings[0] = null -> binding3
>>>> SET: instr2.type = null -> ReferencedDesign1
>>>> The incorrectness of undo order is obvious (binding2 on the first
>>>> step of undo is returned into containment hierarhy whereas it's type
>>>> is not yet restored from null to ReferencedDesign1), please help...
>>>> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar
Re: Undo of RecordingCommand is done in a strange order... [message #87395 is a reply to message #87335] Tue, 26 June 2007 09:43 Go to previous message
Eclipse UserFriend
Originally posted by: michael.bannij.infopulse.com.ua

Hi, Christian.

Thanks for your reply. I will think over the things you wrote to develop=
a =

solution for my problem.

> Hi, Michael,
>
> To respond to a few of your questions (sorry for the delay; I was away=
on
> vacation) ...
>
> All changes must be performed in transactions, including undo/redo of
> previous changes. For undo/redo, the TransactionalCommandStack create=
s
> transactions in which to replay the ChangeDescription that do not both=
er =

> to
>
> - record changes for undo/redo/rollback (since we already have them)=

> - validate changes (since we are moving between known valid states)
> - execute triggers (since we are moving between known valid states)
>
> Perhaps what you are seeing that suggests an immediate reporting of =

> changes
> to listeners is the "broadcastUnbatched(Notification)" method? This i=
s
> only used for simulating transaction post-commit events in a context =

> where
> there is no transaction. In such cases, the changes represented by
> Notifications are necessarily only those that do not require a read/wr=
ite
> transaction, such as proxy resolution and resource loading.
>
> Finally, regarding the ordering of changes when undoing or redoing. I=
t =

> is,
> indeed, assumed by EMF that the ordering of changes is irrelevant to
> effecting the correct change in the resource set's contents. All code=

> generated by EMF is consistent with this assumption, because EMF never=

> generates "side-effects" in the code. However, it is possible that
> post-generation customizations will do this. For example, the Eclipse=
=

> UML2
> implementation automatically applies/unapplies Stereotypes whenever th=
e
> containment of an Element is changed, in order to proactively maintain=
=

> the
> integrity of stereotype applications, by customizing the
> eBasicSetContainer(...) method. This has caused numerous undo/redo
> problems for some applications that I know of. IMO, such side-effects=
=

> are
> better left to "triggers" in the EMF Transaction API (which are
> specifically designed for this purpose). The nice thing about trigger=
s =

> is
> that their changes are recorded in nested transactions and, hence, in
> distinct change-descriptions within the composite. This preserves the=

> ordering of those changes with respect to the client's intended change=
s.
>
> Cheers,
>
> Christian
>
>
> Michael wrote:
>
>> Not exactly true - i just checked and found that in my case the
>> notifications are not deferred, but the code looks like there is a
>> possibility of such behaviour (but i have no ideas how to connect thi=
s
>> with undo - is it correct to perform undo of a transaction in other
>> transaction?).
>>
>> Anyway, it would be good to have some recording functionality that is=

>> unwinding changes exactly in the way that is reverse to the way of ho=
w =

>> the
>> changes were performed...
>>
>>> If what you say is true, it does sound kind of inconsistent. I'll w=
ait
>>> for Christian to comment.
>>>
>>>> Yes, but AFAIK the difference between invalid state while doing =

>>>> changes
>>>> and invalid state while undo changes is that in first case all even=
ts
>>>> are delayed to the end of the transaction, while in the second case=
-
>>>> not. Isn't that a kind of bug?
>>>>
>>>>> Michael,
>>>>> Please use the EMF newsgroup for questions about the transaction =
=

>>>>> APIs
>>>>> in the future. I've added it to the "to" list. Query, Transactio=
n,
>>>>> and Validation have graduated and are components of EMF now.
>>>>> EMF's ChangeRecorder does not simply record events, it records =

>>>>> enough
>>>>> information to know the initial state and then creates a
>>>>> ChangeDescription that describes how to get from the current state=
to
>>>>> the final state. There is no guarantee that applied changes will =
be
>>>>> done in any particular order. In general, all the changes for eac=
h
>>>>> object will be batched, and if you add something and then remove i=
t
>>>>> again, nothing will happen during undo, since there is no actual
>>>>> change in state. Part of the point of having a transaction is tha=
t
>>>>> the intermediate state may well be invalid and it's only at the en=
d =

>>>>> of
>>>>> a transaction that the state must be valid. Similarly during a
>>>>> rollback or undo, the intermediate states are not guaranteed to be=

>>>>> valid. Perhaps what you really want is multiple transactions. I'=
m
>>>>> not sure if transactions can be nested or grouped; Christian will =
=

>>>>> know
>>>>> that best.
>>>>> Michael wrote:
>>>>> Hi.
>>>>> I'm using RecordingCommand to catch changes in my EMF model and u=
ndo
>>>>> them if needed. The model objects are also mapped to edit parts wh=
ich
>>>>> hook emf change listeners into the model objects. When
>>>>> RecordingCommand is undone it issues that change events as undo is=

>>>>> progressing. And i suddenly found that the order of events during =
=

>>>>> undo
>>>>> of a bunch of EMF model changes is different to the reverse order =
of
>>>>> events that i receive when making these changes.
>>>>> I've made some debugging and found that when i undo a
>>>>> RecordingCommand, it in turn undoes internal instance of
>>>>> CompositeChangeDescription.
>>>>> CompositeChangeDescription contains list of ChangeDescription, bei=
ng
>>>>> asked to undo it goes trough the list from the end and undoes each=

>>>>> ChangeDescription.
>>>>> This looks like correct unwinding of EMF changes, but surprisingly=
=

>>>>> the
>>>>> list contains only one ChangeDescription that itself contains all =
the
>>>>> changes.
>>>>> And the changes in list iside this single ChangeDescription are
>>>>> unwinded in the
>>>>> order that is different from both strict and reverseing order of
>>>>> changes as they were performed before undoing... Well, maybe the
>>>>> resulting model will be ok after undoing all primitive changes in =
=

>>>>> that
>>>>> other order, but the problem is that my edit part receives a
>>>>> notification during the undo and the model appears to be in wrong
>>>>> state at this moment.
>>>>> Here is an example trace of the events. I have next structure fro=
m
>>>>> EMF objects:
>>>>> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding=
3.
>>>>> Each of binding and bindingInstr objects has not-containment prope=
rty
>>>>> named "type" that is set to ReferencedDesign1. ReferencedDesign1
>>>>> itself is contained in a list property in the topobject. The actio=
n =

>>>>> is
>>>>> to delete the binding2 and to move it's child binding3 to bindInst=
1.
>>>>> And the action is made in signle transaction. Then the action is
>>>>> undone. Here are event lists (in format: "eventType:
>>>>> objectInstance.property =3D oldValue -> newValue):
>>>>> While removing middle node:
>>>>> REMOVE: instr1.bindings[0] =3D binding2 -> null
>>>>> SET: binding2.parent =3D instr1 -> null
>>>>> REMOVE: instr2.bindings[0] =3D binding3 -> null
>>>>> ADD: instr1.bindings[0] =3D null -> binding3
>>>>> SET: binding3.parent =3D instr2 -> instr1
>>>>> REMOVE: binding2.instructions[0] =3D instr2 -> null
>>>>> SET: instr2.type =3D ReferencedDesign1 -> null
>>>>> SET: binding2.type =3D ReferencedDesign1 -> null
>>>>> While undoing the remove:
>>>>> SET: binding2.parent =3D null -> instr1
>>>>> ADD: instr1.bindings[0] =3D null -> binding2
>>>>> SET: binding3.parent =3D instr1 -> null
>>>>> REMOVE: instr1.bindings[1] =3D binding3 -> null
>>>>> ADD: binding2.instructions[0] =3D null -> instr2
>>>>> SET: binding2.type =3D null -> ReferencedDesign1
>>>>> SET: binding3.parent =3D null -> instr2
>>>>> ADD: instr2.bindings[0] =3D null -> binding3
>>>>> SET: instr2.type =3D null -> ReferencedDesign1
>>>>> The incorrectness of undo order is obvious (binding2 on the firs=
t
>>>>> step of undo is returned into containment hierarhy whereas it's ty=
pe
>>>>> is not yet restored from null to ReferencedDesign1), please help..=
..
>>>>> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.ja=
r
>



-- =

Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Re: Undo of RecordingCommand is done in a strange order... [message #608578 is a reply to message #87167] Fri, 22 June 2007 19:28 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33136
Registered: July 2009
Senior Member
Michael,

Please use the EMF newsgroup for questions about the transaction APIs in
the future. I've added it to the "to" list. Query, Transaction, and
Validation have graduated and are components of EMF now.

EMF's ChangeRecorder does not simply record events, it records enough
information to know the initial state and then creates a
ChangeDescription that describes how to get from the current state to
the final state. There is no guarantee that applied changes will be
done in any particular order. In general, all the changes for each
object will be batched, and if you add something and then remove it
again, nothing will happen during undo, since there is no actual change
in state. Part of the point of having a transaction is that the
intermediate state may well be invalid and it's only at the end of a
transaction that the state must be valid. Similarly during a rollback or
undo, the intermediate states are not guaranteed to be valid. Perhaps
what you really want is multiple transactions. I'm not sure if
transactions can be nested or grouped; Christian will know that best.


Michael wrote:
> Hi.
>
> I'm using RecordingCommand to catch changes in my EMF model and undo
> them if needed. The model objects are also mapped to edit parts which
> hook emf change listeners into the model objects. When
> RecordingCommand is undone it issues that change events as undo is
> progressing. And i suddenly found that the order of events during undo
> of a bunch of EMF model changes is different to the reverse order of
> events that i receive when making these changes.
>
> I've made some debugging and found that when i undo a
> RecordingCommand, it in turn undoes internal instance of
> CompositeChangeDescription.
> CompositeChangeDescription contains list of ChangeDescription, being
> asked to undo it goes trough the list from the end and undoes each
> ChangeDescription.
> This looks like correct unwinding of EMF changes, but surprisingly the
> list contains only one ChangeDescription that itself contains all the
> changes.
> And the changes in list iside this single ChangeDescription are
> unwinded in the
> order that is different from both strict and reverseing order of
> changes as they were performed before undoing... Well, maybe the
> resulting model will be ok after undoing all primitive changes in that
> other order, but the problem is that my edit part receives a
> notification during the undo and the model appears to be in wrong
> state at this moment.
>
> Here is an example trace of the events. I have next structure from EMF
> objects:
> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.
> Each of binding and bindingInstr objects has not-containment property
> named "type" that is set to ReferencedDesign1. ReferencedDesign1
> itself is contained in a list property in the topobject. The action is
> to delete the binding2 and to move it's child binding3 to bindInst1.
> And the action is made in signle transaction. Then the action is
> undone. Here are event lists (in format: "eventType:
> objectInstance.property = oldValue -> newValue):
>
> While removing middle node:
>
> REMOVE: instr1.bindings[0] = binding2 -> null
> SET: binding2.parent = instr1 -> null
>
> REMOVE: instr2.bindings[0] = binding3 -> null
> ADD: instr1.bindings[0] = null -> binding3
> SET: binding3.parent = instr2 -> instr1
>
> REMOVE: binding2.instructions[0] = instr2 -> null
> SET: instr2.type = ReferencedDesign1 -> null
> SET: binding2.type = ReferencedDesign1 -> null
>
> While undoing the remove:
>
> SET: binding2.parent = null -> instr1
> ADD: instr1.bindings[0] = null -> binding2
>
> SET: binding3.parent = instr1 -> null
> REMOVE: instr1.bindings[1] = binding3 -> null
> ADD: binding2.instructions[0] = null -> instr2
>
> SET: binding2.type = null -> ReferencedDesign1
>
> SET: binding3.parent = null -> instr2
> ADD: instr2.bindings[0] = null -> binding3
>
> SET: instr2.type = null -> ReferencedDesign1
>
>
> The incorrectness of undo order is obvious (binding2 on the first step
> of undo is returned into containment hierarhy whereas it's type is not
> yet restored from null to ReferencedDesign1), please help...
>
>
> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Undo of RecordingCommand is done in a strange order... [message #608580 is a reply to message #87200] Mon, 25 June 2007 05:48 Go to previous message
Michael is currently offline MichaelFriend
Messages: 43
Registered: July 2009
Member
Yes, but AFAIK the difference between invalid state while doing changes =
=

and invalid state while undo changes is that in first case all events ar=
e =

delayed to the end of the transaction, while in the second case - not. =

Isn't that a kind of bug?

> Michael,
> Please use the EMF newsgroup for questions about the transaction APIs=
=

> in the future. I've added it to the "to" list. Query, Transaction, a=
nd =

> Validation have graduated and are components of EMF now.
> EMF's ChangeRecorder does not simply record events, it records enough=
=

> information to know the initial state and then creates a =

> ChangeDescription that describes how to get from the current state to =
=

> the final state. There is no guarantee that applied changes will be =

> done in any particular order. In general, all the changes for each =

> object will be batched, and if you add something and then remove it =

> again, nothing will happen during undo, since there is no actual chang=
e =

> in state. Part of the point of having a transaction is that the =

> intermediate state may well be invalid and it's only at the end of a =

> transaction that the state must be valid. Similarly during a rollback =
or =

> undo, the intermediate states are not guaranteed to be valid. Perhaps=
=

> what you really want is multiple transactions. I'm not sure if =

> transactions can be nested or grouped; Christian will know that best.
> Michael wrote:
> Hi.
> I'm using RecordingCommand to catch changes in my EMF model and undo =
=

> them if needed. The model objects are also mapped to edit parts which =
=

> hook emf change listeners into the model objects. When RecordingComman=
d =

> is undone it issues that change events as undo is progressing. And i =

> suddenly found that the order of events during undo of a bunch of EMF =
=

> model changes is different to the reverse order of events that i recei=
ve =

> when making these changes.
> I've made some debugging and found that when i undo a RecordingComman=
d, =

> it in turn undoes internal instance of CompositeChangeDescription.
> CompositeChangeDescription contains list of ChangeDescription, being =

> asked to undo it goes trough the list from the end and undoes each =

> ChangeDescription.
> This looks like correct unwinding of EMF changes, but surprisingly the=
=

> list contains only one ChangeDescription that itself contains all the =
=

> changes.
> And the changes in list iside this single ChangeDescription are unwind=
ed =

> in the
> order that is different from both strict and reverseing order of chang=
es =

> as they were performed before undoing... Well, maybe the resulting mod=
el =

> will be ok after undoing all primitive changes in that other order, bu=
t =

> the problem is that my edit part receives a notification during the un=
do =

> and the model appears to be in wrong state at this moment.
> Here is an example trace of the events. I have next structure from EM=
F =

> objects:
> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.
> Each of binding and bindingInstr objects has not-containment property =
=

> named "type" that is set to ReferencedDesign1. ReferencedDesign1 itsel=
f =

> is contained in a list property in the topobject. The action is to =

> delete the binding2 and to move it's child binding3 to bindInst1. And =
=

> the action is made in signle transaction. Then the action is undone. =

> Here are event lists (in format: "eventType: objectInstance.property =3D=
=

> oldValue -> newValue):
> While removing middle node:
> REMOVE: instr1.bindings[0] =3D binding2 -> null
> SET: binding2.parent =3D instr1 -> null
> REMOVE: instr2.bindings[0] =3D binding3 -> null
> ADD: instr1.bindings[0] =3D null -> binding3
> SET: binding3.parent =3D instr2 -> instr1
> REMOVE: binding2.instructions[0] =3D instr2 -> null
> SET: instr2.type =3D ReferencedDesign1 -> null
> SET: binding2.type =3D ReferencedDesign1 -> null
> While undoing the remove:
> SET: binding2.parent =3D null -> instr1
> ADD: instr1.bindings[0] =3D null -> binding2
> SET: binding3.parent =3D instr1 -> null
> REMOVE: instr1.bindings[1] =3D binding3 -> null
> ADD: binding2.instructions[0] =3D null -> instr2
> SET: binding2.type =3D null -> ReferencedDesign1
> SET: binding3.parent =3D null -> instr2
> ADD: instr2.bindings[0] =3D null -> binding3
> SET: instr2.type =3D null -> ReferencedDesign1
> The incorrectness of undo order is obvious (binding2 on the first st=
ep =

> of undo is returned into containment hierarhy whereas it's type is not=
=

> yet restored from null to ReferencedDesign1), please help...
> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar
>



-- =

Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Re: Undo of RecordingCommand is done in a strange order... [message #608581 is a reply to message #87200] Mon, 25 June 2007 05:59 Go to previous message
Michael is currently offline MichaelFriend
Messages: 43
Registered: July 2009
Member
> Please use the EMF newsgroup for questions about the transaction APIs in
> the future. I've added it to the "to" list. Query, Transaction, and
> Validation have graduated and are components of EMF now.

Sorry for wrong newslist, but unfortunately the "eclipse.tools.emf" is
listed neither under EMF project nor elsewhere here:
http://www.eclipse.org/newsgroups/index_all.php

So it looks like it not exists...
Re: Undo of RecordingCommand is done in a strange order... [message #608582 is a reply to message #87243] Mon, 25 June 2007 11:18 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33136
Registered: July 2009
Senior Member
Michael,

I've asked Nick to look into having this fixed.


Michael wrote:
>> Please use the EMF newsgroup for questions about the transaction APIs
>> in the future. I've added it to the "to" list. Query, Transaction,
>> and Validation have graduated and are components of EMF now.
>
> Sorry for wrong newslist, but unfortunately the "eclipse.tools.emf" is
> listed neither under EMF project nor elsewhere here:
> http://www.eclipse.org/newsgroups/index_all.php
>
> So it looks like it not exists...


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Undo of RecordingCommand is done in a strange order... [message #608583 is a reply to message #87229] Mon, 25 June 2007 11:44 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33136
Registered: July 2009
Senior Member
Michael,

If what you say is true, it does sound kind of inconsistent. I'll wait
for Christian to comment.


Michael wrote:
> Yes, but AFAIK the difference between invalid state while doing
> changes and invalid state while undo changes is that in first case all
> events are delayed to the end of the transaction, while in the second
> case - not. Isn't that a kind of bug?
>
>> Michael,
>> Please use the EMF newsgroup for questions about the transaction
>> APIs in the future. I've added it to the "to" list. Query,
>> Transaction, and Validation have graduated and are components of EMF
>> now.
>> EMF's ChangeRecorder does not simply record events, it records
>> enough information to know the initial state and then creates a
>> ChangeDescription that describes how to get from the current state to
>> the final state. There is no guarantee that applied changes will be
>> done in any particular order. In general, all the changes for each
>> object will be batched, and if you add something and then remove it
>> again, nothing will happen during undo, since there is no actual
>> change in state. Part of the point of having a transaction is that
>> the intermediate state may well be invalid and it's only at the end
>> of a transaction that the state must be valid. Similarly during a
>> rollback or undo, the intermediate states are not guaranteed to be
>> valid. Perhaps what you really want is multiple transactions. I'm
>> not sure if transactions can be nested or grouped; Christian will
>> know that best.
>> Michael wrote:
>> Hi.
>> I'm using RecordingCommand to catch changes in my EMF model and undo
>> them if needed. The model objects are also mapped to edit parts which
>> hook emf change listeners into the model objects. When
>> RecordingCommand is undone it issues that change events as undo is
>> progressing. And i suddenly found that the order of events during
>> undo of a bunch of EMF model changes is different to the reverse
>> order of events that i receive when making these changes.
>> I've made some debugging and found that when i undo a
>> RecordingCommand, it in turn undoes internal instance of
>> CompositeChangeDescription.
>> CompositeChangeDescription contains list of ChangeDescription, being
>> asked to undo it goes trough the list from the end and undoes each
>> ChangeDescription.
>> This looks like correct unwinding of EMF changes, but surprisingly
>> the list contains only one ChangeDescription that itself contains all
>> the changes.
>> And the changes in list iside this single ChangeDescription are
>> unwinded in the
>> order that is different from both strict and reverseing order of
>> changes as they were performed before undoing... Well, maybe the
>> resulting model will be ok after undoing all primitive changes in
>> that other order, but the problem is that my edit part receives a
>> notification during the undo and the model appears to be in wrong
>> state at this moment.
>> Here is an example trace of the events. I have next structure from
>> EMF objects:
>> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.
>> Each of binding and bindingInstr objects has not-containment property
>> named "type" that is set to ReferencedDesign1. ReferencedDesign1
>> itself is contained in a list property in the topobject. The action
>> is to delete the binding2 and to move it's child binding3 to
>> bindInst1. And the action is made in signle transaction. Then the
>> action is undone. Here are event lists (in format: "eventType:
>> objectInstance.property = oldValue -> newValue):
>> While removing middle node:
>> REMOVE: instr1.bindings[0] = binding2 -> null
>> SET: binding2.parent = instr1 -> null
>> REMOVE: instr2.bindings[0] = binding3 -> null
>> ADD: instr1.bindings[0] = null -> binding3
>> SET: binding3.parent = instr2 -> instr1
>> REMOVE: binding2.instructions[0] = instr2 -> null
>> SET: instr2.type = ReferencedDesign1 -> null
>> SET: binding2.type = ReferencedDesign1 -> null
>> While undoing the remove:
>> SET: binding2.parent = null -> instr1
>> ADD: instr1.bindings[0] = null -> binding2
>> SET: binding3.parent = instr1 -> null
>> REMOVE: instr1.bindings[1] = binding3 -> null
>> ADD: binding2.instructions[0] = null -> instr2
>> SET: binding2.type = null -> ReferencedDesign1
>> SET: binding3.parent = null -> instr2
>> ADD: instr2.bindings[0] = null -> binding3
>> SET: instr2.type = null -> ReferencedDesign1
>> The incorrectness of undo order is obvious (binding2 on the first
>> step of undo is returned into containment hierarhy whereas it's type
>> is not yet restored from null to ReferencedDesign1), please help...
>> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar
>>
>
>
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Undo of RecordingCommand is done in a strange order... [message #608584 is a reply to message #87273] Mon, 25 June 2007 13:44 Go to previous message
Michael is currently offline MichaelFriend
Messages: 43
Registered: July 2009
Member
Not exactly true - i just checked and found that in my case the =

notifications are not deferred, but the code looks like there is a =

possibility of such behaviour (but i have no ideas how to connect this =

with undo - is it correct to perform undo of a transaction in other =

transaction?).

Anyway, it would be good to have some recording functionality that is =

unwinding changes exactly in the way that is reverse to the way of how t=
he =

changes were performed...

> If what you say is true, it does sound kind of inconsistent. I'll wai=
t =

> for Christian to comment.
>
>> Yes, but AFAIK the difference between invalid state while doing chang=
es =

>> and invalid state while undo changes is that in first case all events=
=

>> are delayed to the end of the transaction, while in the second case -=
=

>> not. Isn't that a kind of bug?
>>
>>> Michael,
>>> Please use the EMF newsgroup for questions about the transaction AP=
Is =

>>> in the future. I've added it to the "to" list. Query, Transaction,=
=

>>> and Validation have graduated and are components of EMF now.
>>> EMF's ChangeRecorder does not simply record events, it records enou=
gh =

>>> information to know the initial state and then creates a =

>>> ChangeDescription that describes how to get from the current state t=
o =

>>> the final state. There is no guarantee that applied changes will be=
=

>>> done in any particular order. In general, all the changes for each =
=

>>> object will be batched, and if you add something and then remove it =
=

>>> again, nothing will happen during undo, since there is no actual =

>>> change in state. Part of the point of having a transaction is that =
=

>>> the intermediate state may well be invalid and it's only at the end =
of =

>>> a transaction that the state must be valid. Similarly during a =

>>> rollback or undo, the intermediate states are not guaranteed to be =

>>> valid. Perhaps what you really want is multiple transactions. I'm =
=

>>> not sure if transactions can be nested or grouped; Christian will kn=
ow =

>>> that best.
>>> Michael wrote:
>>> Hi.
>>> I'm using RecordingCommand to catch changes in my EMF model and und=
o =

>>> them if needed. The model objects are also mapped to edit parts whic=
h =

>>> hook emf change listeners into the model objects. When =

>>> RecordingCommand is undone it issues that change events as undo is =

>>> progressing. And i suddenly found that the order of events during un=
do =

>>> of a bunch of EMF model changes is different to the reverse order of=
=

>>> events that i receive when making these changes.
>>> I've made some debugging and found that when i undo a =

>>> RecordingCommand, it in turn undoes internal instance of =

>>> CompositeChangeDescription.
>>> CompositeChangeDescription contains list of ChangeDescription, being=
=

>>> asked to undo it goes trough the list from the end and undoes each =

>>> ChangeDescription.
>>> This looks like correct unwinding of EMF changes, but surprisingly t=
he =

>>> list contains only one ChangeDescription that itself contains all th=
e =

>>> changes.
>>> And the changes in list iside this single ChangeDescription are =

>>> unwinded in the
>>> order that is different from both strict and reverseing order of =

>>> changes as they were performed before undoing... Well, maybe the =

>>> resulting model will be ok after undoing all primitive changes in th=
at =

>>> other order, but the problem is that my edit part receives a =

>>> notification during the undo and the model appears to be in wrong =

>>> state at this moment.
>>> Here is an example trace of the events. I have next structure from =
=

>>> EMF objects:
>>> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.=

>>> Each of binding and bindingInstr objects has not-containment propert=
y =

>>> named "type" that is set to ReferencedDesign1. ReferencedDesign1 =

>>> itself is contained in a list property in the topobject. The action =
is =

>>> to delete the binding2 and to move it's child binding3 to bindInst1.=
=

>>> And the action is made in signle transaction. Then the action is =

>>> undone. Here are event lists (in format: "eventType: =

>>> objectInstance.property =3D oldValue -> newValue):
>>> While removing middle node:
>>> REMOVE: instr1.bindings[0] =3D binding2 -> null
>>> SET: binding2.parent =3D instr1 -> null
>>> REMOVE: instr2.bindings[0] =3D binding3 -> null
>>> ADD: instr1.bindings[0] =3D null -> binding3
>>> SET: binding3.parent =3D instr2 -> instr1
>>> REMOVE: binding2.instructions[0] =3D instr2 -> null
>>> SET: instr2.type =3D ReferencedDesign1 -> null
>>> SET: binding2.type =3D ReferencedDesign1 -> null
>>> While undoing the remove:
>>> SET: binding2.parent =3D null -> instr1
>>> ADD: instr1.bindings[0] =3D null -> binding2
>>> SET: binding3.parent =3D instr1 -> null
>>> REMOVE: instr1.bindings[1] =3D binding3 -> null
>>> ADD: binding2.instructions[0] =3D null -> instr2
>>> SET: binding2.type =3D null -> ReferencedDesign1
>>> SET: binding3.parent =3D null -> instr2
>>> ADD: instr2.bindings[0] =3D null -> binding3
>>> SET: instr2.type =3D null -> ReferencedDesign1
>>> The incorrectness of undo order is obvious (binding2 on the first =
=

>>> step of undo is returned into containment hierarhy whereas it's type=
=

>>> is not yet restored from null to ReferencedDesign1), please help...
>>> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar
Re: Undo of RecordingCommand is done in a strange order... [message #608585 is a reply to message #87288] Mon, 25 June 2007 13:46 Go to previous message
Michael is currently offline MichaelFriend
Messages: 43
Registered: July 2009
Member
> Not exactly true - i just checked and found that in my case the
> notifications are not deferred, but the code looks like there is a
> possibility of such behaviour (but i have no ideas how to connect this
> with undo - is it correct to perform undo of a transaction in other
> transaction?).

(I.e. not deferred to the end of the active transaction while making the
changes)

--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Re: Undo of RecordingCommand is done in a strange order... [message #608586 is a reply to message #87288] Mon, 25 June 2007 15:33 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33136
Registered: July 2009
Senior Member
Michael,

It would probably be better to write your code not to depend order
because we have no plans to implement an event recording mechanism.


Michael wrote:
> Not exactly true - i just checked and found that in my case the
> notifications are not deferred, but the code looks like there is a
> possibility of such behaviour (but i have no ideas how to connect this
> with undo - is it correct to perform undo of a transaction in other
> transaction?).
>
> Anyway, it would be good to have some recording functionality that is
> unwinding changes exactly in the way that is reverse to the way of how
> the changes were performed...
>
>> If what you say is true, it does sound kind of inconsistent. I'll
>> wait for Christian to comment.
>>
>>> Yes, but AFAIK the difference between invalid state while doing
>>> changes and invalid state while undo changes is that in first case
>>> all events are delayed to the end of the transaction, while in the
>>> second case - not. Isn't that a kind of bug?
>>>
>>>> Michael,
>>>> Please use the EMF newsgroup for questions about the transaction
>>>> APIs in the future. I've added it to the "to" list. Query,
>>>> Transaction, and Validation have graduated and are components of
>>>> EMF now.
>>>> EMF's ChangeRecorder does not simply record events, it records
>>>> enough information to know the initial state and then creates a
>>>> ChangeDescription that describes how to get from the current state
>>>> to the final state. There is no guarantee that applied changes
>>>> will be done in any particular order. In general, all the changes
>>>> for each object will be batched, and if you add something and then
>>>> remove it again, nothing will happen during undo, since there is no
>>>> actual change in state. Part of the point of having a transaction
>>>> is that the intermediate state may well be invalid and it's only at
>>>> the end of a transaction that the state must be valid. Similarly
>>>> during a rollback or undo, the intermediate states are not
>>>> guaranteed to be valid. Perhaps what you really want is multiple
>>>> transactions. I'm not sure if transactions can be nested or
>>>> grouped; Christian will know that best.
>>>> Michael wrote:
>>>> Hi.
>>>> I'm using RecordingCommand to catch changes in my EMF model and
>>>> undo them if needed. The model objects are also mapped to edit
>>>> parts which hook emf change listeners into the model objects. When
>>>> RecordingCommand is undone it issues that change events as undo is
>>>> progressing. And i suddenly found that the order of events during
>>>> undo of a bunch of EMF model changes is different to the reverse
>>>> order of events that i receive when making these changes.
>>>> I've made some debugging and found that when i undo a
>>>> RecordingCommand, it in turn undoes internal instance of
>>>> CompositeChangeDescription.
>>>> CompositeChangeDescription contains list of ChangeDescription,
>>>> being asked to undo it goes trough the list from the end and undoes
>>>> each ChangeDescription.
>>>> This looks like correct unwinding of EMF changes, but surprisingly
>>>> the list contains only one ChangeDescription that itself contains
>>>> all the changes.
>>>> And the changes in list iside this single ChangeDescription are
>>>> unwinded in the
>>>> order that is different from both strict and reverseing order of
>>>> changes as they were performed before undoing... Well, maybe the
>>>> resulting model will be ok after undoing all primitive changes in
>>>> that other order, but the problem is that my edit part receives a
>>>> notification during the undo and the model appears to be in wrong
>>>> state at this moment.
>>>> Here is an example trace of the events. I have next structure from
>>>> EMF objects:
>>>> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.
>>>> Each of binding and bindingInstr objects has not-containment
>>>> property named "type" that is set to ReferencedDesign1.
>>>> ReferencedDesign1 itself is contained in a list property in the
>>>> topobject. The action is to delete the binding2 and to move it's
>>>> child binding3 to bindInst1. And the action is made in signle
>>>> transaction. Then the action is undone. Here are event lists (in
>>>> format: "eventType: objectInstance.property = oldValue -> newValue):
>>>> While removing middle node:
>>>> REMOVE: instr1.bindings[0] = binding2 -> null
>>>> SET: binding2.parent = instr1 -> null
>>>> REMOVE: instr2.bindings[0] = binding3 -> null
>>>> ADD: instr1.bindings[0] = null -> binding3
>>>> SET: binding3.parent = instr2 -> instr1
>>>> REMOVE: binding2.instructions[0] = instr2 -> null
>>>> SET: instr2.type = ReferencedDesign1 -> null
>>>> SET: binding2.type = ReferencedDesign1 -> null
>>>> While undoing the remove:
>>>> SET: binding2.parent = null -> instr1
>>>> ADD: instr1.bindings[0] = null -> binding2
>>>> SET: binding3.parent = instr1 -> null
>>>> REMOVE: instr1.bindings[1] = binding3 -> null
>>>> ADD: binding2.instructions[0] = null -> instr2
>>>> SET: binding2.type = null -> ReferencedDesign1
>>>> SET: binding3.parent = null -> instr2
>>>> ADD: instr2.bindings[0] = null -> binding3
>>>> SET: instr2.type = null -> ReferencedDesign1
>>>> The incorrectness of undo order is obvious (binding2 on the first
>>>> step of undo is returned into containment hierarhy whereas it's
>>>> type is not yet restored from null to ReferencedDesign1), please
>>>> help...
>>>> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Undo of RecordingCommand is done in a strange order... [message #608587 is a reply to message #87288] Mon, 25 June 2007 19:24 Go to previous message
Eclipse UserFriend
Originally posted by: cdamus.ca.ibm.com

Hi, Michael,

To respond to a few of your questions (sorry for the delay; I was away on
vacation) ...

All changes must be performed in transactions, including undo/redo of
previous changes. For undo/redo, the TransactionalCommandStack creates
transactions in which to replay the ChangeDescription that do not bother to

- record changes for undo/redo/rollback (since we already have them)
- validate changes (since we are moving between known valid states)
- execute triggers (since we are moving between known valid states)

Perhaps what you are seeing that suggests an immediate reporting of changes
to listeners is the "broadcastUnbatched(Notification)" method? This is
only used for simulating transaction post-commit events in a context where
there is no transaction. In such cases, the changes represented by
Notifications are necessarily only those that do not require a read/write
transaction, such as proxy resolution and resource loading.

Finally, regarding the ordering of changes when undoing or redoing. It is,
indeed, assumed by EMF that the ordering of changes is irrelevant to
effecting the correct change in the resource set's contents. All code
generated by EMF is consistent with this assumption, because EMF never
generates "side-effects" in the code. However, it is possible that
post-generation customizations will do this. For example, the Eclipse UML2
implementation automatically applies/unapplies Stereotypes whenever the
containment of an Element is changed, in order to proactively maintain the
integrity of stereotype applications, by customizing the
eBasicSetContainer(...) method. This has caused numerous undo/redo
problems for some applications that I know of. IMO, such side-effects are
better left to "triggers" in the EMF Transaction API (which are
specifically designed for this purpose). The nice thing about triggers is
that their changes are recorded in nested transactions and, hence, in
distinct change-descriptions within the composite. This preserves the
ordering of those changes with respect to the client's intended changes.

Cheers,

Christian


Michael wrote:

> Not exactly true - i just checked and found that in my case the
> notifications are not deferred, but the code looks like there is a
> possibility of such behaviour (but i have no ideas how to connect this
> with undo - is it correct to perform undo of a transaction in other
> transaction?).
>
> Anyway, it would be good to have some recording functionality that is
> unwinding changes exactly in the way that is reverse to the way of how the
> changes were performed...
>
>> If what you say is true, it does sound kind of inconsistent. I'll wait
>> for Christian to comment.
>>
>>> Yes, but AFAIK the difference between invalid state while doing changes
>>> and invalid state while undo changes is that in first case all events
>>> are delayed to the end of the transaction, while in the second case -
>>> not. Isn't that a kind of bug?
>>>
>>>> Michael,
>>>> Please use the EMF newsgroup for questions about the transaction APIs
>>>> in the future. I've added it to the "to" list. Query, Transaction,
>>>> and Validation have graduated and are components of EMF now.
>>>> EMF's ChangeRecorder does not simply record events, it records enough
>>>> information to know the initial state and then creates a
>>>> ChangeDescription that describes how to get from the current state to
>>>> the final state. There is no guarantee that applied changes will be
>>>> done in any particular order. In general, all the changes for each
>>>> object will be batched, and if you add something and then remove it
>>>> again, nothing will happen during undo, since there is no actual
>>>> change in state. Part of the point of having a transaction is that
>>>> the intermediate state may well be invalid and it's only at the end of
>>>> a transaction that the state must be valid. Similarly during a
>>>> rollback or undo, the intermediate states are not guaranteed to be
>>>> valid. Perhaps what you really want is multiple transactions. I'm
>>>> not sure if transactions can be nested or grouped; Christian will know
>>>> that best.
>>>> Michael wrote:
>>>> Hi.
>>>> I'm using RecordingCommand to catch changes in my EMF model and undo
>>>> them if needed. The model objects are also mapped to edit parts which
>>>> hook emf change listeners into the model objects. When
>>>> RecordingCommand is undone it issues that change events as undo is
>>>> progressing. And i suddenly found that the order of events during undo
>>>> of a bunch of EMF model changes is different to the reverse order of
>>>> events that i receive when making these changes.
>>>> I've made some debugging and found that when i undo a
>>>> RecordingCommand, it in turn undoes internal instance of
>>>> CompositeChangeDescription.
>>>> CompositeChangeDescription contains list of ChangeDescription, being
>>>> asked to undo it goes trough the list from the end and undoes each
>>>> ChangeDescription.
>>>> This looks like correct unwinding of EMF changes, but surprisingly the
>>>> list contains only one ChangeDescription that itself contains all the
>>>> changes.
>>>> And the changes in list iside this single ChangeDescription are
>>>> unwinded in the
>>>> order that is different from both strict and reverseing order of
>>>> changes as they were performed before undoing... Well, maybe the
>>>> resulting model will be ok after undoing all primitive changes in that
>>>> other order, but the problem is that my edit part receives a
>>>> notification during the undo and the model appears to be in wrong
>>>> state at this moment.
>>>> Here is an example trace of the events. I have next structure from
>>>> EMF objects:
>>>> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding3.
>>>> Each of binding and bindingInstr objects has not-containment property
>>>> named "type" that is set to ReferencedDesign1. ReferencedDesign1
>>>> itself is contained in a list property in the topobject. The action is
>>>> to delete the binding2 and to move it's child binding3 to bindInst1.
>>>> And the action is made in signle transaction. Then the action is
>>>> undone. Here are event lists (in format: "eventType:
>>>> objectInstance.property = oldValue -> newValue):
>>>> While removing middle node:
>>>> REMOVE: instr1.bindings[0] = binding2 -> null
>>>> SET: binding2.parent = instr1 -> null
>>>> REMOVE: instr2.bindings[0] = binding3 -> null
>>>> ADD: instr1.bindings[0] = null -> binding3
>>>> SET: binding3.parent = instr2 -> instr1
>>>> REMOVE: binding2.instructions[0] = instr2 -> null
>>>> SET: instr2.type = ReferencedDesign1 -> null
>>>> SET: binding2.type = ReferencedDesign1 -> null
>>>> While undoing the remove:
>>>> SET: binding2.parent = null -> instr1
>>>> ADD: instr1.bindings[0] = null -> binding2
>>>> SET: binding3.parent = instr1 -> null
>>>> REMOVE: instr1.bindings[1] = binding3 -> null
>>>> ADD: binding2.instructions[0] = null -> instr2
>>>> SET: binding2.type = null -> ReferencedDesign1
>>>> SET: binding3.parent = null -> instr2
>>>> ADD: instr2.bindings[0] = null -> binding3
>>>> SET: instr2.type = null -> ReferencedDesign1
>>>> The incorrectness of undo order is obvious (binding2 on the first
>>>> step of undo is returned into containment hierarhy whereas it's type
>>>> is not yet restored from null to ReferencedDesign1), please help...
>>>> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.jar
Re: Undo of RecordingCommand is done in a strange order... [message #608591 is a reply to message #87335] Tue, 26 June 2007 09:43 Go to previous message
Michael is currently offline MichaelFriend
Messages: 43
Registered: July 2009
Member
Hi, Christian.

Thanks for your reply. I will think over the things you wrote to develop=
a =

solution for my problem.

> Hi, Michael,
>
> To respond to a few of your questions (sorry for the delay; I was away=
on
> vacation) ...
>
> All changes must be performed in transactions, including undo/redo of
> previous changes. For undo/redo, the TransactionalCommandStack create=
s
> transactions in which to replay the ChangeDescription that do not both=
er =

> to
>
> - record changes for undo/redo/rollback (since we already have them)=

> - validate changes (since we are moving between known valid states)
> - execute triggers (since we are moving between known valid states)
>
> Perhaps what you are seeing that suggests an immediate reporting of =

> changes
> to listeners is the "broadcastUnbatched(Notification)" method? This i=
s
> only used for simulating transaction post-commit events in a context =

> where
> there is no transaction. In such cases, the changes represented by
> Notifications are necessarily only those that do not require a read/wr=
ite
> transaction, such as proxy resolution and resource loading.
>
> Finally, regarding the ordering of changes when undoing or redoing. I=
t =

> is,
> indeed, assumed by EMF that the ordering of changes is irrelevant to
> effecting the correct change in the resource set's contents. All code=

> generated by EMF is consistent with this assumption, because EMF never=

> generates "side-effects" in the code. However, it is possible that
> post-generation customizations will do this. For example, the Eclipse=
=

> UML2
> implementation automatically applies/unapplies Stereotypes whenever th=
e
> containment of an Element is changed, in order to proactively maintain=
=

> the
> integrity of stereotype applications, by customizing the
> eBasicSetContainer(...) method. This has caused numerous undo/redo
> problems for some applications that I know of. IMO, such side-effects=
=

> are
> better left to "triggers" in the EMF Transaction API (which are
> specifically designed for this purpose). The nice thing about trigger=
s =

> is
> that their changes are recorded in nested transactions and, hence, in
> distinct change-descriptions within the composite. This preserves the=

> ordering of those changes with respect to the client's intended change=
s.
>
> Cheers,
>
> Christian
>
>
> Michael wrote:
>
>> Not exactly true - i just checked and found that in my case the
>> notifications are not deferred, but the code looks like there is a
>> possibility of such behaviour (but i have no ideas how to connect thi=
s
>> with undo - is it correct to perform undo of a transaction in other
>> transaction?).
>>
>> Anyway, it would be good to have some recording functionality that is=

>> unwinding changes exactly in the way that is reverse to the way of ho=
w =

>> the
>> changes were performed...
>>
>>> If what you say is true, it does sound kind of inconsistent. I'll w=
ait
>>> for Christian to comment.
>>>
>>>> Yes, but AFAIK the difference between invalid state while doing =

>>>> changes
>>>> and invalid state while undo changes is that in first case all even=
ts
>>>> are delayed to the end of the transaction, while in the second case=
-
>>>> not. Isn't that a kind of bug?
>>>>
>>>>> Michael,
>>>>> Please use the EMF newsgroup for questions about the transaction =
=

>>>>> APIs
>>>>> in the future. I've added it to the "to" list. Query, Transactio=
n,
>>>>> and Validation have graduated and are components of EMF now.
>>>>> EMF's ChangeRecorder does not simply record events, it records =

>>>>> enough
>>>>> information to know the initial state and then creates a
>>>>> ChangeDescription that describes how to get from the current state=
to
>>>>> the final state. There is no guarantee that applied changes will =
be
>>>>> done in any particular order. In general, all the changes for eac=
h
>>>>> object will be batched, and if you add something and then remove i=
t
>>>>> again, nothing will happen during undo, since there is no actual
>>>>> change in state. Part of the point of having a transaction is tha=
t
>>>>> the intermediate state may well be invalid and it's only at the en=
d =

>>>>> of
>>>>> a transaction that the state must be valid. Similarly during a
>>>>> rollback or undo, the intermediate states are not guaranteed to be=

>>>>> valid. Perhaps what you really want is multiple transactions. I'=
m
>>>>> not sure if transactions can be nested or grouped; Christian will =
=

>>>>> know
>>>>> that best.
>>>>> Michael wrote:
>>>>> Hi.
>>>>> I'm using RecordingCommand to catch changes in my EMF model and u=
ndo
>>>>> them if needed. The model objects are also mapped to edit parts wh=
ich
>>>>> hook emf change listeners into the model objects. When
>>>>> RecordingCommand is undone it issues that change events as undo is=

>>>>> progressing. And i suddenly found that the order of events during =
=

>>>>> undo
>>>>> of a bunch of EMF model changes is different to the reverse order =
of
>>>>> events that i receive when making these changes.
>>>>> I've made some debugging and found that when i undo a
>>>>> RecordingCommand, it in turn undoes internal instance of
>>>>> CompositeChangeDescription.
>>>>> CompositeChangeDescription contains list of ChangeDescription, bei=
ng
>>>>> asked to undo it goes trough the list from the end and undoes each=

>>>>> ChangeDescription.
>>>>> This looks like correct unwinding of EMF changes, but surprisingly=
=

>>>>> the
>>>>> list contains only one ChangeDescription that itself contains all =
the
>>>>> changes.
>>>>> And the changes in list iside this single ChangeDescription are
>>>>> unwinded in the
>>>>> order that is different from both strict and reverseing order of
>>>>> changes as they were performed before undoing... Well, maybe the
>>>>> resulting model will be ok after undoing all primitive changes in =
=

>>>>> that
>>>>> other order, but the problem is that my edit part receives a
>>>>> notification during the undo and the model appears to be in wrong
>>>>> state at this moment.
>>>>> Here is an example trace of the events. I have next structure fro=
m
>>>>> EMF objects:
>>>>> topobject -> binding1 -> inst1 -> binding2 -> instr2 -> binding=
3.
>>>>> Each of binding and bindingInstr objects has not-containment prope=
rty
>>>>> named "type" that is set to ReferencedDesign1. ReferencedDesign1
>>>>> itself is contained in a list property in the topobject. The actio=
n =

>>>>> is
>>>>> to delete the binding2 and to move it's child binding3 to bindInst=
1.
>>>>> And the action is made in signle transaction. Then the action is
>>>>> undone. Here are event lists (in format: "eventType:
>>>>> objectInstance.property =3D oldValue -> newValue):
>>>>> While removing middle node:
>>>>> REMOVE: instr1.bindings[0] =3D binding2 -> null
>>>>> SET: binding2.parent =3D instr1 -> null
>>>>> REMOVE: instr2.bindings[0] =3D binding3 -> null
>>>>> ADD: instr1.bindings[0] =3D null -> binding3
>>>>> SET: binding3.parent =3D instr2 -> instr1
>>>>> REMOVE: binding2.instructions[0] =3D instr2 -> null
>>>>> SET: instr2.type =3D ReferencedDesign1 -> null
>>>>> SET: binding2.type =3D ReferencedDesign1 -> null
>>>>> While undoing the remove:
>>>>> SET: binding2.parent =3D null -> instr1
>>>>> ADD: instr1.bindings[0] =3D null -> binding2
>>>>> SET: binding3.parent =3D instr1 -> null
>>>>> REMOVE: instr1.bindings[1] =3D binding3 -> null
>>>>> ADD: binding2.instructions[0] =3D null -> instr2
>>>>> SET: binding2.type =3D null -> ReferencedDesign1
>>>>> SET: binding3.parent =3D null -> instr2
>>>>> ADD: instr2.bindings[0] =3D null -> binding3
>>>>> SET: instr2.type =3D null -> ReferencedDesign1
>>>>> The incorrectness of undo order is obvious (binding2 on the firs=
t
>>>>> step of undo is returned into containment hierarhy whereas it's ty=
pe
>>>>> is not yet restored from null to ReferencedDesign1), please help..=
..
>>>>> PS. I'm using org.eclipse.emf.transaction_1.0.2.v200611161636.ja=
r
>



-- =

Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Previous Topic:no implementation classes of "java.lang.Object" have been found!
Next Topic:[Teneo] doUnload() in the StoreResource
Goto Forum:
  


Current Time: Fri Apr 19 04:17:09 GMT 2024

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

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

Back to the top