Cool! What i havw always argued for is a global property that turned on or off the behavior that the changing of any var or property generated a message. The message would only happen if a property "sharechanges" of all vars and props (by default false) was set to true. The message would be sent with context and old value parameters.
on rect_changed, context, oldval Storecontexthistory Bla bla bla End rect_changed randall -----Original Message----- From: "Andre Garzia" <[EMAIL PROTECTED]> To: "How to use Revolution" <[email protected]> Sent: 8/29/2008 1:55 AM Subject: One step closer to closures, or, how I captured variables by clever use of context switches. Folks, This is the kind of post you get when I keep code until 5:15 AM. Today I've set a goal to produce a library that would allow me to create persistent variables, by persistent variables I mean that when the program finishes it somehow saves the variable contents and when it loads, it inserts the content back. I know about custom properties, SQL Databases, stack files, that's how we usually solve this kind of issue, but I'd decided to try something different and work with actual variables. To solve this problem, I've decomposed the task into two big components, the saver and the loader. The loader is the piece of code that picks the value and inserts back into the variable, this is trivial, you just read the value from somewhere and insert it back, the tricky thing is the saver. Picking values from global variables is easy, you just declare a global and grab the value. Script local variables are easy to access when you're in the same script. Temporary variables, well, those are tricky to grab when you're not in the same handler as them. So the big task is, how to we access variables that were defined and used in a different context? For those new to transcript let me put a simple example below: on firstHandler local temp put "I am a happy variable" into temp end firstHandler No code outside "firstHandler" can query the value of the temp variable, it is defined in the context of that handler. Now, imagine that you have the following piece: on firstHandler local temp put "I am a happy variable" into temp newPersistentVariable "temp" put "I've just changed the value of temp." into temp secondHandler end firstHandler on secondHandler put captureVariable("temp") end secondHandler And when secondHandler runs, it outputs "I've just changed the value of temp.". If you look carefully at the code above, you'll see that this is not an easy task. We have a strange handler called newPersistentVariable which we don't know what it is and on the secondHandler we have a function that is supposed to return the value from a variable on the other handler. Now, even without the details about those two functions, you can see that we're redefining the content of the temp variable after calling newPersistentVariable, so in a magic way, captureVariable function is returning the last value of temp . How does it works? It works by capturing the context and switching to it when needed. When newPersistentVariable is called it receives a param which is the variable name that you want to keep track (not it's value). newPersistentVariable then checks the executioncontexts and save it for later reference. When we call captureVariable() we pass it a variable name, it then checks to see in which context that variable was defined, it switch there and with a little hack, picks the value from there. The code for both functions is: local lPersistentVariablesA global gVar function captureVariable pVariable put lPersistentVariablesA[pVariable] into tContextsRaw put 0 into tNum repeat for each line tLine in tContextsRaw add 1 to tNum put return & tNum & comma & tLine after tBuf end repeat delete char 1 of tBuf set the cREVScriptDebugMode of stack "revPreferences" to true set the debugcontext to (item 1 of line -2 of tBuf) put format("global gVar; put %s into gVar", pVariable) into tCmd debugdo tCmd set the debugcontext to empty set the cREVScriptDebugMode of stack "revPreferences" to false return gVar end captureVariable on newPersistentVariable pVariable put the executioncontexts into lPersistentVariablesA[pVariable] end newPersistentVariable Now, why this is useful? Well, as you can see from the code, we have an array called lPersistentVariablesA, we could simply loop the keys of that array and capture and save all variables on shutdownRequest. We could modify the newPersistentVariable to check for the saved content and insert it back. Whats wrong with my current code? (A-Ha!) Right now, if you nest to many handlers, the context switch fails somehow... it's hard to debug this. I think that as Rev exits the handlers it drops the contexts (can we call that backtracking?). So if we go from firstHandler into secondHandler into thirdHandler, then in the thirdHandler we can capture variables from them all, but if we go from firstHandler into secondHandler out of secondHandler and into thirdHandler, then anything from secondHandler is lost. Anyway, it still a nice hack and it still useful. I've developed this to use with CGI programming, and in CGIs most things happen in the startup script or very near it, so I can still use these routines to pick variables from contexts that I know are still alive. How to solve this? Well, I don't know, I just wanted to play and try to build myself something that would allow me to freeze the execution contexts in time so that I could re-use them later (still trying to create state out of the stateless nature of cgis, order from chaos...). Andre -- http://www.andregarzia.com All We Do Is Code. _______________________________________________ use-revolution mailing list [email protected] Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-revolution _______________________________________________ use-revolution mailing list [email protected] Please visit this url to subscribe, unsubscribe and manage your subscription preferences: http://lists.runrev.com/mailman/listinfo/use-revolution
