I would like to use R.oo and tcltk to implement a Turtle World. I have encountered many problems because: 1) I am not sure how to implement static fields with R.oo 2) I am not sure how to implement a constructor that would call a function only for the first instance of a class (i.e., to initialize value of static fields only once) 3) I am not sure how to remove/delete cleanly existing instances. In particular, I don't know how to reset tcktk when the last instance is deleted. Here is the sort of behavior I would like to get: t1<-TurtleBasic() # a window (the Turtle world) with a turtle appears forward(t1,50) # the turtle moves (turtle's state is also updated) turn(t1,pi/2) forward(t1,50) t2<-TurtleBasic() # a second turtle in the Turtle world appears turn(t2,pi/2) # second turtle moves forward(t1,50) delete(t1) # first turtle disappears delete(t2) # second turtle and the world disappears If possible, I would like to keep this syntax. In fact, I am using R.oo to create mutable objects so as to avoid syntax like tu<-forward(tu,10) which would be more typical of a functional language like R. From the doc/help files of R.oo, I believe that one could do it but I don't find many examples to guide me. I pasted my current code with comments below. Thank you for your help. Gabriel Baud-Bovy #--------------------------------------------------------------------------------------------------------------------- Description of Turtle Basic Class: private fields: .x, .y, .a (turtle position and heading) .turtle: ID of canvas item representing turtle static fields: .canvas: tcltk canvas widget .top: tcktk toplevel widget methods: TurtleBasic: constructor plot: display turtle in Turtle World forward, turn: move turtle delete: delete turtle (not implemented) Note: My current code is very buggy: - Can't see turtle movements - Does not define method to delete turtles - I get an tcltk error when I try to recreate a turtle world after having tried to destroy it (for the moment, I need to detach tcltk to reset it) #--------------------------------------------------------------------------------------------------------------------- library("R.oo") setConstructorS3("TurtleBasic",function() { new<-extend(Object(),"TurtleBasic",.x=100,.y=100,.a=0,.turtle=NA) ## Create a new Turtle World if necessary require(tcltk) || stop("tcl/ library not available") if(!is.tkwin(new$.canvas)) { # check to see if it is first instance or not cat("Create Turtle World\n") top <- tktoplevel() tktitle(top) <- "Turtle World" canvas <- tkcanvas(top, relief="raised", width=200, height=200) tkpack(canvas, side="top", fill="both",expand="1") new$.canvas<-canvas # store canvas widget in static field new$.top<-top } plot.TurtleBasic(new) # plot Turtle new }) setMethodS3("plot","TurtleBasic",function(turtle) { ## delete old item (if it exists) if(is.tkwin(turtle$.canvas) && is.tclObj(turtle$.turtle)) tkdelete(turtle$.canvas,turtle$.turtle) ## a new canvas item representing the turtle is created ## (note: it's necessary to make new item because turtle's heading can change) x <- c(-10,10) y <- c(-10,10) aux<- cos(turtle$.a)*x+sin(turtle$.a)*y + turtle$.x y <- -sin(turtle$.a)*x+cos(turtle$.a)*y + turtle$.y x <- aux turtle$.turtle <- tkcreate(turtle$.canvas, "line", x[1],-y[1],x[2],-y[2],width=1) }) setMethodS3("forward","TurtleBasic",function(turtle,length){ aux <- turtle$.x + length*cos(turtle$.a) turtle$.y <- turtle$.y + length*sin(turtle$.a) turtle$.x <- aux plot(turtle) }) setMethodS3("turn","TurtleBasic",function(turtle,angle){ turtle$.a<-turtle$.a+angle plot(turtle) }) if(0) { t1<-TurtleBasic() # a window (the Turtle world) with a turtle appears forward(t1,50) turn(t1,pi/2) forward(t1,50) t2<-TurtleBasic() # a second turtle in the Turtle world turn(t2,pi/2) # manually destroy first turtle (would be great to define some sort of method for it) tkdelete(t1$.canvas,t1$.turtle) rm(t1) # destroy second turtle and world tkdelete(t2$.canvas,t2$.turtle) tkdestroy(t2$.top) rm(t2) } -------------------------------------------------------------------- Gabriel Baud-Bovy Assistant Professor UHSR University via Olgettina, 58 tel: (+39) 02 2643 4839 20132 Milan, Italy fax: (+39) 02 2643 4892
This is not really an rhelp question. I'll get back to you later today with answers related to R.oo. Henrik Bengtsson The R.oo author> -----Original Message----- > From: r-help-bounces at stat.math.ethz.ch > [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of > Gabriel Baud-Bovy > Sent: den 27 oktober 2003 01:56 > To: r-help at stat.math.ethz.ch > Subject: [R] Difficulties with R.oo (static fields, etc.) > > > I would like to use R.oo and tcltk to implement a Turtle > World. I have > encountered > many problems because: > > 1) I am not sure how to implement static fields with R.oo > 2) I am not sure how to implement a constructor that would > call a function only for the first instance of a class (i.e., to > initialize > value of static fields only once) > 3) I am not sure how to remove/delete cleanly existing instances. In > particular, > I don't know how to reset tcktk when the last instance > is deleted. > > Here is the sort of behavior I would like to get: > > t1<-TurtleBasic() # a window (the Turtle world) with a > turtle appears > forward(t1,50) # the turtle moves (turtle's state is > also updated) > turn(t1,pi/2) > forward(t1,50) > t2<-TurtleBasic() # a second turtle in the Turtle world appears > turn(t2,pi/2) # second turtle moves > forward(t1,50) > delete(t1) # first turtle disappears > delete(t2) # second turtle and the world disappears > > If possible, I would like to keep this syntax. In fact, I am > using R.oo to create mutable objects so as to avoid syntax > like tu<-forward(tu,10) which would be more typical of a > functional language like R. From the doc/help > files of R.oo, > I believe that one could do it but I don't find many examples > to guide me. > > I pasted my current code with comments below. Thank you for your help. > > Gabriel Baud-Bovy > > #------------------------------------------------------------- > -------------------------------------------------------- > > Description of Turtle Basic Class: > > private fields: > .x, .y, .a (turtle position and heading) > .turtle: ID of canvas item representing turtle > static fields: > .canvas: tcltk canvas widget > .top: tcktk toplevel widget > methods: > TurtleBasic: constructor > plot: display turtle in Turtle World > forward, turn: move turtle > delete: delete turtle (not implemented) > > Note: My current code is very buggy: > - Can't see turtle movements > - Does not define method to delete turtles > - I get an tcltk error when I try to recreate a turtle > world after having > tried to destroy it > (for the moment, I need to detach tcltk to reset it) > > #------------------------------------------------------------- > -------------------------------------------------------- > > library("R.oo") > > setConstructorS3("TurtleBasic",function() { > new<-extend(Object(),"TurtleBasic",.x=100,.y=100,.a=0,.turtle=NA) > ## Create a new Turtle World if necessary > require(tcltk) || stop("tcl/ library not available") > if(!is.tkwin(new$.canvas)) { # check to see if it is first > instance or not > cat("Create Turtle World\n") > top <- tktoplevel() > tktitle(top) <- "Turtle World" > canvas <- tkcanvas(top, relief="raised", width=200, height=200) > tkpack(canvas, side="top", fill="both",expand="1") > new$.canvas<-canvas # store > canvas widget in static field > new$.top<-top > } > plot.TurtleBasic(new) > # plot Turtle > new > }) > > setMethodS3("plot","TurtleBasic",function(turtle) { > ## delete old item (if it exists) > if(is.tkwin(turtle$.canvas) && is.tclObj(turtle$.turtle)) > tkdelete(turtle$.canvas,turtle$.turtle) > ## a new canvas item representing the turtle is created > ## (note: it's necessary to make new item because > turtle's heading can > change) > x <- c(-10,10) > y <- c(-10,10) > aux<- cos(turtle$.a)*x+sin(turtle$.a)*y + turtle$.x > y <- -sin(turtle$.a)*x+cos(turtle$.a)*y + turtle$.y > x <- aux > turtle$.turtle <- tkcreate(turtle$.canvas, "line", > x[1],-y[1],x[2],-y[2],width=1) > }) > > setMethodS3("forward","TurtleBasic",function(turtle,length){ > aux <- turtle$.x + length*cos(turtle$.a) > turtle$.y <- turtle$.y + length*sin(turtle$.a) > turtle$.x <- aux > plot(turtle) > }) > > setMethodS3("turn","TurtleBasic",function(turtle,angle){ > turtle$.a<-turtle$.a+angle > plot(turtle) > }) > > > if(0) { > > t1<-TurtleBasic() # a window (the Turtle world) with a turtle appears > forward(t1,50) > turn(t1,pi/2) > forward(t1,50) > t2<-TurtleBasic() # a second turtle in the Turtle world > turn(t2,pi/2) > > # manually destroy first turtle (would be great to define > some sort of > method for it) > tkdelete(t1$.canvas,t1$.turtle) > rm(t1) > # destroy second turtle and world > tkdelete(t2$.canvas,t2$.turtle) > tkdestroy(t2$.top) > rm(t2) > > } > -------------------------------------------------------------------- > Gabriel Baud-Bovy > Assistant Professor > UHSR University > via Olgettina, 58 tel: (+39) 02 2643 4839 > 20132 Milan, Italy fax: (+39) 02 2643 4892 > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > stat.math.ethz.ch/mailma> n/listinfo/r-help > >