Subversion Repositories HomeAutomation

Rev

Rev 1042 | Rev 1203 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 1042 Rev 1060
1
/***************************************************************************
1
/***************************************************************************
2
 *   Copyright (C) December 10, 2008 by Mattias Runge                             *
2
 *   Copyright (C) December 10, 2008 by Mattias Runge                             *
3
 *   mattias@runge.se                                                      *
3
 *   mattias@runge.se                                                      *
4
 *   virtualmachine.cpp                                            *
4
 *   virtualmachine.cpp                                            *
5
 *                                                                         *
5
 *                                                                         *
6
 *   This program is free software; you can redistribute it and/or modify  *
6
 *   This program is free software; you can redistribute it and/or modify  *
7
 *   it under the terms of the GNU General Public License as published by  *
7
 *   it under the terms of the GNU General Public License as published by  *
8
 *   the Free Software Foundation; either version 2 of the License, or     *
8
 *   the Free Software Foundation; either version 2 of the License, or     *
9
 *   (at your option) any later version.                                   *
9
 *   (at your option) any later version.                                   *
10
 *                                                                         *
10
 *                                                                         *
11
 *   This program is distributed in the hope that it will be useful,       *
11
 *   This program is distributed in the hope that it will be useful,       *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU General Public License for more details.                          *
14
 *   GNU General Public License for more details.                          *
15
 *                                                                         *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU General Public License     *
16
 *   You should have received a copy of the GNU General Public License     *
17
 *   along with this program; if not, write to the                         *
17
 *   along with this program; if not, write to the                         *
18
 *   Free Software Foundation, Inc.,                                       *
18
 *   Free Software Foundation, Inc.,                                       *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20
 ***************************************************************************/
20
 ***************************************************************************/
21
 
21
 
22
#include "virtualmachine.h"
22
#include "virtualmachine.h"
23
 
23
 
24
VirtualMachine* VirtualMachine::myInstance = NULL;
24
VirtualMachine* VirtualMachine::myInstance = NULL;
25
 
25
 
26
VirtualMachine& VirtualMachine::getInstance()
26
VirtualMachine& VirtualMachine::getInstance()
27
{
27
{
28
    if (myInstance == NULL)
28
    if (myInstance == NULL)
29
    {
29
    {
30
        myInstance = new VirtualMachine();
30
        myInstance = new VirtualMachine();
31
    }
31
    }
32
 
32
 
33
    return *myInstance;
33
    return *myInstance;
34
}
34
}
35
 
35
 
36
void VirtualMachine::deleteInstance()
36
void VirtualMachine::deleteInstance()
37
{
37
{
38
    if (myInstance != NULL)
38
    if (myInstance != NULL)
39
    {
39
    {
40
        delete myInstance;
40
        delete myInstance;
41
        myInstance = NULL;
41
        myInstance = NULL;
42
    }
42
    }
43
}
43
}
44
 
44
 
45
VirtualMachine::VirtualMachine()
45
VirtualMachine::VirtualMachine()
46
{
46
{
47
}
47
}
48
 
48
 
49
VirtualMachine::~VirtualMachine()
49
VirtualMachine::~VirtualMachine()
50
{
50
{
51
    stop();
51
    stop();
52
 
52
 
53
    myCommandThread.stop();
53
    myCommandThread.stop();
54
 
54
 
55
    ///FIXME: Verify that this works and does not cause segfaults
55
    ///FIXME: Verify that this works and does not cause segfaults
56
    for (map<int, SocketThread*>::iterator iter = mySocketThreads.begin(); iter != mySocketThreads.end(); iter++)
56
    for (map<int, SocketThread*>::iterator iter = mySocketThreads.begin(); iter != mySocketThreads.end(); iter++)
57
    {
57
    {
58
        iter->second->stop();
58
        iter->second->stop();
59
        delete iter->second;
59
        delete iter->second;
60
        //mySocketThreads.erase(iter);
60
        //mySocketThreads.erase(iter);
61
    }
61
    }
62
 
62
 
63
    mySocketThreads.clear();
63
    mySocketThreads.clear();
64
 
64
 
65
    for (map<int, IntervalThread*>::iterator iter = myIntervalThreads.begin(); iter != myIntervalThreads.end(); iter++)
65
    for (map<int, IntervalThread*>::iterator iter = myIntervalThreads.begin(); iter != myIntervalThreads.end(); iter++)
66
    {
66
    {
67
        iter->second->stop();
67
        iter->second->stop();
68
        delete iter->second;
68
        delete iter->second;
69
        //myIntervalThreads.erase(iter);
69
        //myIntervalThreads.erase(iter);
70
    }
70
    }
71
 
71
 
72
    myIntervalThreads.clear();
72
    myIntervalThreads.clear();
73
}
73
}
74
 
74
 
75
void VirtualMachine::run()
75
void VirtualMachine::run()
76
{
76
{
77
    myGlobal = ObjectTemplate::New();
77
    myGlobal = ObjectTemplate::New();
78
    myGlobal->Set(String::New("_quit"), FunctionTemplate::New(VirtualMachine::_quit));
78
    myGlobal->Set(String::New("_quit"), FunctionTemplate::New(VirtualMachine::_quit));
79
    myGlobal->Set(String::New("_print"), FunctionTemplate::New(VirtualMachine::_print));
79
    myGlobal->Set(String::New("_print"), FunctionTemplate::New(VirtualMachine::_print));
80
    myGlobal->Set(String::New("log"), FunctionTemplate::New(VirtualMachine::_log));
80
    myGlobal->Set(String::New("log"), FunctionTemplate::New(VirtualMachine::_log));
81
    myGlobal->Set(String::New("sendCanMessage"), FunctionTemplate::New(VirtualMachine::_sendCanMessage));
81
    myGlobal->Set(String::New("sendCanMessage"), FunctionTemplate::New(VirtualMachine::_sendCanMessage));
82
    myGlobal->Set(String::New("sendCanNMTMessage"), FunctionTemplate::New(VirtualMachine::_sendCanNMTMessage));
82
    myGlobal->Set(String::New("sendCanNMTMessage"), FunctionTemplate::New(VirtualMachine::_sendCanNMTMessage));
83
    myGlobal->Set(String::New("loadScript"), FunctionTemplate::New(VirtualMachine::_loadScript));
83
    myGlobal->Set(String::New("loadScript"), FunctionTemplate::New(VirtualMachine::_loadScript));
84
    myGlobal->Set(String::New("startIntervalThread"), FunctionTemplate::New(VirtualMachine::_startIntervalThread));
84
    myGlobal->Set(String::New("startIntervalThread"), FunctionTemplate::New(VirtualMachine::_startIntervalThread));
85
    myGlobal->Set(String::New("stopIntervalThread"), FunctionTemplate::New(VirtualMachine::_stopIntervalThread));
85
    myGlobal->Set(String::New("stopIntervalThread"), FunctionTemplate::New(VirtualMachine::_stopIntervalThread));
86
    myGlobal->Set(String::New("setIntervalThreadTimeout"), FunctionTemplate::New(VirtualMachine::_setIntervalThreadTimeout));
86
    myGlobal->Set(String::New("setIntervalThreadTimeout"), FunctionTemplate::New(VirtualMachine::_setIntervalThreadTimeout));
87
    myGlobal->Set(String::New("startSocketThread"), FunctionTemplate::New(VirtualMachine::_startSocketThread));
87
    myGlobal->Set(String::New("startSocketThread"), FunctionTemplate::New(VirtualMachine::_startSocketThread));
88
    myGlobal->Set(String::New("stopSocketThread"), FunctionTemplate::New(VirtualMachine::_stopSocketThread));
88
    myGlobal->Set(String::New("stopSocketThread"), FunctionTemplate::New(VirtualMachine::_stopSocketThread));
89
    myGlobal->Set(String::New("sendToSocketThread"), FunctionTemplate::New(VirtualMachine::_sendToSocketThread));
89
    myGlobal->Set(String::New("sendToSocketThread"), FunctionTemplate::New(VirtualMachine::_sendToSocketThread));
90
    myGlobal->Set(String::New("loadDataStore"), FunctionTemplate::New(VirtualMachine::_loadDataStore));
90
    myGlobal->Set(String::New("loadDataStore"), FunctionTemplate::New(VirtualMachine::_loadDataStore));
91
    myGlobal->Set(String::New("getFileContents"), FunctionTemplate::New(VirtualMachine::_getFileContents));
91
    myGlobal->Set(String::New("getFileContents"), FunctionTemplate::New(VirtualMachine::_getFileContents));
92
    myGlobal->Set(String::New("uint2hex"), FunctionTemplate::New(VirtualMachine::_uint2hex));
92
    myGlobal->Set(String::New("uint2hex"), FunctionTemplate::New(VirtualMachine::_uint2hex));
93
    myGlobal->Set(String::New("hex2bin"), FunctionTemplate::New(VirtualMachine::_hex2bin));
93
    myGlobal->Set(String::New("hex2bin"), FunctionTemplate::New(VirtualMachine::_hex2bin));
94
    myGlobal->Set(String::New("bin2hex"), FunctionTemplate::New(VirtualMachine::_bin2hex));
94
    myGlobal->Set(String::New("bin2hex"), FunctionTemplate::New(VirtualMachine::_bin2hex));
95
    myGlobal->Set(String::New("bin2float"), FunctionTemplate::New(VirtualMachine::_bin2float));
95
    myGlobal->Set(String::New("bin2float"), FunctionTemplate::New(VirtualMachine::_bin2float));
96
    myGlobal->Set(String::New("float2bin"), FunctionTemplate::New(VirtualMachine::_float2bin));
96
    myGlobal->Set(String::New("float2bin"), FunctionTemplate::New(VirtualMachine::_float2bin));
97
    myGlobal->Set(String::New("bin2uint"), FunctionTemplate::New(VirtualMachine::_bin2uint));
97
    myGlobal->Set(String::New("bin2uint"), FunctionTemplate::New(VirtualMachine::_bin2uint));
98
    myGlobal->Set(String::New("uint2bin"), FunctionTemplate::New(VirtualMachine::_uint2bin));
98
    myGlobal->Set(String::New("uint2bin"), FunctionTemplate::New(VirtualMachine::_uint2bin));
99
    myGlobal->Set(String::New("hex2uint"), FunctionTemplate::New(VirtualMachine::_hex2uint));
99
    myGlobal->Set(String::New("hex2uint"), FunctionTemplate::New(VirtualMachine::_hex2uint));
-
 
100
    myGlobal->Set(String::New("sleep"), FunctionTemplate::New(VirtualMachine::_sleep));
100
    myContext = Context::New(NULL, myGlobal);
101
    myContext = Context::New(NULL, myGlobal);
101
 
102
 
102
 
103
 
103
    if (loadScript("System/Base.js"))
104
    if (loadScript("System/Base.js"))
104
    {
105
    {
105
        loadScript("System/Startup.js");
106
        loadScript("System/Startup.js");
106
 
107
 
107
        loadScript("Autostart.js");
108
        loadScript("Autostart.js");
108
 
109
 
109
        Context::Scope contextScope(myContext);
110
        Context::Scope contextScope(myContext);
110
 
111
 
111
        myFunctionStartup = Handle<Function>::Cast(myContext->Global()->Get(String::New("startup")));
112
        myFunctionStartup = Handle<Function>::Cast(myContext->Global()->Get(String::New("startup")));
112
    }
113
    }
113
    else
114
    else
114
    {
115
    {
115
        ///FIXME: We should probably exit the application here
116
        ///FIXME: We should probably exit the application here
116
        return;
117
        return;
117
    }
118
    }
118
 
119
 
119
    const int argc = 0;
120
    const int argc = 0;
120
    Handle<Value> argv[argc] = { };
121
    Handle<Value> argv[argc] = { };
121
    Handle<Value> result = myFunctionStartup->Call(myFunctionStartup, argc, argv);
122
    Handle<Value> result = myFunctionStartup->Call(myFunctionStartup, argc, argv);
122
 
123
 
123
 
124
 
124
    string commandPort = Settings::get("CommandPort");
125
    string commandPort = Settings::get("CommandPort");
125
    if (commandPort != "")
126
    if (commandPort != "")
126
    {
127
    {
127
        myCommandThread.setSettings(stoi(commandPort), "Command console");
128
        myCommandThread.setSettings(stoi(commandPort), "Command console");
128
        myCommandThread.start();
129
        myCommandThread.start();
129
    }
130
    }
130
    else
131
    else
131
    {
132
    {
132
        Logger &log = Logger::getInstance();
133
        Logger &log = Logger::getInstance();
133
        log.add("CommandPort is not defined, can not start Command console socket\n");
134
        log.add("CommandPort is not defined, can not start Command console socket\n");
134
    }
135
    }
135
 
136
 
136
 
137
 
137
    mySemaphore.lock();
138
    mySemaphore.lock();
138
 
139
 
139
    while (true)
140
    while (true)
140
    {
141
    {
141
        while (myExpressions.size() > 0)
142
        while (myExpressions.size() > 0)
142
        {
143
        {
143
            runExpression(myExpressions.pop());
144
            runExpression(myExpressions.pop());
144
        }
145
        }
145
 
146
 
146
        mySemaphore.wait();
147
        mySemaphore.wait();
147
    }
148
    }
148
 
149
 
149
    mySemaphore.unlock();
150
    mySemaphore.unlock();
150
}
151
}
151
 
152
 
152
void VirtualMachine::queueExpression(Expression expression)
153
void VirtualMachine::queueExpression(Expression expression)
153
{
154
{
154
    myExpressions.push(expression);
155
    myExpressions.push(expression);
155
    mySemaphore.broadcast();
156
    mySemaphore.broadcast();
156
}
157
}
157
 
158
 
158
string VirtualMachine::formatException(TryCatch* tryCatch)
159
string VirtualMachine::formatException(TryCatch* tryCatch)
159
{
160
{
160
    string result;
161
    string result;
161
 
162
 
162
    HandleScope handleScope;
163
    HandleScope handleScope;
163
    String::Utf8Value exception(tryCatch->Exception());
164
    String::Utf8Value exception(tryCatch->Exception());
164
    Handle<v8::Message> message = tryCatch->Message();
165
    Handle<v8::Message> message = tryCatch->Message();
165
 
166
 
166
    string strException = *exception;
167
    string strException = *exception;
167
 
168
 
168
    if (message.IsEmpty())
169
    if (message.IsEmpty())
169
    {
170
    {
170
        result += strException + "\n";
171
        result += strException + "\n";
171
    }
172
    }
172
    else
173
    else
173
    {
174
    {
174
        String::Utf8Value filename(message->GetScriptResourceName());
175
        String::Utf8Value filename(message->GetScriptResourceName());
175
        string strFilename = *filename;
176
        string strFilename = *filename;
176
 
177
 
177
        result += strFilename + ":" + itos(message->GetLineNumber()) + ": " + strException + "\n";
178
        result += strFilename + ":" + itos(message->GetLineNumber()) + ": " + strException + "\n";
178
 
179
 
179
        String::Utf8Value sourceline(message->GetSourceLine());
180
        String::Utf8Value sourceline(message->GetSourceLine());
180
        string strSourceline = *sourceline;
181
        string strSourceline = *sourceline;
181
 
182
 
182
        result += strSourceline + "\n";
183
        result += strSourceline + "\n";
183
 
184
 
184
        string underline = rpad("", message->GetStartColumn(), ' ');
185
        string underline = rpad("", message->GetStartColumn(), ' ');
185
        underline = rpad(underline, message->GetEndColumn(), '^');
186
        underline = rpad(underline, message->GetEndColumn(), '^');
186
 
187
 
187
        result += underline + "\n";
188
        result += underline + "\n";
188
    }
189
    }
189
 
190
 
190
    return result;
191
    return result;
191
}
192
}
192
 
193
 
193
bool VirtualMachine::loadDataStore(string storeName)
194
bool VirtualMachine::loadDataStore(string storeName)
194
{
195
{
195
    Logger &log = Logger::getInstance();
196
    Logger &log = Logger::getInstance();
196
 
197
 
197
    string basePath = Settings::get("BasePath") + "Services/DataStores/";
198
    string basePath = Settings::get("BasePath") + "Services/DataStores/";
198
    string scriptFileName = basePath + storeName + ".js";
199
    string scriptFileName = basePath + storeName + ".js";
199
 
200
 
200
    if (!file_exists(scriptFileName))
201
    if (!file_exists(scriptFileName))
201
    {
202
    {
202
        log.add("Failed to load datastore " + scriptFileName + ", file does not exist.\n");
203
        log.add("Failed to load datastore " + scriptFileName + ", file does not exist.\n");
203
        return false;
204
        return false;
204
    }
205
    }
205
 
206
 
206
    string scriptSource = file_get_contents(scriptFileName);
207
    string scriptSource = file_get_contents(scriptFileName);
207
 
208
 
208
    scriptSource = "DataStore.addStore('" + storeName + "', " + str_replace("\n", "", scriptSource) + ");";
209
    scriptSource = "DataStore.addStore('" + storeName + "', " + str_replace("\n", "", scriptSource) + ");";
209
 
210
 
210
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
211
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
211
    Handle<String> name = String::New(scriptFileName.c_str(), scriptFileName.length());
212
    Handle<String> name = String::New(scriptFileName.c_str(), scriptFileName.length());
212
 
213
 
213
    Context::Scope contextScope(myContext);
214
    Context::Scope contextScope(myContext);
214
 
215
 
215
    TryCatch tryCatch;
216
    TryCatch tryCatch;
216
 
217
 
217
    Handle<Script> script = Script::Compile(source, name);
218
    Handle<Script> script = Script::Compile(source, name);
218
 
219
 
219
    if (script.IsEmpty())
220
    if (script.IsEmpty())
220
    {
221
    {
221
        log.add(formatException(&tryCatch));
222
        log.add(formatException(&tryCatch));
222
        return false;
223
        return false;
223
    }
224
    }
224
    else
225
    else
225
    {
226
    {
226
        Handle<Value> result = script->Run();
227
        Handle<Value> result = script->Run();
227
 
228
 
228
        if (result.IsEmpty())
229
        if (result.IsEmpty())
229
        {
230
        {
230
            log.add(formatException(&tryCatch));
231
            log.add(formatException(&tryCatch));
231
            return false;
232
            return false;
232
        }
233
        }
233
 
234
 
234
        log.add("Loaded datastore " + storeName + "\n");
235
        log.add("Loaded datastore " + storeName + "\n");
235
    }
236
    }
236
 
237
 
237
    return true;
238
    return true;
238
}
239
}
239
 
240
 
240
bool VirtualMachine::loadScript(string scriptName)
241
bool VirtualMachine::loadScript(string scriptName)
241
{
242
{
242
    Logger &log = Logger::getInstance();
243
    Logger &log = Logger::getInstance();
243
 
244
 
244
    string basePath = Settings::get("BasePath") + "Services/";
245
    string basePath = Settings::get("BasePath") + "Services/";
245
    string scriptFileName = basePath + scriptName;
246
    string scriptFileName = basePath + scriptName;
246
 
247
 
247
    if (!file_exists(scriptFileName))
248
    if (!file_exists(scriptFileName))
248
    {
249
    {
249
        log.add("Failed to load " + scriptFileName + ", file does not exist.\n");
250
        log.add("Failed to load " + scriptFileName + ", file does not exist.\n");
250
        return false;
251
        return false;
251
    }
252
    }
252
 
253
 
253
    string scriptSource = file_get_contents(scriptFileName);
254
    string scriptSource = file_get_contents(scriptFileName);
254
 
255
 
255
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
256
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
256
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
257
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
257
 
258
 
258
    Context::Scope contextScope(myContext);
259
    Context::Scope contextScope(myContext);
259
 
260
 
260
    TryCatch tryCatch;
261
    TryCatch tryCatch;
261
 
262
 
262
    Handle<Script> script = Script::Compile(source, name);
263
    Handle<Script> script = Script::Compile(source, name);
263
 
264
 
264
    if (script.IsEmpty())
265
    if (script.IsEmpty())
265
    {
266
    {
266
        log.addToSyslog(formatException(&tryCatch));
267
        log.addToSyslog(formatException(&tryCatch));
267
        return false;
268
        return false;
268
    }
269
    }
269
    else
270
    else
270
    {
271
    {
271
        Handle<Value> result = script->Run();
272
        Handle<Value> result = script->Run();
272
 
273
 
273
        if (result.IsEmpty())
274
        if (result.IsEmpty())
274
        {
275
        {
275
            log.addToSyslog(formatException(&tryCatch));
276
            log.addToSyslog(formatException(&tryCatch));
276
            return false;
277
            return false;
277
        }
278
        }
278
 
279
 
279
        log.add("Loaded " + scriptName + "\n");
280
        log.add("Loaded " + scriptName + "\n");
280
    }
281
    }
281
 
282
 
282
    return true;
283
    return true;
283
}
284
}
284
 
285
 
285
unsigned int VirtualMachine::startIntervalThread(unsigned int timeout)
286
unsigned int VirtualMachine::startIntervalThread(unsigned int timeout)
286
{
287
{
287
    IntervalThread *intervalThread = new IntervalThread(timeout);
288
    IntervalThread *intervalThread = new IntervalThread(timeout);
288
 
289
 
289
    myIntervalThreads[intervalThread->getId()] = intervalThread;
290
    myIntervalThreads[intervalThread->getId()] = intervalThread;
290
    myIntervalThreads[intervalThread->getId()]->start();
291
    myIntervalThreads[intervalThread->getId()]->start();
291
 
292
 
292
    return intervalThread->getId();
293
    return intervalThread->getId();
293
}
294
}
294
 
295
 
295
bool VirtualMachine::stopIntervalThread(unsigned int id)
296
bool VirtualMachine::stopIntervalThread(unsigned int id)
296
{
297
{
297
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
298
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
298
    {
299
    {
299
        myIntervalThreads[id]->stop();
300
        myIntervalThreads[id]->stop();
300
        delete myIntervalThreads[id];
301
        delete myIntervalThreads[id];
301
        myIntervalThreads.erase(id);
302
        myIntervalThreads.erase(id);
302
 
303
 
303
        return true;
304
        return true;
304
    }
305
    }
305
 
306
 
306
    return false;
307
    return false;
307
}
308
}
308
 
309
 
309
bool VirtualMachine::setIntervalThreadTimeout(unsigned int id, unsigned int timeout)
310
bool VirtualMachine::setIntervalThreadTimeout(unsigned int id, unsigned int timeout)
310
{
311
{
311
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
312
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
312
    {
313
    {
313
        myIntervalThreads[id]->setTimeout(timeout);
314
        myIntervalThreads[id]->setTimeout(timeout);
314
        return true;
315
        return true;
315
    }
316
    }
316
 
317
 
317
    return false;
318
    return false;
318
}
319
}
319
 
320
 
320
unsigned int VirtualMachine::startSocketThread(string address, int port, unsigned int reconnectTimeout)
321
unsigned int VirtualMachine::startSocketThread(string address, int port, unsigned int reconnectTimeout)
321
{
322
{
322
    SocketThread *socketThread = new SocketThread(address, port, reconnectTimeout);
323
    SocketThread *socketThread = new SocketThread(address, port, reconnectTimeout);
323
    mySocketThreads[socketThread->getId()] = socketThread;
324
    mySocketThreads[socketThread->getId()] = socketThread;
324
    mySocketThreads[socketThread->getId()]->start();
325
    mySocketThreads[socketThread->getId()]->start();
325
 
326
 
326
    return socketThread->getId();
327
    return socketThread->getId();
327
}
328
}
328
 
329
 
329
bool VirtualMachine::stopSocketThread(unsigned int id)
330
bool VirtualMachine::stopSocketThread(unsigned int id)
330
{
331
{
331
    if (mySocketThreads.find(id) != mySocketThreads.end())
332
    if (mySocketThreads.find(id) != mySocketThreads.end())
332
    {
333
    {
333
        delete mySocketThreads[id];
334
        delete mySocketThreads[id];
334
        mySocketThreads.erase(id);
335
        mySocketThreads.erase(id);
335
        return true;
336
        return true;
336
    }
337
    }
337
 
338
 
338
    return false;
339
    return false;
339
}
340
}
340
 
341
 
341
void VirtualMachine::sendToSocketThread(unsigned int id, string data)
342
void VirtualMachine::sendToSocketThread(unsigned int id, string data)
342
{
343
{
343
    if (mySocketThreads.find(id) != mySocketThreads.end())
344
    if (mySocketThreads.find(id) != mySocketThreads.end())
344
    {
345
    {
345
        mySocketThreads[id]->send(data);
346
        mySocketThreads[id]->send(data);
346
    }
347
    }
347
}
348
}
348
 
349
 
349
void VirtualMachine::disconnectCommandClient(unsigned int id)
350
void VirtualMachine::disconnectCommandClient(unsigned int id)
350
{
351
{
351
    myCommandThread.disconnectClient(id);
352
    myCommandThread.disconnectClient(id);
352
}
353
}
353
 
354
 
354
void VirtualMachine::sendToCommandClient(unsigned int id, string data)
355
void VirtualMachine::sendToCommandClient(unsigned int id, string data)
355
{
356
{
356
    myCommandThread.sendTo(id, data);
357
    myCommandThread.sendTo(id, data);
357
}
358
}
358
 
359
 
359
void VirtualMachine::print(unsigned int id, string data)
360
void VirtualMachine::print(unsigned int id, string data)
360
{
361
{
361
    if (id == 0)
362
    if (id == 0)
362
    {
363
    {
363
        Logger &log = Logger::getInstance();
364
        Logger &log = Logger::getInstance();
364
        log.add(data);
365
        log.add(data);
365
    }
366
    }
366
    else
367
    else
367
    {
368
    {
368
        VirtualMachine &vm = VirtualMachine::getInstance();
369
        VirtualMachine &vm = VirtualMachine::getInstance();
369
        vm.sendToCommandClient(id, data);
370
        vm.sendToCommandClient(id, data);
370
    }
371
    }
371
}
372
}
372
 
373
 
373
bool VirtualMachine::runExpression(Expression expression)
374
bool VirtualMachine::runExpression(Expression expression)
374
{
375
{
375
    string scriptName = "runExpression";
376
    string scriptName = "runExpression";
376
 
377
 
377
    string scriptData = expression.getScript();
378
    string scriptData = expression.getScript();
378
 
379
 
379
    scriptData = "setClientId(" + itos(expression.getTargetId()) + ");\n" + scriptData + "\n";
380
    scriptData = "setClientId(" + itos(expression.getTargetId()) + ");\n" + scriptData + "\n";
380
 
381
 
381
    Handle<String> source =  String::New(scriptData.c_str(), scriptData.length());
382
    Handle<String> source =  String::New(scriptData.c_str(), scriptData.length());
382
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
383
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
383
 
384
 
384
    Context::Scope contextScope(myContext);
385
    Context::Scope contextScope(myContext);
385
 
386
 
386
    TryCatch tryCatch;
387
    TryCatch tryCatch;
387
 
388
 
388
    Handle<Script> script = Script::Compile(source, name);
389
    Handle<Script> script = Script::Compile(source, name);
389
 
390
 
390
    if (script.IsEmpty())
391
    if (script.IsEmpty())
391
    {
392
    {
392
        print(expression.getTargetId(), formatException(&tryCatch));
393
        print(expression.getTargetId(), formatException(&tryCatch));
393
        return false;
394
        return false;
394
    }
395
    }
395
    else
396
    else
396
    {
397
    {
397
        Handle<Value> result = script->Run();
398
        Handle<Value> result = script->Run();
398
 
399
 
399
        if (result.IsEmpty())
400
        if (result.IsEmpty())
400
        {
401
        {
401
            print(expression.getTargetId(), formatException(&tryCatch));
402
            print(expression.getTargetId(), formatException(&tryCatch));
402
            return false;
403
            return false;
403
        }
404
        }
404
        else if (expression.getTargetId() != 0)
405
        else if (expression.getTargetId() != 0)
405
        {
406
        {
406
             String::AsciiValue ascii(result);
407
             String::AsciiValue ascii(result);
407
             string resultString = *ascii;
408
             string resultString = *ascii;
408
 
409
 
409
             if (resultString != "undefined")
410
             if (resultString != "undefined")
410
             {
411
             {
411
                print(expression.getTargetId(), resultString + "\n");
412
                print(expression.getTargetId(), resultString + "\n");
412
             }
413
             }
413
        }
414
        }
414
    }
415
    }
415
 
416
 
416
    return true;
417
    return true;
417
}
418
}
418
 
419
 
419
 
420
 
420
Handle<Value> VirtualMachine::_quit(const Arguments& args)
421
Handle<Value> VirtualMachine::_quit(const Arguments& args)
421
{
422
{
422
    VirtualMachine &vm = VirtualMachine::getInstance();
423
    VirtualMachine &vm = VirtualMachine::getInstance();
423
 
424
 
424
    vm.disconnectCommandClient(args[0]->Uint32Value());
425
    vm.disconnectCommandClient(args[0]->Uint32Value());
425
 
426
 
426
    return Undefined();
427
    return Undefined();
427
}
428
}
428
 
429
 
429
Handle<Value> VirtualMachine::_log(const Arguments& args)
430
Handle<Value> VirtualMachine::_log(const Arguments& args)
430
{
431
{
431
    Logger &log = Logger::getInstance();
432
    Logger &log = Logger::getInstance();
432
 
433
 
433
    String::AsciiValue str(args[0]);
434
    String::AsciiValue str(args[0]);
434
 
435
 
435
    log.add(*str);
436
    log.add(*str);
436
 
437
 
437
    return Undefined();
438
    return Undefined();
438
}
439
}
439
 
440
 
440
Handle<Value> VirtualMachine::_print(const Arguments& args)
441
Handle<Value> VirtualMachine::_print(const Arguments& args)
441
{
442
{
442
    VirtualMachine &vm = VirtualMachine::getInstance();
443
    VirtualMachine &vm = VirtualMachine::getInstance();
443
 
444
 
444
    String::AsciiValue str(args[1]);
445
    String::AsciiValue str(args[1]);
445
 
446
 
446
    vm.print(args[0]->Uint32Value(), *str);
447
    vm.print(args[0]->Uint32Value(), *str);
447
 
448
 
448
    return Undefined();
449
    return Undefined();
449
}
450
}
450
 
451
 
451
Handle<Value> VirtualMachine::_sendCanMessage(const Arguments& args)
452
Handle<Value> VirtualMachine::_sendCanMessage(const Arguments& args)
452
{
453
{
453
    CanNetManager &canMan = CanNetManager::getInstance();
454
    CanNetManager &canMan = CanNetManager::getInstance();
454
 
455
 
455
    CanMessage canMessage;
456
    CanMessage canMessage;
456
 
457
 
457
    String::AsciiValue className(args[0]);
458
    String::AsciiValue className(args[0]);
458
    canMessage.setClassName(*className);
459
    canMessage.setClassName(*className);
459
    String::AsciiValue directionFlag(args[1]);
460
    String::AsciiValue directionFlag(args[1]);
460
    canMessage.setDirectionFlag(*directionFlag);
461
    canMessage.setDirectionFlag(*directionFlag);
461
    String::AsciiValue moduleName(args[2]);
462
    String::AsciiValue moduleName(args[2]);
462
    canMessage.setModuleName(*moduleName);
463
    canMessage.setModuleName(*moduleName);
463
    canMessage.setModuleId(args[3]->Uint32Value());
464
    canMessage.setModuleId(args[3]->Uint32Value());
464
    String::AsciiValue commandName(args[4]);
465
    String::AsciiValue commandName(args[4]);
465
    canMessage.setCommandName(*commandName);
466
    canMessage.setCommandName(*commandName);
466
 
467
 
467
    String::AsciiValue dataString(args[5]);
468
    String::AsciiValue dataString(args[5]);
468
 
469
 
469
    vector<string> parts = explode(",", trim(*dataString, ','));
470
    vector<string> parts = explode(",", trim(*dataString, ','));
470
    map<string, CanVariable> data;
471
    map<string, CanVariable> data;
471
 
472
 
472
    for (int n = 0; n < parts.size(); n++)
473
    for (int n = 0; n < parts.size(); n++)
473
    {
474
    {
474
        vector<string> keyAndValue = explode(":", parts[n]);
475
        vector<string> keyAndValue = explode(":", parts[n]);
475
 
476
 
476
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
477
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
477
    }
478
    }
478
 
479
 
479
    canMessage.setData(data);
480
    canMessage.setData(data);
480
   
481
   
481
    canMan.sendMessage(canMessage);
482
    canMan.sendMessage(canMessage);
482
 
483
 
483
    return Undefined();
484
    return Undefined();
484
}
485
}
485
 
486
 
486
Handle<Value> VirtualMachine::_sendCanNMTMessage(const Arguments& args)
487
Handle<Value> VirtualMachine::_sendCanNMTMessage(const Arguments& args)
487
{
488
{
488
    CanNetManager &canMan = CanNetManager::getInstance();
489
    CanNetManager &canMan = CanNetManager::getInstance();
489
 
490
 
490
    CanMessage canMessage;
491
    CanMessage canMessage;
491
 
492
 
492
    String::AsciiValue className(args[0]);
493
    String::AsciiValue className(args[0]);
493
    canMessage.setClassName(*className);
494
    canMessage.setClassName(*className);
494
    String::AsciiValue commandName(args[1]);
495
    String::AsciiValue commandName(args[1]);
495
    canMessage.setCommandName(*commandName);
496
    canMessage.setCommandName(*commandName);
496
 
497
 
497
    String::AsciiValue dataString(args[2]);
498
    String::AsciiValue dataString(args[2]);
498
 
499
 
499
    vector<string> parts = explode(",", trim(*dataString, ','));
500
    vector<string> parts = explode(",", trim(*dataString, ','));
500
    map<string, CanVariable> data;
501
    map<string, CanVariable> data;
501
 
502
 
502
    for (int n = 0; n < parts.size(); n++)
503
    for (int n = 0; n < parts.size(); n++)
503
    {
504
    {
504
        vector<string> keyAndValue = explode(":", parts[n]);
505
        vector<string> keyAndValue = explode(":", parts[n]);
505
 
506
 
506
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
507
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
507
    }
508
    }
508
 
509
 
509
    canMessage.setData(data);
510
    canMessage.setData(data);
510
 
511
 
511
    canMan.sendMessage(canMessage);
512
    canMan.sendMessage(canMessage);
512
 
513
 
513
    return Undefined();
514
    return Undefined();
514
}
515
}
515
 
516
 
516
Handle<Value> VirtualMachine::_loadScript(const Arguments& args)
517
Handle<Value> VirtualMachine::_loadScript(const Arguments& args)
517
{
518
{
518
    VirtualMachine &vm = VirtualMachine::getInstance();
519
    VirtualMachine &vm = VirtualMachine::getInstance();
519
 
520
 
520
    String::AsciiValue str(args[0]);
521
    String::AsciiValue str(args[0]);
521
 
522
 
522
    return Boolean::New(vm.loadScript(*str));
523
    return Boolean::New(vm.loadScript(*str));
523
}
524
}
524
 
525
 
525
Handle<Value> VirtualMachine::_loadDataStore(const Arguments& args)
526
Handle<Value> VirtualMachine::_loadDataStore(const Arguments& args)
526
{
527
{
527
    VirtualMachine &vm = VirtualMachine::getInstance();
528
    VirtualMachine &vm = VirtualMachine::getInstance();
528
 
529
 
529
    String::AsciiValue str(args[0]);
530
    String::AsciiValue str(args[0]);
530
 
531
 
531
    return Boolean::New(vm.loadDataStore(*str));
532
    return Boolean::New(vm.loadDataStore(*str));
532
}
533
}
533
 
534
 
534
Handle<Value> VirtualMachine::_startIntervalThread(const Arguments& args)
535
Handle<Value> VirtualMachine::_startIntervalThread(const Arguments& args)
535
{
536
{
536
    VirtualMachine &vm = VirtualMachine::getInstance();
537
    VirtualMachine &vm = VirtualMachine::getInstance();
537
    return Integer::New(vm.startIntervalThread(args[0]->Uint32Value()));
538
    return Integer::New(vm.startIntervalThread(args[0]->Uint32Value()));
538
}
539
}
539
 
540
 
540
Handle<Value> VirtualMachine::_stopIntervalThread(const Arguments& args)
541
Handle<Value> VirtualMachine::_stopIntervalThread(const Arguments& args)
541
{
542
{
542
    VirtualMachine &vm = VirtualMachine::getInstance();
543
    VirtualMachine &vm = VirtualMachine::getInstance();
543
    return Boolean::New(vm.stopIntervalThread(args[0]->Uint32Value()));
544
    return Boolean::New(vm.stopIntervalThread(args[0]->Uint32Value()));
544
}
545
}
545
 
546
 
546
Handle<Value> VirtualMachine::_setIntervalThreadTimeout(const Arguments& args)
547
Handle<Value> VirtualMachine::_setIntervalThreadTimeout(const Arguments& args)
547
{
548
{
548
    VirtualMachine &vm = VirtualMachine::getInstance();
549
    VirtualMachine &vm = VirtualMachine::getInstance();
549
    return Integer::New(vm.setIntervalThreadTimeout(args[0]->Uint32Value(), args[1]->Uint32Value()));
550
    return Integer::New(vm.setIntervalThreadTimeout(args[0]->Uint32Value(), args[1]->Uint32Value()));
550
}
551
}
551
 
552
 
552
Handle<Value> VirtualMachine::_startSocketThread(const Arguments& args)
553
Handle<Value> VirtualMachine::_startSocketThread(const Arguments& args)
553
{
554
{
554
    VirtualMachine &vm = VirtualMachine::getInstance();
555
    VirtualMachine &vm = VirtualMachine::getInstance();
555
 
556
 
556
    String::AsciiValue address(args[0]);
557
    String::AsciiValue address(args[0]);
557
 
558
 
558
    return Integer::New(vm.startSocketThread(*address, args[1]->Uint32Value(), args[2]->Uint32Value()));
559
    return Integer::New(vm.startSocketThread(*address, args[1]->Uint32Value(), args[2]->Uint32Value()));
559
}
560
}
560
 
561
 
561
Handle<Value> VirtualMachine::_stopSocketThread(const Arguments& args)
562
Handle<Value> VirtualMachine::_stopSocketThread(const Arguments& args)
562
{
563
{
563
    VirtualMachine &vm = VirtualMachine::getInstance();
564
    VirtualMachine &vm = VirtualMachine::getInstance();
564
 
565
 
565
    return Boolean::New(vm.stopSocketThread(args[0]->Uint32Value()));
566
    return Boolean::New(vm.stopSocketThread(args[0]->Uint32Value()));
566
}
567
}
567
 
568
 
568
Handle<Value> VirtualMachine::_sendToSocketThread(const Arguments& args)
569
Handle<Value> VirtualMachine::_sendToSocketThread(const Arguments& args)
569
{
570
{
570
    VirtualMachine &vm = VirtualMachine::getInstance();
571
    VirtualMachine &vm = VirtualMachine::getInstance();
571
 
572
 
572
    String::AsciiValue data(args[1]);
573
    String::AsciiValue data(args[1]);
573
 
574
 
574
    vm.sendToSocketThread(args[0]->Uint32Value(), *data);
575
    vm.sendToSocketThread(args[0]->Uint32Value(), *data);
575
 
576
 
576
    return Undefined();
577
    return Undefined();
577
}
578
}
578
 
579
 
579
Handle<Value> VirtualMachine::_getFileContents(const Arguments& args)
580
Handle<Value> VirtualMachine::_getFileContents(const Arguments& args)
580
{
581
{
581
    String::AsciiValue filename(args[0]);
582
    String::AsciiValue filename(args[0]);
582
 
583
 
583
    if (!file_exists(*filename))
584
    if (!file_exists(*filename))
584
    {
585
    {
585
        return Undefined();
586
        return Undefined();
586
    }
587
    }
587
 
588
 
588
    string content = file_get_contents(*filename);
589
    string content = file_get_contents(*filename);
589
 
590
 
590
    return String::New(content.c_str());
591
    return String::New(content.c_str());
591
}
592
}
592
 
593
 
593
Handle<Value> VirtualMachine::_uint2hex(const Arguments& args)
594
Handle<Value> VirtualMachine::_uint2hex(const Arguments& args)
594
{
595
{
595
    string hex = uint2hex(args[0]->Uint32Value(), args[1]->Uint32Value());
596
    string hex = uint2hex(args[0]->Uint32Value(), args[1]->Uint32Value());
596
    return String::New(hex.c_str());
597
    return String::New(hex.c_str());
597
}
598
}
598
 
599
 
599
Handle<Value> VirtualMachine::_hex2bin(const Arguments& args)
600
Handle<Value> VirtualMachine::_hex2bin(const Arguments& args)
600
{
601
{
601
    String::AsciiValue hex(args[0]);
602
    String::AsciiValue hex(args[0]);
602
    string bin = hex2bin(*hex);
603
    string bin = hex2bin(*hex);
603
    return String::New(bin.c_str());
604
    return String::New(bin.c_str());
604
}
605
}
605
 
606
 
606
Handle<Value> VirtualMachine::_bin2hex(const Arguments& args)
607
Handle<Value> VirtualMachine::_bin2hex(const Arguments& args)
607
{
608
{
608
    String::AsciiValue bin(args[0]);
609
    String::AsciiValue bin(args[0]);
609
    string hex = bin2hex(*bin);
610
    string hex = bin2hex(*bin);
610
    return String::New(hex.c_str());
611
    return String::New(hex.c_str());
611
}
612
}
612
 
613
 
613
Handle<Value> VirtualMachine::_bin2float(const Arguments& args)
614
Handle<Value> VirtualMachine::_bin2float(const Arguments& args)
614
{
615
{
615
    String::AsciiValue bin(args[0]);
616
    String::AsciiValue bin(args[0]);
616
    float f = bin2float(*bin);
617
    float f = bin2float(*bin);
617
    return Number::New(f);
618
    return Number::New(f);
618
}
619
}
619
 
620
 
620
Handle<Value> VirtualMachine::_float2bin(const Arguments& args)
621
Handle<Value> VirtualMachine::_float2bin(const Arguments& args)
621
{
622
{
622
    string bin = float2bin(args[0]->NumberValue(), args[1]->Uint32Value());
623
    string bin = float2bin(args[0]->NumberValue(), args[1]->Uint32Value());
623
    return String::New(bin.c_str());
624
    return String::New(bin.c_str());
624
}
625
}
625
 
626
 
626
Handle<Value> VirtualMachine::_bin2uint(const Arguments& args)
627
Handle<Value> VirtualMachine::_bin2uint(const Arguments& args)
627
{
628
{
628
    String::AsciiValue bin(args[0]);
629
    String::AsciiValue bin(args[0]);
629
    unsigned int num = bin2uint(*bin);
630
    unsigned int num = bin2uint(*bin);
630
    return Number::New(num);
631
    return Number::New(num);
631
}
632
}
632
 
633
 
633
Handle<Value> VirtualMachine::_uint2bin(const Arguments& args)
634
Handle<Value> VirtualMachine::_uint2bin(const Arguments& args)
634
{
635
{
635
    string bin = uint2bin(args[0]->Uint32Value(), args[1]->Uint32Value());
636
    string bin = uint2bin(args[0]->Uint32Value(), args[1]->Uint32Value());
636
    return String::New(bin.c_str());
637
    return String::New(bin.c_str());
637
}
638
}
638
 
639
 
639
Handle<Value> VirtualMachine::_hex2uint(const Arguments& args)
640
Handle<Value> VirtualMachine::_hex2uint(const Arguments& args)
640
{
641
{
641
    String::AsciiValue hex(args[0]);
642
    String::AsciiValue hex(args[0]);
642
    unsigned int num = hex2uint(*hex);
643
    unsigned int num = hex2uint(*hex);
643
    return Number::New(num);
644
    return Number::New(num);
-
 
645
}
-
 
646
 
-
 
647
Handle<Value> VirtualMachine::_sleep(const Arguments& args)
-
 
648
{
-
 
649
    usleep(args[0]->Uint32Value());
-
 
650
    return Undefined();
644
}
651
}
645
 
652