Standalone calendar with standalone alarms

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
trevix
Posts: 1085
Joined: Sat Feb 24, 2007 11:25 pm
Contact:

Standalone calendar with standalone alarms

Post by trevix » Thu Mar 05, 2009 12:57 pm

I'm trying to build a calendar application that has an alarm application that sits in the background, even when the calendar is not launched.
The two should obviously communicate and be able to launch one another.

I've been doing it using socket communication but the handshaking protocol is growing too much complex...and if you add the problem of firewall permissions on the "new user" installation, it looks to me that this is not the way to go.

I could use a shared text file to enable communication between the two, but the continous polling is not probably a good idea.

Is any other way to do it ?
I think an environment variable could do it but, for what I know, the $0 is shared only if the process is started from one of the two applications, so, if alarms is launched in the background and the user start the calendar from the desktop, this would not work.

Any comments ?

Trevix

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Thu Mar 05, 2009 1:46 pm

Hi Trevix,

The calendar application can launch the alarm application using a shell function with command line parameters. Check out the relaunch message. This should be sufficient to update the alarm application when needed.

Best,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

trevix
Posts: 1085
Joined: Sat Feb 24, 2007 11:25 pm
Contact:

Post by trevix » Thu Mar 05, 2009 2:23 pm

I'm already doing that...but taking control of all the options, as I said, generated (in my opinion) too many lines of code in order to handle:

- wait in the calendar startup script till the server (alarm) open the connection
- may be the port is used by other application so we need to restart the process with different port
- the firewall could block the alarm so we need to wait till the user allows the alarm to open the socket
- the calendar is launched but, for some reason, the alarm is not so we need to restart alarm and reconnect the calendar
- the alarm is launched but the calendar is not. I need to start the calendar and handle the wait time till the connection is done. Then may be the user has moved the calendar app
- The calendar is made for Windows and Mac so there are all the Applescript and relaunch/shell/vbscript "if..then"
- ...etc.etc

These are only examples and I've already done all this; but it generated tons of rootines and loops. So what I am asking is: is there another simpler way to do it without socket communication ? Or should I just accept my poor knowledge of handshaking protocols ?

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Thu Mar 05, 2009 2:43 pm

Hi Trevix,

You are not already doing that. You are using sockets, I say use the shell.

Best,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

SparkOut
Posts: 2949
Joined: Sun Sep 23, 2007 4:58 pm

Post by SparkOut » Thu Mar 05, 2009 3:37 pm

I'm not clear what information you are passing between the applications in socket communications. It seems to me that (as Mark suggests) sockets are not necessary at all (if the data exchange is not huge for each update).

If you just trigger the application to start with the shell, and put the data you want to transfer from one stack to another into an argument to be passed, then you can use the startup and relaunch handlers to react to the arguments.

If the "other" application is not already open, then the on startup handler will have the (first) argument passed as $1.

If the "other application is already open, then the on relaunch handler will have the argument attached like any other handler.

I have loaded two stacks AlarmStack.rev and CalendarStack.rev in my RevOnline space which show the principle in action on Windows. I'm not familiar with Mac, but it will work in the same sort of way, I'm sure.

If you compile the two stacks as standalones and put them into the same folder (because I told each one to look for the other in the same place) then whether or not one stack or the other is open, you will see the data being passed from one to the other. If the destination stack is not open then on startup will react to the $1 argument, and if the destination stack is already open then the on relaunch pParam will deal with it. (If you close one standalone stack, then of course the data will be forgotten, but you would naturally have your own handling of the data so that updates will be saved.)

trevix
Posts: 1085
Joined: Sat Feb 24, 2007 11:25 pm
Contact:

Post by trevix » Thu Mar 05, 2009 4:31 pm

mmmmh...lots of info to think about. Thanks
On the docs, the relaunch is mentioned to work on Windows only (I used to handle the launch from the doc, to avoid to instances...On MacOS there is not this problem)
I will look into your two stacks and see what I can do.
Thanks again

Trevix

Mark
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 5150
Joined: Thu Feb 23, 2006 9:24 pm
Contact:

Post by Mark » Thu Mar 05, 2009 4:46 pm

Hi Trevix,

True, the relaunch message doesn't work on Mac OS X. On the Mac, you might use AppeScript:

Code: Select all

tell application "Standalone" to do script "someCommand param1,param2"
Here's another AppleScript example:

Code: Select all

tell application "Revolution" to do script "create stack \"New Stack\""
Just an idea.

Best,

Mark
The biggest LiveCode group on Facebook: https://www.facebook.com/groups/livecode.developers
The book "Programming LiveCode for the Real Beginner"! Get it here! http://tinyurl.com/book-livecode

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10057
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Post by FourthWorld » Thu Mar 05, 2009 6:34 pm

To confuse matters even more, there's yet another option: polling for a file.

One app checks for a file in a given location such as in the temp directory, access in Rev with specialFolderPath("temporary"), and the other write any data it needs to pass to that file. When the "listener" app finds that the file exists, it grabs the data and does whatever it needs to with it.

Given that directory accesses are usually cached by most OSes it isn't so resource-consuming as it sounds, esp. if the polling is infrequent.

If the "listener" app isn't running all the time, you could also just launch it as needed with the path to the data file using the "launch" command. This would also allow you to pass any amount of data to it without needing to use any direct inter-app communications at all, and simple to do on all platforms.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

trevix
Posts: 1085
Joined: Sat Feb 24, 2007 11:25 pm
Contact:

Post by trevix » Thu Mar 05, 2009 8:37 pm

I've integrated the two stack of SparkOut with applescript, for the Mac part, and everything seems to work (I have posted the new stacks as "CalendarStack2" and "AlarmStack2")

It is not ....fast fast.. but it works and solved with few lines my problem (sending also long text)
The only thing I do not understand is that, if i send 2 or more lines of text (text with the return char on it):
- On Windows it gets received only the first line
- On Mac you get all the text without return

Should replace the return on the text with (line feed?) before sending ?

About FourthWorld remark I can say that it would bnice not to have disk access... with some kind of computer memory space available for any application to check, no matter how it was launched. Not possible ?

SparkOut
Posts: 2949
Joined: Sun Sep 23, 2007 4:58 pm

Post by SparkOut » Thu Mar 05, 2009 10:52 pm

Hi Trevix,
With the returns in the data it depends on how you need to handle it what you do.
The simple way would be to replace cr with the literal "~cr~" or another pattern that's reserved, transfer the single parameter and then replace "~cr~" with cr when you've received the data in the target stack.
Alternatively you can wrap each line in quotes and pass them as multiple parameters in your shell string.

The relaunch handler will have the paramCount populated, and you can iterate through them all as

Code: Select all

on relaunch
--no need to specify the parameter name assigned
   put empty into field "fldAlarmData"
   repeat with i = 1 to the paramCount
      put param (i) & cr after field "fldAlarmData"
   end repeat
end relaunch
the startup handler doesn't work quite that way, as the command line argument $ keyword doesn't populate the paramCount. On Windows, as long as each argument is wrapped in quotes then each new argument is assigned to $1,$2,$3, etc. ($0 is the application name, by the way). You can fudge a little routine to iterate through the arguments passed this way

Code: Select all

on startUp
   put "null" into tParam
   put 1 into tIndex
   repeat until (tParam is empty) or (tIndex > 20) --or your sensible max limit on number of lines of data
      do "put $" & tIndex && "into tParam"
      put tParam & cr after field "fldAlarmData"
      add 1 to tIndex
   end repeat
end startUp
Obviously you can do a bit more tidying up, and just putting the lines into the field that way is not worth the effort, rather than just replacing the cr before and after, but this way you can see how to pass multiple lines of disparate data to do with as you need.

Post Reply