Thanks very much for those links, Mark. Based on them I got it to work. One key realization that my while loop was unnecessary since shiny is continually running and checking things. So I changed it into an if statement.
In my renderPlot function I just had the code to do the plot. No computations there.
Then all the computations and updating were in an observe({isolate({ block, and I updated the values of components of a reactiveValues data structure.
I'm not sure yet how to get it not to reset the plot when it is done.
shinyUI<-(
fluidPage(
# Application title
titlePanel("Simulating Infection"),
# Sidebar with a slider input for proportion vaccinated
sidebarLayout(
sidebarPanel(
sliderInput("size",
"Grid size",
min = 4,
max = 151,
value = 4,
animate=F,
step=5),
actionButton("goButton", "Go!"),
actionButton("reset","Stop/Reset")
),
# Show a plot of the grid
mainPanel(
plotOutput("gridPlot"))
)
)
)
########################################################
shserver<-(function(input,output,session){
gr<-reactiveValues(ifield=array(0,dim=c(2,2)),counter=1,resetHelper=0)#just to initialize ifield to some array
output$gridPlot<-renderPlot({
image(gr$ifield)
})
observe({
if(gr$resetHelper==0){
return(NULL)
}
isolate({
if (gr$counter==1){ #initialization code
gr$ifield=array(data=0,dim=c(input$size,input$size))
gr$ifield[gr$counter]=1
}
if (gr$counter>1){
gr$ifield[gr$counter]=1
}
gr$counter=gr$counter+1
})
if (((isolate(gr$resetHelper==1 & gr$counter<=input$size*input$size))))
invalidateLater(200,session)
})
observe({
if(input$goButton>0){
gr$resetHelper<<-1
}
})
observe({
if (input$reset>0){
gr$counter <<- 1
gr$resetHelper<<-0
}
})
observe({
if (input$size>0){
gr$resetHelper<<-0
}
})
})
##############
runApp(list(ui=shinyUI,server=shserver))