Page 1 of 1

Using search to find coding about ticking seconds

Posted: Mon Sep 21, 2009 12:59 am
by urbaud
I have a small program that displays the time. However, it doesn't show the seconds ticking away, which I would like it to do. I obviously don't know how to use the search function on this forum because I never get anything close to what I type in as a key word. I've been "searching" the forum to find code that will show me how to display the seconds ticking in a clock-no luck.
This is what I have so far:
on OpenCard
put the long time into fld "t1"
end OpenCard
Can anyone show me the code to get the seconds to tick in my clock?

Posted: Mon Sep 21, 2009 6:10 am
by Janschenkel
Try this - it starts a timer that will trigger a call to DisplayTime every second:

Code: Select all

on openCard
  DisplayTime
end openCard

on DisplayTime
  put the long time into field "t1"
  send "DisplayTime" to me in 1 second
end DIsplayTime
HTH,

Jan Schenkel.

Posted: Mon Sep 21, 2009 7:04 am
by urbaud
Jan,

Thanks for the code. It works just fine. Just one question, though. I put the 'put...' and 'send...' lines in the onOpenCard handler, without using the onDisplayTime handler and it didn't work. Is the onDisplayTime handler considered a function in this instance? Can you explain what is happening with the -send "DisplayTime" to me in 1 second-line. Does the 'send...' line send the 1 second to the put command or to the 'long time' statement? I'm confused as to how this works. Any help would be appreciated.

Posted: Mon Sep 21, 2009 8:16 am
by malte
Hi urbaud,

this might be a bit long, so excuses beforehand.

rev is an event driven programming language.

There are different types of events.
User events (input events) like moving the mouse, clicking a button or typing text into a field.There are also automatic events like opening a stack or opening a card.

Everytime an event happens it triggers a message that informs the engine that something has happened. These messages travel along themessage path from the object that receives the message first down to the engine.

You can react upon messages being sent by writing handlers for these messages.

Each message handler begins with the keyword on followed by the name of the message that this handler responds to. The handler ends with the keyword end and the name of the message. The simplest handler you can write looks like this:

Code: Select all

  on mouseUp
    beep
  end mouseUp
This script will play a system sound if the user clicks on the control that contains the script.

A message handler is executed when the object whose script contains the handler receives the message that needs to be handled.

You can write handlers for any built-in message. You can also write a handler for your own custom message, and send the message to an object either by using the send command or by using the name of the message as a command.

Assume the following handler is stored in a button called "myButton":

on sausage
beep
end sausage

You can call it by using send sausage to button "myButton" from anyWhere in your stack, as long as the card the button is on is on top. If you want to call the sausage script from the button itself e.G. in a mouseUp handler you could also use:

in the script of button "myButton"

on mouseUp
sausage
end mouseUp

However, it is a good idea to write custom handlers that have a better name than sausage. ;-) Otherwise you will have a hard time to remember what the script you wrote a few weeks ago does.

Function handlers
Each function handler begins with the function keyword followed by the name of the function. The handler ends with the end keyword and the name of the function. A function handler might look like this:

Code: Select all

  function thisYear
    return item 3 of the long date
  end thisYear
A function handler is executed when a handler in the same script (or higher in the message path) calls the function. This example handler returns the current year.

getProp handlers
Each getProp handler begins with the getProp keyword followed by the name of the custom property that this handler is related to. The handler ends with the end keyword and the name of the property. getProp handlers look like this:

Code: Select all

  getProp myAspectRatio
    return the width of me/the height of me
  end myAspectRatio
A getProp handler is executed whenever the value of the related custom property is requested by a Transcript statement.

You can write a getProp handler for any custom property of the object or another object that's up higher in the message path.

setProp handlers
Each setProp handler begins with the setProp keyword followed by the name of the custom property that the handler relates to. The handler ends with the end keyword and the name of the property. setProp handlers look like this:

Code: Select all

  setProp myColor newSetting
    set the backColor of me to newSetting
    set the frontColor of me to newSetting
    pass setProp
  end myColor
A setProp handler is executed whenever the value of the corresponding custom property is changed by the set command.

You can write a setProp handler for any custom property of the object or another that's higher in the message path.

Now getting to timers. (still there? <g>)

A timer script is just a handler that calls itself after you trigger it once. You could write a handler that beeps every three seconds.

In the script of a button:

Code: Select all

on mouseUp
  annoyingBeepRepeat
end mouseUp

on annoyingBeepRepeat
  beep
  send annoyingBeepRepeat to me in 3 seconds
end annoyingBeepRepeat
Once you click the button your computer will start beeping at you. don't considder it to be rude as he doesn't know any better. You won't be able to stop the computer from beeping but clicking onto the "lock messages" button in the menubar or by typing "lock messages" into the messageBox. You will need to unlock messages afterwards. Of course this is not desired behaviour. If you start a timer you want to be able to stop it. This script will do the trick:

Code: Select all

on mouseUp
  if the flag of me is empty then set the flag of me to false
  set the flag of me to not the flag of me
  annoyingBeepRepeat
end mouseUp

on annoyingBeepRepeat
  beep
  if the flag of me then
    send annoyingBeepRepeat to me in 3 seconds
  end if
end annoyingBeepRepeat
The additional lines of code add a custom property to your button. This property is alternating between true and false everytime you click the button. The additional if control structure in the annoyingBeepRepeat handler checks if the flag of your button is true and only sends the next message if you haven't clicked the button a second time.

There is one problem remaining when you use timers. If you switch to another card or close the stack the message still gets fired and might throw an error as your button is not on the newly opened card or rev needs to stop sending the message while closing the stack. You will need to stop sending the message and cancel the remaining messages that are qued in the pendingMessages before you leave a card. looking at the annoyingBeepRepeat example you would do it this way:

In the script of your card:

Code: Select all

on closecard
  set the flag of btn "myButton" to false
  repeat for each line theMessage in the pendingMessages
    if "annoyingBeepRepeat" is in theMessage then
      cancel item 1 of theMessage
    end if
  end repeat
end closeCard
Using this script will allow your users to leave the card without errors.

Cheers,

Malte