PDA

View Full Version : Self-updating Custom Attributes


JHaywood
06-20-2008, 12:19 AM
What's the best way to create a self-updating CA? I want to add one to a scene so that when it's opened stuff happens. But I want it to be updatable so that if the file containing the CA is changed, it will get updated on file load.

So let's say file, "testCA.ms" contains the following, and that this CA is applied to the rootNode of a scene.

ca = attributes testCA
(
on load do
(
fileIn "testCA.ms"
print "doing something"
)
)


So now whenever I open the file it prints "doing something" in the listener. That's all good. But now I want to change the "testCA.ms" file to this...

ca = attributes testCA
(
on load do
(
fileIn "testCA.ms"
print "doing something else"
)
)


I save the CA file and reload the scene. It still prints "doing something" on open, but now the CA on the rootNode has been updated. If I then save the file and open it again it now prints "doing something else" as it should because of the updated CA.

The problem is that I want the CA to not only update on file open, but execute the updated version and not the have to wait until the file is save and reloaded to use the new definition.

PEN
06-20-2008, 11:43 AM
I have done this by using postFileLoad callbacks. Search the scene for the CAdef that you want to update and change it's definition. Make note that all instances will be changed.

JHaywood
06-20-2008, 09:30 PM
I don't have any trouble changing the definition using the fileIn method. The trouble is that the code inside the "on load" event handler of the old definition still gets executed until you save the file and then load it again, at which point the definition executes as expected.

So here's the hacky way I've set it to do exactly that, but there must be a more elegant solution...

testCA = attributes test attribID:#(0x42869098, 0x26160ba5)
(
local isUpdated = false

on load do
(
-- update the CA by executing this file
fileIn @"c:\testCA.ms"

-- put all commands to be executed on file open here
-- if the CA has not been updated, do this stuff...
if not isUpdated then
(
print "doing stuff"
)
-- if the CA has been updated, save the file then load it again to execute the new updated code
else
(
cbkString = stringStream ""
format "messagebox \"This file is out of date and needs to been updated.\nIt will now be updated, saved and then loaded again.\" title:\"File Aggregator\"\n" file to:cbkString
format "saveMaxFile (maxFilePath + maxFileName)\n" file to:cbkString
format "loadMaxFile (maxFilePath + maxFileName)\n" file to:cbkString
format "saveMaxFile (maxFilePath + maxFileName)\n" file to:cbkString
callbacks.removeScripts id:#test_CBK
callbacks.addScript #filePostOpen cbkString id:#test_CBK
)
)

on update do
(
-- change the isUpdated parameter to indicate that the CA has changed and has been updated
isUpdated = true
)

on deleted do
(
callbacks.removeScripts id:#test_CBK
)
)

magicm
06-20-2008, 10:59 PM
Placing your code in a separate function instead of the load handler itself should do the trick:

testCA = attributes test attribID:#(0x42869098, 0x26160ba5)
(
fn DoStuff =
(
format "Hello World!\n"
)

on postLoad do
(
fileIn @"c:\testCA.ms"
DoStuff()
)
)
Cheers,
Martijn

JHaywood
06-20-2008, 11:36 PM
Brilliant!

CGTalk Moderation
06-20-2008, 11:36 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.