21
21
#include <iostream>
23
22
#include <dirent.h>
26
28
#include "script_mgr.h"
30
#include "stel_command_interface.h"
31
#include "StelApp.hpp"
32
#include "StelFileMgr.hpp"
33
#include "InitParser.hpp"
29
35
using namespace std;
32
ScriptMgr::ScriptMgr(StelCommandInterface *command_interface, string _data_dir) : play_paused(false) {
33
commander = command_interface;
37
record_elapsed_time = 0;
39
// used when scripts are on a CD that needs to be mounted manually
40
RemoveableScriptDirectory = "";
41
RemoveableDirectoryMounted = 0;
37
ScriptMgr::ScriptMgr(StelCommandInterface *command_interface) : play_paused(false) {
38
setObjectName("ScriptMgr");
39
commander = command_interface;
42
record_elapsed_time = 0;
43
scripts_can_write_files = false;
44
// used when scripts are on a CD that needs to be mounted manually
45
RemoveableScriptDirectory = "";
46
RemoveableDirectoryMounted = 0;
44
50
ScriptMgr::~ScriptMgr() {
53
void ScriptMgr::init(const InitParser& conf)
55
set_allow_ui( conf.get_boolean("scripts","flag_script_allow_ui",0) );
56
scripts_can_write_files = conf.get_boolean("scripts","scripting_allow_write_files", false);
47
59
// path is used for loading script assets
48
bool ScriptMgr::play_script(string script_file, string script_path) {
52
// cancel current script and start next (one script can call another)
56
set_gui_debug(0); // Default off until script sets otherwise
58
//if (script) delete script;
59
script = new Script();
61
// if script is on mountable disk, mount that now
62
if( RemoveableScriptDirectory != "" &&
63
script_file.compare(0,RemoveableScriptDirectory.length(), RemoveableScriptDirectory) ==0) {
64
system( ( DataDir + "script_mount_script_disk " ).c_str() );
65
cout << "MOUNT DISK to read script\n";
67
RemoveableDirectoryMounted = 1;
70
if( script->load(script_file, script_path) ) {
73
elapsed_time = wait_time = 0;
60
bool ScriptMgr::play_script(const QString& script_file, const QString& script_path) {
64
// cancel current script and start next (one script can call another)
68
set_gui_debug(0); // Default off until script sets otherwise
70
//if (script) delete script;
71
script = new Script();
73
// if script is on mountable disk, mount that now
74
if( RemoveableScriptDirectory != "" && script_file.startsWith(RemoveableScriptDirectory))
78
system(QFile::encodeName(StelApp::getInstance().getFileMgr().findFile("data/script_mount_script_disk")).constData());
79
cout << "MOUNT DISK to read script" << endl;
80
RemoveableDirectoryMounted = 1;
84
cerr << "ERROR while trying to mount removable media: " << e.what() << endl;
88
if( script->load(script_file, script_path) ) {
91
elapsed_time = wait_time = 0;
83
100
void ScriptMgr::cancel_script() {
91
108
if(RemoveableDirectoryMounted) {
92
system( ( DataDir + "script_unmount_script_disk " ).c_str() );
93
cout << "UNMOUNT DISK\n";
94
RemoveableDirectoryMounted = 0;
111
system(QFile::encodeName(StelApp::getInstance().getFileMgr().findFile("data/script_unmount_script_disk")).constData());
112
cout << "UNMOUNT DISK" << endl;
113
RemoveableDirectoryMounted = 0;
117
cerr << "ERROR while trying to unmount removable media: " << e.what() << endl;
99
123
void ScriptMgr::pause_script() {
101
// need to pause time as well
102
commander->execute_command("timerate action pause");
125
// need to pause time as well
126
commander->execute_command("timerate action pause");
105
129
void ScriptMgr::resume_script() {
120
if(script_filename != "") {
121
rec_file.open(script_filename.c_str(), fstream::out);
125
#if defined(WIN32) || defined(CYGWIN) || defined(__MINGW32__)
126
if(getenv("USERPROFILE")!=NULL){
128
sdir = string(getenv("USERPROFILE")) + "\\My Documents\\";
131
sdir = "C:\\My Documents\\";
134
sdir = string(getenv("HOME")) + "/";
140
// add a number to be unique
143
for(int j=0; j<=100; ++j)
144
// If we get no script filename as a parameter we should make a new one.
145
if(script_filename == "") {
146
QString scriptSaveDir;
149
// this probably wont work with non-ascii username. handle this in StelFileMgr? nkerr
150
scriptSaveDir = StelApp::getInstance().getFileMgr().getUserDir() + "/scripts";
151
if (!StelApp::getInstance().getFileMgr().exists(scriptSaveDir))
145
snprintf(c,3,"%d",j);
147
script_filename = sdir + "stellarium" + c + ".sts";
148
fp = fopen(script_filename.c_str(), "r");
153
if (!StelApp::getInstance().getFileMgr().mkDir(scriptSaveDir))
155
throw(runtime_error("couldn't create it"));
155
rec_file.open(script_filename.c_str(), fstream::out);
161
cerr << "ERROR ScriptMgr::record_script: could not determine script save directory (" << e.what() << ") NOT RECORDING" << endl;
166
for(int j=0; j<1000; ++j)
169
oss << setfill('0') << setw(3) << j;
170
scriptPath = scriptSaveDir +"/"+ "recorded-" + oss.str().c_str() + ".sts";
171
if (!StelApp::getInstance().getFileMgr().exists(scriptPath))
174
// catch the case where we we have all 999 scripts existing...
175
if (StelApp::getInstance().getFileMgr().exists(scriptPath))
177
cerr << "ERROR ScriptMgr::record_script: could not make a new scipt filename, NOT RECORDING" << endl;
182
script_filename = QFile::encodeName(scriptPath).constData();
186
// Open the file for writing.
187
rec_file.open(script_filename.c_str(), fstream::out);
160
189
if(rec_file.is_open()) {
197
226
// runs maximum of one command per update
198
227
// note that waits can drift by up to 1/fps seconds
199
void ScriptMgr::update(int delta_time) {
201
if(recording) record_elapsed_time += delta_time;
203
if(playing && !play_paused) {
205
elapsed_time += delta_time; // time elapsed since last command (should have been) executed
207
if(elapsed_time >= wait_time) {
208
// now time to run next command
211
// cout << "dt " << delta_time << " et: " << elapsed_time << endl;
212
elapsed_time -= wait_time;
214
unsigned long int wait;
215
if(script->next_command(comd)) {
216
commander->execute_command(comd, wait, 0); // untrusted commands
221
cout << "Script completed." << endl;
222
commander->execute_command("script action end");
228
void ScriptMgr::update(double delta_time)
230
if(recording) record_elapsed_time += (unsigned long int)(delta_time * 1000);
232
if(playing && !play_paused)
234
// time elapsed since last command (should have been) executed
235
elapsed_time += (unsigned long int)(delta_time * 1000);
237
if(elapsed_time >= wait_time)
239
// now time to run next command
240
elapsed_time -= wait_time;
242
unsigned long int wait;
243
if(script->next_command(comd))
245
commander->execute_command(comd, wait, 0); // untrusted commands
250
cout << "Script completed." << endl;
251
commander->execute_command("script action end");
229
// get a list of script files from directory
230
string ScriptMgr::get_script_list(string directory) {
232
// TODO: This is POSIX specific
234
struct dirent *entryp;
239
// if directory is on mountable disk, mount that now
240
if( RemoveableScriptDirectory != "" &&
241
directory.compare(0,RemoveableScriptDirectory.length(), RemoveableScriptDirectory) ==0) {
242
system( ( DataDir + "script_mount_script_disk " ).c_str() );
243
cout << "MOUNT DISK to read directory\n";
245
RemoveableDirectoryMounted = 1;
248
if ((dp = opendir(directory.c_str())) == NULL) {
249
cout << "Unable to read script directory" << directory << endl;
253
// TODO: sort the directory
254
while ((entryp = readdir(dp)) != NULL) {
255
tmp = entryp->d_name;
257
if(tmp.length()>4 && tmp.find(".sts", tmp.length()-4)!=string::npos ) {
258
result += tmp + "\n";
259
//cout << entryp->d_name << endl;
264
if(RemoveableDirectoryMounted) {
265
// leave disk unmounted
266
system( ( DataDir + "script_unmount_script_disk " ).c_str() );
267
cout << "UNMOUNT DISK\n";
268
RemoveableDirectoryMounted = 0;
271
//cout << "Result = " << result;
258
/****************************************************************************
259
get a list of script files from directory. If directory is equal to the
260
removable media directory, the mount and unmount scripts are called
261
before and after the file listing is done. Note the removable media
262
directory must be a complete path - not a relative path.
263
returns a string list of script file names, delimited with the '\n'
265
****************************************************************************/
266
string ScriptMgr::get_script_list(QString directory) {
268
// if directory is on mountable disk, mount that now
269
if(RemoveableScriptDirectory!="" && directory.startsWith(RemoveableScriptDirectory))
273
system(QFile::encodeName(StelApp::getInstance().getFileMgr().findFile("data/script_mount_script_disk")).constData());
274
cout << "MOUNT DISK to read directory\n";
275
directory += "/scripts";
276
RemoveableDirectoryMounted = 1;
280
cerr << "ERROR while trying to mount removable media: " << e.what() << endl;
286
// we add an entry if there exists <directory>/scriptname/scriptname.sts
287
QSet<QString> scriptList = StelApp::getInstance().getFileMgr().listContents(directory, StelFileMgr::FILE);
288
for(QSet<QString>::iterator i=scriptList.begin(); i!=scriptList.end(); i++)
290
if (i->endsWith(".sts"))
292
result = result + (*i).toUtf8().data() + '\n';
298
cerr << "ERROR while listing scripts: " << e.what() << endl;
301
if(RemoveableDirectoryMounted) {
304
system(QFile::encodeName(StelApp::getInstance().getFileMgr().findFile("data/script_unmount_script_disk")).constData());
305
cout << "UNMOUNT DISK" << endl;
306
RemoveableDirectoryMounted = 0;
310
cerr << "ERROR while trying to unmount removable media: " << e.what() << endl;
276
string ScriptMgr::get_script_path() {
277
if(script) return script->get_path();
317
QString ScriptMgr::get_script_path() {
318
if(script) return script->get_path();
285
326
// first try on removeable directory
286
327
if(RemoveableScriptDirectory !="" &&
287
play_script(RemoveableScriptDirectory + "scripts/startup.sts",
288
RemoveableScriptDirectory + "scripts/")) {
291
// try in stellarium tree
292
return play_script(DataDir + "scripts/startup.sts", DataDir + "scripts/");
328
play_script(RemoveableScriptDirectory + "/scripts/startup.sts",
329
RemoveableScriptDirectory + "/scripts/")) {
333
QString fullPath(StelApp::getInstance().getFileMgr().findFile("scripts/startup.sts"));
334
QString parentDir(StelApp::getInstance().getFileMgr().dirName(fullPath));
335
play_script(fullPath, parentDir + "/");
339
cerr << "ERROR running startup.sts script: " << e.what() << endl;