Page 1 of 1

Launching a cel script from a celx script

Posted: 29.10.2007, 11:06
by Vincent
As discussed by Andrea in the following thread, launching a Cel script from a Celx script is not possible yet: http://celestiaproject.net/forum/viewtopic.php?t=11607&start=8

Of course, one can already include Cel commands into a celx script. However, with the new possibilities to set the line and label colors, or to map functions to specific keys via celx scripting, I think that it could be useful and above all handier to have the ability to run one or several celx scripts in a row before launching a start.cel script.

I've already implemented a celestia:runscript command in one of my Celestia builds. Adding this command at the end of a celx script allows launching whatever celx or cel script once the original celx script is done.

Here's a concrete example:

Code: Select all

-- Title: Alternate color palette

celestia:setlabelcolor("stars",            0.500, 0.500, 1.000)
celestia:setlabelcolor("planets",          0.150, 0.740, 1.000)
celestia:setlabelcolor("moons",            0.450, 0.576, 0.612)
celestia:setlabelcolor("asteroids",        0.460, 0.440, 0.360)
celestia:setlabelcolor("comets",           0.840, 0.620, 0.280)
celestia:setlabelcolor("spacecraft",       0.750, 0.740, 0.670)
celestia:setlabelcolor("locations",        0.220, 0.940, 0.440)
celestia:setlabelcolor("galaxies",         0.190, 0.850, 0.710)
celestia:setlabelcolor("nebulae",          0.850, 0.350, 0.290)
celestia:setlabelcolor("openclusters",     0.620, 0.480, 0.540)
celestia:setlabelcolor("constellations",   0.385, 0.280, 0.567)
celestia:setlabelcolor("equatorialgrid",   0.318, 0.439, 0.361)

celestia:setlinecolor ("starorbits",       0.500, 0.500, 0.800)
celestia:setlinecolor ("planetorbits",     0.000, 0.360, 0.900)
celestia:setlinecolor ("moonorbits",       0.220, 0.330, 0.400)
celestia:setlinecolor ("asteroidorbits",   0.280, 0.240, 0.216)
celestia:setlinecolor ("cometorbits",      0.520, 0.320, 0.128)
celestia:setlinecolor ("spacecraftorbits", 0.360, 0.360, 0.360)
celestia:setlinecolor ("constellations",   0.234, 0.090, 0.576)
celestia:setlinecolor ("boundaries",       0.192, 0.079, 0.151)
celestia:setlinecolor ("equatorialgrid",   0.192, 0.248, 0.184)

---------------------------------
runscript("start.cel")
---------------------------------


Would you find such a feature useful ?

Re: Launching a cel script from a celx script

Posted: 29.10.2007, 11:08
by ANDREA
Vincent wrote:I've already implemented a celestia:runscript command in my own Celestia code. Placing this command at the end of a celx script allows to launch whatever celx or cel script once the original celx script is done. Would you find such a feature useful ?

Yes, please, Vincent, very appreciated. :wink:
Bye

Andrea :D

Posted: 29.10.2007, 11:08
by ElChristou
So this way you can do a "chain" of scripts?
That seems to be interesting...

Posted: 29.10.2007, 11:15
by Vincent
ElChristou wrote:So this way you can do a "chain" of scripts?
That seems to be interesting...

Actually, this is already possible via the loadfile Lua command, but only for celx (-> Lua) scripts. However, I've noticed that some scripts don't work as expected... Moreover, I find it quite useful and handy to run several specific celx scripts in a row before launching a start.cel script, rather than copying all the stuff in a single script...

Re:

Posted: 08.02.2010, 16:51
by Cham
Vincent wrote:
ElChristou wrote:So this way you can do a "chain" of scripts?
That seems to be interesting...
Actually, this is already possible via the loadfile Lua command, but only for celx (-> Lua) scripts. However, I've noticed that some scripts don't work as expected... Moreover, I find it quite useful and handy to run several specific celx scripts in a row before launching a start.cel script, rather than copying all the stuff in a single script...

I'm trying to use that function in a LUA module, but currently it isn't working. What is wrong here in the following code ?

Code: Select all

button_5.Action = (function()
        return
            function()
                if not script_1 then
                    script_1 = true;
                    --celestia:dofile("../scripts/Magnetisme-Champs.celx");
                    celestia:loadfile("../scripts/Magnetisme-Champs.celx");
                    --celestia:print(" Message d'activation 5", 3);
                elseif script_1 then
                    script_1 = false;
                    celestia:print(" Message de d?sactivation 5", 3);
                end
            end
        end) ();


I also tried this function :

Code: Select all

local dofile = function(filename)
    script = assert(loadfile( filename ), "unable to load " ..filename);
    return script
end


I'm simply trying to execute a CELX script file from within a LUA (i.e. CELX) module...

Re: Re:

Posted: 10.02.2010, 12:11
by Vincent
Cham wrote:I'm trying to use that function in a LUA module, but currently it isn't working. What is wrong here in the following code ?
Martin,

First of all, all these issues we're having when trying to launch a script from within another
with the dofile() or loadfile() Lua functions will be eventually fixed in Celestia 1.6.1 using
the celestia:runscript method.

Then, the following reasons could explain the fact that your script above is not working:
1- The loadfile() function only compiles the chunk of Lua code but does not run it, and thus,
one has to write:

Code: Select all

runscript = loadfile(filepath)
runscript()

I'd suggest to use the dofile() function instead, which is more straightforward:

Code: Select all

dofile(filepath)


2- Lua uses the celestia base directory to look for files.
As a workaround, I've written my own function that returns the path of the Lua directory
from which I run my Lua scripts.

Code: Select all

local getLuaDirPath =
    function(dir)
        local pathes = package.path;
        local c0, c1 = string.find(pathes, dir);
        local path1 = string.sub(pathes, 1, c1);
        local revpath1 = string.reverse(path1);
        local c2 = string.find(revpath1, ";");
        local revpath2 = string.sub(revpath1, 1, c2 - 1);
        local path = string.reverse(revpath2);
        return path;
    end

Then you can run your script using:

Code: Select all

local scriptpath = getLuaDirPath(myLuaDir).."/"..myLuaScript;
celestia:runscript(scriptpath);


3- As we discussed recently (see: viewtopic.php?f=9&t=15718&start=12 ),
your celx script shouldn't contain any wait() or createcelscript command.

Re: Launching a cel script from a celx script

Posted: 10.02.2010, 13:12
by Cham
Vincent,

the dofile() command is now working. Thanks a lot ! :D

Now, what will be the difference between the dofile() and the new celestia:runscript() command ?

Re: Launching a cel script from a celx script

Posted: 10.02.2010, 16:04
by Vincent
Cham wrote:the dofile() command is now working. Thanks a lot ! :D
Good, you're welcome!


Cham wrote:Now, what will be the difference between the dofile() and the new celestia:runscript() command ?
The Lua dofile() function runs the content of the script to launch as a Lua chunk that is not
recognized by the celestia core as a standard celestia script. And thus, special commands like
wait() or celscript:tick() are simply ignored. This can be quite annoying since the wait()
command is pretty frequently used.

The celestia:runscript() method will fix that.

Re: Re:

Posted: 17.02.2010, 21:11
by Marco Klunder
Vincent wrote:Lua uses the celestia base directory to look for files.
As a workaround, I've written my own function that returns the path of the Lua directory
from which I run my Lua scripts.

Code: Select all

local getLuaDirPath =
    function(dir)
        local pathes = package.path;
        local c0, c1 = string.find(pathes, dir);
        local path1 = string.sub(pathes, 1, c1);
        local revpath1 = string.reverse(path1);
        local c2 = string.find(revpath1, ";");
        local revpath2 = string.sub(revpath1, 1, c2 - 1);
        local path = string.reverse(revpath2);
        return path;
    end

Then you can run your script using:

Code: Select all

local scriptpath = getLuaDirPath(myLuaDir).."/"..myLuaScript;
celestia:runscript(scriptpath);

Vincent,

Is this all the available information on this new 161 celestia method?
Do you probably have some aditional info, so we can update the celx wiki page on this new method as accurate as possible?

e.g.
may scriptpath in your example also be a string relative to the base directory or may it even be in the root as you wish?
Are there probably more parameters not mentioned in the above example?
...

Marco

Re: Launching a cel script from a celx script

Posted: 19.02.2010, 10:25
by Vincent
The celestia:runscript method is in SVN now.

Marco Klunder wrote:Is this all the available information on this new 161 celestia method?
Do you probably have some aditional info, so we can update the celx wiki page on this new method as accurate as possible?
Marco,

Thanks for your help on keeping the Lua/Celx wiki page up-to-date.

So far, the script absolute path is required, but we still have time to make celestia:runscript
use a path relative to the main celx/lua script, instead. We just need to agree on this...

Now if we stick with using an absolute path, the script to launch will be still located in the same
directory as the main script -- or in a sub directory. Thus, some precision might be needed
about how to get the path of the main script. The process is different in a CELX script
than in a LUA script.

- Getting the path of a CELX script

Code: Select all

scriptpath = celestia:getscriptpath().."/../"

Then, we can launch our celx script using:

Code: Select all

scriptfilename = "myCelxScript.celx"
celestia:runscript(scriptpath..scriptfilename)
wait(0)

Note that in a celx script, the celestia:runscript method should be always followed by
a wait(0) command.


- Getting the path of a LUA script
Lua uses the celestia base directory to look for files, and thus we can't use the celestia:getscriptpath()
command here since it will return the path of the celestia base directory (= package.path variable).
So we need to write our own function to get the main Lua script path :

Code: Select all

local getLuaDirPath =
    function(dirName)
        local pathes = package.path
        local c0, c1 = string.find(pathes, dirName)
        local path1 = string.sub(pathes, 1, c1)
        local revpath1 = string.reverse(path1)
        local c2 = string.find(revpath1, ";")
        local revpath2 = string.sub(revpath1, 1, c2 - 1)
        local path = string.reverse(revpath2)
        return path
    end

Then, we can launch our celx script using:

Code: Select all

local scriptpath = getLuaDirPath(myLuaDir).."/"
local scriptfilename = "myCelxScript.celx"
celestia:runscript(scriptpath..scriptfilename)

Re: Launching a cel script from a celx script

Posted: 19.02.2010, 19:25
by Marco Klunder
Vincent, thanks for this update

Vincent wrote:So far, the script absolute path is required, but we still have time to make celestia:runscript
use a path relative to the main celx/lua script, instead. We just need to agree on this...

I don't want to interfere with the development, but probably a 2nd parameter in the runscript method can be used to determine wether the scriptpath is absolute or relative ... :idea:

Marco

Re: Launching a cel script from a celx script

Posted: 22.02.2010, 13:19
by Vincent
Marco Klunder wrote:I don't want to interfere with the development, but probably a 2nd parameter in the runscript method can be used to determine wether the scriptpath is absolute or relative ... :idea:
I just commited a fix that makes celestia:runscript use relative file pathes only.
I don't see any case where an absolute path should be prefered over a relative one.
That will make things much simpler: no more need to get the main script path and
no more difference between Lua and Celx scripts. Moreover, this is more consistent
with other methods like celestia:loadtexture which also use relative file pathes.

Here's an example where the main script and the script to launch are located in
the same dir:

Code: Select all

celestia:runscript("myScriptToLaunch.celx")
wait(0)


Notes:
- Even on Windows, use slashes "/" in the script path (when the script to launch is located in a different dir):

Code: Select all

celestia:runscript("../myDir2/myScriptToLaunch.celx")
wait(0)

- The main script will be terminated as soon as the second script is launched.
That means that all extra lines of codes below the celestia:runscript command
will be ignored.

Re: Launching a cel script from a celx script

Posted: 02.03.2010, 16:11
by duds26
Very nice enhancements.
Could it be possible to make a division between loading and executing a script?
It can avoid some overhead on the moments it matters.
It would be handy to load a script at the background while one is still playing.

You're doing great work here. Please don't stop, but keep going :D

Re: Launching a cel script from a celx script

Posted: 03.03.2010, 09:01
by Vincent
duds26 wrote:Could it be possible to make a division between loading and executing a script?
It can avoid some overhead on the moments it matters.
It would be handy to load a script at the background while one is still playing.

There's no built in method in Celestia core that loads a script without running it.
So I'd suggest to use the Lua loadfile function which compiles the chunk of Lua code before
running it:

Code: Select all

 -- First load and compile myscriptfilename as a chunk of Lua code...
runscript = loadfile(myscriptfilename)

--
-- insert your script commands here...
--

-- ... And now run the script
runscript()


As precised all along this thread, the wait() command can't be used in a chunk of Lua code, though...