~ubuntu-branches/debian/squeeze/stellarium/squeeze

« back to all changes in this revision

Viewing changes to src/script_mgr.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cédric Delfosse
  • Date: 2008-05-19 21:28:23 UTC
  • mfrom: (3.1.5 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080519212823-m5nfiuntxstxzxj7
Tags: 0.9.1-4
Add libxcursor-dev, libxfixes-dev, libxinerama-dev, libqt4-opengl-dev to
build-deps (Closes: #479906)

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
 
21
21
#include <iostream>
22
 
#include <string>
23
22
#include <dirent.h>
24
23
#include <cstdio>
 
24
#include <sstream>
 
25
#include <iomanip>
 
26
#include <QFile>
25
27
 
26
28
#include "script_mgr.h"
27
 
 
 
29
#include "script.h"
 
30
#include "stel_command_interface.h"
 
31
#include "StelApp.hpp"
 
32
#include "StelFileMgr.hpp"
 
33
#include "InitParser.hpp"
28
34
 
29
35
using namespace std;
30
36
 
31
 
 
32
 
ScriptMgr::ScriptMgr(StelCommandInterface *command_interface, string _data_dir) : play_paused(false) {
33
 
  commander = command_interface;
34
 
  DataDir = _data_dir;
35
 
  recording = 0;
36
 
  playing = 0;
37
 
  record_elapsed_time = 0;
38
 
 
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;
 
40
        recording = 0;
 
41
        playing = 0;
 
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;
 
47
 
42
48
}
43
49
 
44
50
ScriptMgr::~ScriptMgr() {
45
51
}
46
52
 
 
53
void ScriptMgr::init(const InitParser& conf)
 
54
{
 
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);
 
57
}
 
58
 
47
59
// path is used for loading script assets 
48
 
bool ScriptMgr::play_script(string script_file, string script_path) {
49
 
  // load script...
50
 
 
51
 
  if(playing){
52
 
          // cancel current script and start next (one script can call another)
53
 
          cancel_script();
54
 
  }
55
 
 
56
 
  set_gui_debug(0);  // Default off until script sets otherwise
57
 
 
58
 
  //if (script) delete script;
59
 
  script = new Script();
60
 
 
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";
66
 
                
67
 
          RemoveableDirectoryMounted = 1;
68
 
  }
69
 
 
70
 
  if( script->load(script_file, script_path) ) {
71
 
    playing = 1;
72
 
    play_paused = 0;
73
 
    elapsed_time = wait_time = 0;
74
 
        return 1;
75
 
 
76
 
  } else {
77
 
    delete script;
78
 
        script = NULL;
79
 
        return 0;
80
 
  }
 
60
bool ScriptMgr::play_script(const QString& script_file, const QString& script_path) {
 
61
        // load script...
 
62
        
 
63
        if(playing){
 
64
                // cancel current script and start next (one script can call another)
 
65
                cancel_script();
 
66
        }
 
67
 
 
68
        set_gui_debug(0);  // Default off until script sets otherwise
 
69
 
 
70
        //if (script) delete script;
 
71
        script = new Script();
 
72
 
 
73
        // if script is on mountable disk, mount that now
 
74
        if( RemoveableScriptDirectory != "" && script_file.startsWith(RemoveableScriptDirectory))
 
75
        {
 
76
                try
 
77
                {
 
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;
 
81
                }
 
82
                catch(exception& e)
 
83
                {
 
84
                        cerr << "ERROR while trying to mount removable media: " << e.what() << endl;            
 
85
                }
 
86
        }
 
87
 
 
88
        if( script->load(script_file, script_path) ) {
 
89
                playing = 1;
 
90
                play_paused = 0;
 
91
                elapsed_time = wait_time = 0;
 
92
                return 1;
 
93
 
 
94
        } else {
 
95
                cancel_script();
 
96
                return 0;
 
97
        }
81
98
}
82
99
 
83
100
void ScriptMgr::cancel_script() {
89
106
        play_paused = 0;
90
107
        
91
108
        if(RemoveableDirectoryMounted) {
92
 
                system( ( DataDir + "script_unmount_script_disk " ).c_str() );    
93
 
                cout << "UNMOUNT DISK\n";
94
 
                RemoveableDirectoryMounted = 0;
 
109
                try
 
110
                {
 
111
                        system(QFile::encodeName(StelApp::getInstance().getFileMgr().findFile("data/script_unmount_script_disk")).constData());  
 
112
                        cout << "UNMOUNT DISK" << endl;
 
113
                        RemoveableDirectoryMounted = 0;
 
114
                }
 
115
                catch(exception& e)
 
116
                {
 
117
                        cerr << "ERROR while trying to unmount removable media: " << e.what() << endl;          
 
118
                }
95
119
        }
96
120
}
97
121
 
98
122
 
99
123
void ScriptMgr::pause_script() {
100
 
  play_paused = 1;
101
 
  // need to pause time as well
102
 
  commander->execute_command("timerate action pause");
 
124
        play_paused = 1;
 
125
        // need to pause time as well
 
126
        commander->execute_command("timerate action pause");
103
127
}
104
128
 
105
129
void ScriptMgr::resume_script() { 
117
141
                return;
118
142
        }
119
143
 
120
 
        if(script_filename != "") {
121
 
                rec_file.open(script_filename.c_str(), fstream::out);
122
 
        } else {
123
 
 
124
 
                string sdir;
125
 
#if defined(WIN32) || defined(CYGWIN) || defined(__MINGW32__)
126
 
                if(getenv("USERPROFILE")!=NULL){
127
 
                        //for Win XP etc.
128
 
                        sdir = string(getenv("USERPROFILE")) + "\\My Documents\\";
129
 
                }else{
130
 
                        //for Win 98 etc.
131
 
                        sdir = "C:\\My Documents\\";
132
 
                }
133
 
#else
134
 
                sdir = string(getenv("HOME")) + "/";
135
 
#endif
136
 
#ifdef MACOSX
137
 
                sdir += "/Desktop/";
138
 
#endif
139
 
 
140
 
                // add a number to be unique
141
 
                char c[3];
142
 
                FILE * fp;
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;
 
147
                try
 
148
                {
 
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))
144
152
                        {
145
 
                                snprintf(c,3,"%d",j);
146
 
 
147
 
                                script_filename = sdir + "stellarium" + c + ".sts";
148
 
                                fp = fopen(script_filename.c_str(), "r");
149
 
                                if(fp == NULL)
150
 
                                        break;
151
 
                                else
152
 
                                        fclose(fp);
 
153
                                if (!StelApp::getInstance().getFileMgr().mkDir(scriptSaveDir))
 
154
                                {
 
155
                                        throw(runtime_error("couldn't create it"));                             
 
156
                                }
153
157
                        }
154
 
        
155
 
                rec_file.open(script_filename.c_str(), fstream::out);
156
 
 
 
158
                }
 
159
                catch(exception& e)
 
160
                {
 
161
                        cerr << "ERROR ScriptMgr::record_script: could not determine script save directory (" << e.what() << ") NOT RECORDING" << endl;
 
162
                        return;
 
163
                }
 
164
                
 
165
                QString scriptPath;
 
166
                for(int j=0; j<1000; ++j)
 
167
                {
 
168
                        stringstream oss;
 
169
                        oss << setfill('0') << setw(3) << j;
 
170
                        scriptPath = scriptSaveDir +"/"+ "recorded-" + oss.str().c_str() + ".sts";
 
171
                        if (!StelApp::getInstance().getFileMgr().exists(scriptPath))
 
172
                                break;
 
173
                }
 
174
                // catch the case where we we have all 999 scripts existing...
 
175
                if (StelApp::getInstance().getFileMgr().exists(scriptPath))
 
176
                {
 
177
                        cerr << "ERROR ScriptMgr::record_script: could not make a new scipt filename, NOT RECORDING" << endl;
 
178
                        return;
 
179
                }
 
180
                else
 
181
                {
 
182
                        script_filename = QFile::encodeName(scriptPath).constData();
 
183
                }
157
184
        }
158
185
        
 
186
        // Open the file for writing.
 
187
        rec_file.open(script_filename.c_str(), fstream::out);   
159
188
 
160
189
        if(rec_file.is_open()) {
161
190
                recording = 1;
165
194
        } else {
166
195
                cout << "Error opening script file for writing: " << script_filename << endl;
167
196
                rec_filename = "";
168
 
        } 
 
197
        }
169
198
}
170
199
 
171
200
void ScriptMgr::record_command(string commandline) {
172
201
 
173
 
  if(recording) {
174
 
    // write to file...
 
202
        if(recording) {
 
203
                // write to file...
175
204
 
176
 
    if(record_elapsed_time) {
177
 
      rec_file << "wait duration " << record_elapsed_time/1000.f << endl;
178
 
      record_elapsed_time = 0;
179
 
    }
 
205
                if(record_elapsed_time) {
 
206
                        rec_file << "wait duration " << record_elapsed_time/1000.f << endl;
 
207
                        record_elapsed_time = 0;
 
208
                }
180
209
    
181
 
    rec_file << commandline << endl;
 
210
                rec_file << commandline << endl;
182
211
 
183
 
        // TEMPORARY for debugging
184
 
    cout << commandline << endl;
185
 
  }
 
212
                // TEMPORARY for debugging
 
213
                cout << commandline << endl;
 
214
        }
186
215
}
187
216
 
188
217
void ScriptMgr::cancel_record_script() {
196
225
 
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) {
200
 
 
201
 
  if(recording) record_elapsed_time += delta_time;
202
 
 
203
 
  if(playing && !play_paused) {
204
 
 
205
 
    elapsed_time += delta_time;  // time elapsed since last command (should have been) executed
206
 
 
207
 
    if(elapsed_time >= wait_time) {
208
 
      // now time to run next command
209
 
 
210
 
 
211
 
      //      cout << "dt " << delta_time << " et: " << elapsed_time << endl;
212
 
      elapsed_time -= wait_time;
213
 
      string comd;
214
 
      unsigned long int wait;
215
 
      if(script->next_command(comd)) {
216
 
        commander->execute_command(comd, wait, 0);  // untrusted commands
217
 
        wait_time = wait; 
218
 
 
219
 
      } else {
220
 
        // script done
221
 
        cout << "Script completed." << endl;
222
 
        commander->execute_command("script action end");
223
 
      }
224
 
    }
225
 
  }
 
228
void ScriptMgr::update(double delta_time) 
 
229
{
 
230
        if(recording) record_elapsed_time += (unsigned long int)(delta_time * 1000);
 
231
 
 
232
        if(playing && !play_paused) 
 
233
        {
 
234
                // time elapsed since last command (should have been) executed
 
235
                elapsed_time += (unsigned long int)(delta_time * 1000);  
 
236
                
 
237
                if(elapsed_time >= wait_time) 
 
238
                {
 
239
                        // now time to run next command
 
240
                        elapsed_time -= wait_time;
 
241
                        string comd;
 
242
                        unsigned long int wait;
 
243
                        if(script->next_command(comd)) 
 
244
                        {
 
245
                                commander->execute_command(comd, wait, 0);  // untrusted commands
 
246
                                wait_time = wait; 
 
247
 
 
248
                        } else {
 
249
                                // script done
 
250
                                cout << "Script completed." << endl;
 
251
                                commander->execute_command("script action end");
 
252
                        }
 
253
                }
 
254
        }
226
255
 
227
256
}  
228
257
 
229
 
// get a list of script files from directory
230
 
string ScriptMgr::get_script_list(string directory) {
231
 
 
232
 
  // TODO: This is POSIX specific
233
 
 
234
 
  struct dirent *entryp;
235
 
  DIR *dp;
236
 
  string result="";
237
 
  string tmp;
238
 
 
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";
244
 
                
245
 
          RemoveableDirectoryMounted = 1;
246
 
  }
247
 
 
248
 
  if ((dp = opendir(directory.c_str())) == NULL) {
249
 
    cout << "Unable to read script directory" << directory << endl;
250
 
    return "";
251
 
  }
252
 
 
253
 
  // TODO: sort the directory
254
 
  while ((entryp = readdir(dp)) != NULL) {
255
 
    tmp = entryp->d_name;
256
 
 
257
 
    if(tmp.length()>4 && tmp.find(".sts", tmp.length()-4)!=string::npos ) {
258
 
      result += tmp + "\n";
259
 
      //cout << entryp->d_name << endl;
260
 
    }
261
 
  }
262
 
  closedir(dp);
263
 
 
264
 
  if(RemoveableDirectoryMounted) {
265
 
          // leave disk unmounted
266
 
          system( ( DataDir + "script_unmount_script_disk " ).c_str() );          
267
 
          cout << "UNMOUNT DISK\n";
268
 
          RemoveableDirectoryMounted = 0;
269
 
  }
270
 
 
271
 
  //cout << "Result = " << result;
272
 
  return result;
273
 
 
 
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' 
 
264
 character
 
265
****************************************************************************/
 
266
string ScriptMgr::get_script_list(QString directory) {
 
267
        string result="";
 
268
        // if directory is on mountable disk, mount that now
 
269
        if(RemoveableScriptDirectory!="" && directory.startsWith(RemoveableScriptDirectory)) 
 
270
        {
 
271
                try
 
272
                {
 
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;
 
277
                }
 
278
                catch(exception& e)
 
279
                {
 
280
                        cerr << "ERROR while trying to mount removable media: " << e.what() << endl;
 
281
                }
 
282
        }
 
283
 
 
284
        try
 
285
        {
 
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++)
 
289
                {
 
290
                        if (i->endsWith(".sts"))
 
291
                        {
 
292
                                result = result + (*i).toUtf8().data() + '\n';
 
293
                        }
 
294
                }
 
295
        }
 
296
        catch(exception& e)
 
297
        {
 
298
                cerr << "ERROR while listing scripts: " << e.what() << endl;
 
299
        }
 
300
        
 
301
        if(RemoveableDirectoryMounted) {
 
302
                try
 
303
                {
 
304
                        system(QFile::encodeName(StelApp::getInstance().getFileMgr().findFile("data/script_unmount_script_disk")).constData());
 
305
                        cout << "UNMOUNT DISK" << endl;
 
306
                        RemoveableDirectoryMounted = 0;
 
307
                }
 
308
                catch(exception& e)
 
309
                {
 
310
                        cerr << "ERROR while trying to unmount removable media: " << e.what() << endl;
 
311
                }
 
312
        }
 
313
 
 
314
        return result;
274
315
}
275
316
 
276
 
string ScriptMgr::get_script_path() { 
277
 
  if(script) return script->get_path(); 
278
 
  return ""; 
 
317
QString ScriptMgr::get_script_path() { 
 
318
        if(script) return script->get_path(); 
 
319
        return ""; 
279
320
}
280
321
 
281
322
 
284
325
 
285
326
        // first try on removeable directory
286
327
        if(RemoveableScriptDirectory !="" &&
287
 
           play_script(RemoveableScriptDirectory + "scripts/startup.sts", 
288
 
                                        RemoveableScriptDirectory + "scripts/")) {
289
 
                return 1;
290
 
        } else {
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/")) {
293
330
        } 
294
 
 
 
331
        else {
 
332
                try {
 
333
                        QString fullPath(StelApp::getInstance().getFileMgr().findFile("scripts/startup.sts")); 
 
334
                        QString parentDir(StelApp::getInstance().getFileMgr().dirName(fullPath));
 
335
                        play_script(fullPath, parentDir + "/");
 
336
                }
 
337
                catch(exception& e)
 
338
                {
 
339
                        cerr << "ERROR running startup.sts script: " << e.what() << endl;
 
340
                }
 
341
        }
 
342
        return 1;
295
343
}