[squeak-dev] Undoable environment ?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Undoable environment ?

Sophie424
I have commands that I would like to make undoable. Is it possible to wrap
the commands within an "undoable" environment as suggested in
http://www.ceteva.com/forum/viewtopic.php?t=17

I imagine something like this (but wouldn't know where to start):

A>>setFoo: aFoo
    Undoable newOn: [ foo := aFoo ]

A>>setBar: aBar
    Undoable newOn: [ bar := aBar ]

a := A new foo: 0; bar: 0; yourself.
a setFoo: 5.
a setBar: 10.
Undoable undo. "a bar == 0"
Undoable undo. "a foo == 0"
Undoable redo. "a foo == 10"

Thanks - Sophie




Reply | Threaded
Open this post in threaded view
|

RE: [squeak-dev] Undoable environment ?

Gary Chambers-4
Have a look at the Command and CommandHistory clasees. Worked well for our
Report Builder...

Gary.

> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]]On Behalf Of
> itsme213
> Sent: 29 April 2008 6:37 PM
> To: [hidden email]
> Subject: [squeak-dev] Undoable environment ?
>
>
> I have commands that I would like to make undoable. Is it
> possible to wrap
> the commands within an "undoable" environment as suggested in
> http://www.ceteva.com/forum/viewtopic.php?t=17
>
> I imagine something like this (but wouldn't know where to start):
>
> A>>setFoo: aFoo
>     Undoable newOn: [ foo := aFoo ]
>
> A>>setBar: aBar
>     Undoable newOn: [ bar := aBar ]
>
> a := A new foo: 0; bar: 0; yourself.
> a setFoo: 5.
> a setBar: 10.
> Undoable undo. "a bar == 0"
> Undoable undo. "a foo == 0"
> Undoable redo. "a foo == 10"
>
> Thanks - Sophie
>
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Undoable environment ?

johnmci
In reply to this post by Sophie424
There is an undo system that impara wrote for Sophie. You should  
consider it, we used it extensively to make *most* actions (some VERY  
complex ones) undoable/redoable, this also included
the ability to transparently nest actions, such as having one action  
be a consolidation of multiple sub actions, then treat the one  
container action as an atomic do/undo/redo item.

Say for example do most any textual editing, frame layout, page  
manipulation for 20 mintues, then hold the undo-key down and watch it  
rollback everything.

On Apr 29, 2008, at 10:36 AM, itsme213 wrote:

> I have commands that I would like to make undoable. Is it possible  
> to wrap
> the commands within an "undoable" environment as suggested in
> http://www.ceteva.com/forum/viewtopic.php?t=17
>
> I imagine something like this (but wouldn't know where to start):
>
> A>>setFoo: aFoo
>    Undoable newOn: [ foo := aFoo ]
>
> A>>setBar: aBar
>    Undoable newOn: [ bar := aBar ]
>
> a := A new foo: 0; bar: 0; yourself.
> a setFoo: 5.
> a setBar: 10.
> Undoable undo. "a bar == 0"
> Undoable undo. "a foo == 0"
> Undoable redo. "a foo == 10"
>
> Thanks - Sophie
>
>
>
>

--
=
=
=
========================================================================
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
=
=
=
========================================================================



Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Undoable environment ?

Sophie424
"John M McIntosh" <[hidden email]> wrote

> There is an undo system that impara wrote for Sophie. You should  consider
> it,

Where will I find this? I downloaded Sophie and don't see image + sources.

Thanks.




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Undoable environment ?

Frank Urbach
In reply to this post by Sophie424
Hi Sophie,

you can start Sophie in the normal way. After the startup is proceed go to the File-Menue and klick on exit. The sophie-system will be closed and you are in the squeak-system below sophie. There you find a package called Sophie-Undo.

HTH
  Frank

-------- Original Message --------
Subject: [squeak-dev] Re: Undoable environment ? (30-Apr-2008 14:49)
From:    itsme213 <[hidden email]>
To:      [hidden email]

> "John M McIntosh" <[hidden email]> wrote
>
> > There is an undo system that impara wrote for Sophie. You should  consider
> > it,
>
> Where will I find this? I downloaded Sophie and don't see image + sources.
>
> Thanks.
>
>
>
>
>

Edelstahlwerke Schmees GmbH
Geschäftsleitung Clemens Schmees
Sitz D-01796 Pirna
Handelsregister Dresden HRB 54
E-Mail: [hidden email]
WEB:     www.schmees.com
 
Diese E-Mail enthält vertrauliche und/oder rechtlich geschützte Informationen. Wenn Sie nicht der richtige Adressat sind oder diese E-Mail irrtümlich erhalten haben, informieren Sie bitte sofort den Absender und vernichten Sie diese Mail. Das unerlaubte Kopieren sowie die unbefugte Weitergabe dieser Mail ist nicht gestattet.
 
This e-mail may contain confidental and/or privileged information. If you are not intended recipient or have received this e-mail in error, please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden.



Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Undoable environment ?

Sophie424
In reply to this post by Gary Chambers-4
"Gary Chambers" <[hidden email]> wrote in message

>> A>>setFoo: aFoo
>>     Undoable newOn: [ foo := aFoo ]

> Have a look at the Command and CommandHistory clasees. Worked well for our
> Report Builder...

I am hoping to find a way for Undoable to dynamically extend a few
primitives (e.g. assiging to an instVar or indexedVar, probably adding or
removing indexedVars, others??).

========== e.g. currently:

Object>> instVarAt: anInteger put: anObject
 <primitive: 74>
 ^self basicAt: anInteger - self class instSize put: anObject

========== Dynamically change to:

Object>> instVarAt: anInteger put: anObject
  self recordIVarChange: anInteger oldVal: self instVarAt: anInteger.
  self primInstVarAt: anInteger put: anObject

Object>> primInstVarAt: anInteger put: anObject
 <primitive: 74>
 ^self basicAt: anInteger - self class instSize put: anObject

===========
Then #recordIVarChange can put undoable/redoable records on the stack.

Does this sound feasible? Scary to dynamically re-define primitive methods,
don't know where to start :-(

Sophie





Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Re: Undoable environment ?

Sophie424
In reply to this post by Frank Urbach
> There you find a package called Sophie-Undo.

Thanks!




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Undoable environment ?

Bert Freudenberg
In reply to this post by Sophie424

On 30.04.2008, at 16:22, itsme213 wrote:

> "Gary Chambers" <[hidden email]> wrote in message
>
>>> A>>setFoo: aFoo
>>>    Undoable newOn: [ foo := aFoo ]
>
>> Have a look at the Command and CommandHistory clasees. Worked well  
>> for our
>> Report Builder...
>
> I am hoping to find a way for Undoable to dynamically extend a few
> primitives (e.g. assiging to an instVar or indexedVar, probably  
> adding or
> removing indexedVars, others??).
>
> ========== e.g. currently:
>
> Object>> instVarAt: anInteger put: anObject
> <primitive: 74>
> ^self basicAt: anInteger - self class instSize put: anObject
>
> ========== Dynamically change to:
>
> Object>> instVarAt: anInteger put: anObject
>  self recordIVarChange: anInteger oldVal: self instVarAt: anInteger.
>  self primInstVarAt: anInteger put: anObject
>
> Object>> primInstVarAt: anInteger put: anObject
> <primitive: 74>
> ^self basicAt: anInteger - self class instSize put: anObject
>
> ===========
> Then #recordIVarChange can put undoable/redoable records on the stack.
>
> Does this sound feasible? Scary to dynamically re-define primitive  
> methods,
> don't know where to start :-(


This will not work. #instVarAt:put: is not called for regular inst var  
assignments.

Besides, you certainly only want to do that for your domain objects.  
One way to achieve that is to extend the compiler for your class  
hierarchy and make it insert the #recordIVarChange:oldVal:instVarAt:  
send right before or after the assignment bytecode.

This is how Tweak objects work - it has "fields" that can be used  
exactly like instance variables in code, but actually generate change  
events when assigned. It compiles any inst var assignment (and usage)  
as message send of an accessor named like the variable. The setter  
then generates the change events. The getter can be used to implement  
"virtual fields" with a computed value.

- Bert -



Reply | Threaded
Open this post in threaded view
|

RE: [squeak-dev] Re: Undoable environment ?

Gary Chambers-4
In reply to this post by Sophie424
You'd need to be very careful... and probably need to redefine
instVarAt:put: in the object that handles the command/undo to do the normal
thing (to avoid recursion).

Of course, assignments to ivars in methods won't actually call
instVarAt:put: (done in the bytecode I believe).

Can you explain the general functionality you are hoping to obtain?

Gary.


> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]]On Behalf Of
> itsme213
> Sent: 30 April 2008 3:22 PM
> To: [hidden email]
> Subject: [squeak-dev] Re: Undoable environment ?
>
>
> "Gary Chambers" <[hidden email]> wrote in message
>
> >> A>>setFoo: aFoo
> >>     Undoable newOn: [ foo := aFoo ]
>
> > Have a look at the Command and CommandHistory clasees. Worked
> well for our
> > Report Builder...
>
> I am hoping to find a way for Undoable to dynamically extend a few
> primitives (e.g. assiging to an instVar or indexedVar, probably adding or
> removing indexedVars, others??).
>
> ========== e.g. currently:
>
> Object>> instVarAt: anInteger put: anObject
>  <primitive: 74>
>  ^self basicAt: anInteger - self class instSize put: anObject
>
> ========== Dynamically change to:
>
> Object>> instVarAt: anInteger put: anObject
>   self recordIVarChange: anInteger oldVal: self instVarAt: anInteger.
>   self primInstVarAt: anInteger put: anObject
>
> Object>> primInstVarAt: anInteger put: anObject
>  <primitive: 74>
>  ^self basicAt: anInteger - self class instSize put: anObject
>
> ===========
> Then #recordIVarChange can put undoable/redoable records on the stack.
>
> Does this sound feasible? Scary to dynamically re-define
> primitive methods,
> don't know where to start :-(
>
> Sophie
>
>
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Undoable environment ?

johnmci
In reply to this post by Frank Urbach

On Apr 30, 2008, at 6:09 AM, Frank Urbach wrote:

> Hi Sophie,
>
> you can start Sophie in the normal way. After the startup is proceed  
> go to the File-Menue and klick on exit. The sophie-system will be  
> closed and you are in the squeak-system below sophie. There you find  
> a package called Sophie-Undo.
>
> HTH
>  Frank


That won't work in the production release.  The magic keystrokes to  
quit the running Sophie Application are to.

a) download Sophie from http://www.sophieproject.org/download
b) install and start
c) Once Sophie is running do cmd-'.'   or whatever the interrupt key  
is on your platform.
d) In the Squeak debugger window that comes up enter
e)  SophieApplication singleton ui close
f)  invoke doit on the above smalltalk code.


The SophieApplication singleton returns the sole instance of the  
running SophieApplication
ui returns the user interface
close is the command to tweak/morphic to close the CWorld that is  
hosing the SophieApplication

Once Sophie has stopped you may need to do
SophieSystem resetSystem.
SophieSystem cleanoutInstances.
to reset the system and to garbage collection *all* instances of any  
sophie class.

then you can use either of the  two morphic buttons to start Sophie  
or Sophie Reader in full screen mode.

You can choose to start it in window mode via:  "SophieApplication  
open "

--
=
=
=
========================================================================
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
=
=
=
========================================================================



Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Re: Undoable environment ?

Sophie424
In reply to this post by Gary Chambers-4
"Gary Chambers" <[hidden email]> wrote in message

> Can you explain the general functionality you are hoping to obtain?

Generic undo of arbitrary domain-object actions with no extra effort.

AnyObject>> anyMethod
    Undoable on: [ any side effect block, recursively ]

or,  Undoable on: [ anyObject anyMethod ]

- Sophie




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Re: Undoable environment ?

Lukas Renggli
> Generic undo of arbitrary domain-object actions with no extra effort.
>
>  AnyObject>> anyMethod
>     Undoable on: [ any side effect block, recursively ]
>
>  or,  Undoable on: [ anyObject anyMethod ]

Get GemStone and use transactions.

Or if you are extremely adventurous use the transactional memory I
implemented in Squeak:
<http://source.lukas-renggli.ch/transactional.html>.

Other than that you probably can't avoid wrapping #anyMethod into a
Command object, as described by the "Design Patterns Smalltalk
Companion" book.

Lukas

--
Lukas Renggli
http://www.lukas-renggli.ch

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Re: Undoable environment ?

Lukas Renggli
>  Other than that you probably can't avoid wrapping #anyMethod into a
>  Command object, as described by the "Design Patterns Smalltalk
>  Companion" book.

Ahh, there is one more thing ...

If you know (or are able to calculate) a list of objects that are
changed during #anyMethod, then you can use Seaside's object
backtracking mechanism.

Lukas

--
Lukas Renggli
http://www.lukas-renggli.ch

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Re: Undoable environment ?

timrowledge
In reply to this post by Sophie424

On 30-Apr-08, at 1:18 PM, itsme213 wrote:

> "Gary Chambers" <[hidden email]> wrote in message
>
>> Can you explain the general functionality you are hoping to obtain?
>
> Generic undo of arbitrary domain-object actions with no extra effort.
Unless you propose to make a practical completely reversible  
computational system I suspect you are heading for some disappointment.

Not all actions have trivially derivable inverse actions. Consider a  
real example from Sophie that occupied me for several days; inserting  
a character into a paragraph. Sound pathetically simple, doesn't it?

Until you realise that the character might be carrying a style that is  
not the same as the text where it is being inserted. Or that the  
insertion point is in between two adjacent pagebreaks.
If the character's style matches the style of where it is being  
inserted, you can simply stick the Character into the relevant String.  
The undo record would record the insertion index; simple.
If the character style doesn't match, then you have to split the  
string, make a new string for the character, insert that into the  
paragraph. Of course, the insertion point might be at the very  
beginning or end of the string and that adds some extra twists. The  
undo record needs to record that a new string was added instead of  
merely a Character being put into a String. The undo action has to  
remove that string and remerge the split halves if needed. Oh, and all  
cases have to make sure that any annotations like highlighting get  
updated to account for the splitting, inserting, merging etc.

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Strange OpCodes: ESBD: Erase System and Burn Documentation



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Re: Undoable environment ?

dpharris
In reply to this post by Sophie424
Quoting tim Rowledge <[hidden email]>:

>
> On 30-Apr-08, at 1:18 PM, itsme213 wrote:
>
> > "Gary Chambers" <[hidden email]> wrote in message
> >
> >> Can you explain the general functionality you are hoping to obtain?
> >
> > Generic undo of arbitrary domain-object actions with no extra effort.
> Unless you propose to make a practical completely reversible  
> computational system I suspect you are heading for some disappointment.
>
> Not all actions have trivially derivable inverse actions. Consider a  
> real example from Sophie that occupied me for several days; inserting  
> a character into a paragraph. Sound pathetically simple, doesn't it?
>
> Until you realise that the character might be carrying a style that is  
> not the same as the text where it is being inserted. Or that the  
> insertion point is in between two adjacent pagebreaks.
> If the character's style matches the style of where it is being  
> inserted, you can simply stick the Character into the relevant String.  
> The undo record would record the insertion index; simple.
> If the character style doesn't match, then you have to split the  
> string, make a new string for the character, insert that into the  
> paragraph. Of course, the insertion point might be at the very  
> beginning or end of the string and that adds some extra twists. The  
> undo record needs to record that a new string was added instead of  
> merely a Character being put into a String. The undo action has to  
> remove that string and remerge the split halves if needed. Oh, and all  
> cases have to make sure that any annotations like highlighting get  
> updated to account for the splitting, inserting, merging etc.
>
> tim
> --
> tim Rowledge; [hidden email]; http://www.rowledge.org/tim
> Strange OpCodes: ESBD: Erase System and Burn Documentation

But surely all that logic is built into the application, so the inverse
operation is 'delete character at insertion index' - since you obviously need
this functionality.  Nobody said it was easy or trivial.

David



>
>
>
>





Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Undoable environment ?

stephane ducasse
In reply to this post by Sophie424
You can also have a look at the Iterator DP in the Smalltalk companion  
they have  an hisotrystream to manipulate commands
and do undo.
On Apr 29, 2008, at 7:36 PM, itsme213 wrote:

> I have commands that I would like to make undoable. Is it possible  
> to wrap
> the commands within an "undoable" environment as suggested in
> http://www.ceteva.com/forum/viewtopic.php?t=17
>
> I imagine something like this (but wouldn't know where to start):
>
> A>>setFoo: aFoo
>    Undoable newOn: [ foo := aFoo ]
>
> A>>setBar: aBar
>    Undoable newOn: [ bar := aBar ]
>
> a := A new foo: 0; bar: 0; yourself.
> a setFoo: 5.
> a setBar: 10.
> Undoable undo. "a bar == 0"
> Undoable undo. "a foo == 0"
> Undoable redo. "a foo == 10"
>
> Thanks - Sophie
>
>
>
>
>


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Re: Undoable environment ?

Sophie424
In reply to this post by Frank Urbach
Thank you, all!

Sophie