Subversion Repositories HomeAutomation

Rev

Rev 986 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 986 Rev 995
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
    Thread<VirtualMachine>();
47
    Thread<VirtualMachine>();
48
}
48
}
49
 
49
 
50
VirtualMachine::~VirtualMachine()
50
VirtualMachine::~VirtualMachine()
51
{
51
{
52
    stop();
52
    stop();
53
}
53
}
54
 
54
 
55
void VirtualMachine::run()
55
void VirtualMachine::run()
56
{
56
{
57
    SyslogStream &slog = SyslogStream::getInstance();
57
    SyslogStream &slog = SyslogStream::getInstance();
58
 
58
 
59
    string basePath = Settings::get("BasePath") + "Services/";
59
    string basePath = Settings::get("BasePath") + "Services/";
60
    string scriptName = "Base.js";
60
    string scriptName = "Base.js";
61
    string scriptFileName = basePath + "System/" + scriptName;
61
    string scriptFileName = basePath + "System/" + scriptName;
62
 
62
 
63
    if (!file_exists(scriptFileName))
63
    if (!file_exists(scriptFileName))
64
    {
64
    {
65
        slog << "Failed to load :" + scriptFileName + "\n";
65
        slog << "Failed to load :" + scriptFileName + "\n";
66
    }
66
    }
67
 
67
 
68
    string scriptSource = file_get_contents(scriptFileName);
68
    string scriptSource = file_get_contents(scriptFileName);
69
 
69
 
70
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
70
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
71
    //each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
71
    //each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
72
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
72
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
73
 
73
 
74
    // Create a template for the global object.
74
    // Create a template for the global object.
75
    myGlobal = ObjectTemplate::New();
75
    myGlobal = ObjectTemplate::New();
76
 
76
 
77
    //associates "print" on script to the Print function
77
    //associates "print" on script to the Print function
78
    myGlobal->Set(String::New("log"), FunctionTemplate::New(VirtualMachine_log));
78
    myGlobal->Set(String::New("log"), FunctionTemplate::New(VirtualMachine_log));
79
    myGlobal->Set(String::New("sendCanMessage"), FunctionTemplate::New(VirtualMachine_sendCanMessage));
79
    myGlobal->Set(String::New("sendCanMessage"), FunctionTemplate::New(VirtualMachine_sendCanMessage));
80
    myGlobal->Set(String::New("sendCanNMTMessage"), FunctionTemplate::New(VirtualMachine_sendCanNMTMessage));
80
    myGlobal->Set(String::New("sendCanNMTMessage"), FunctionTemplate::New(VirtualMachine_sendCanNMTMessage));
81
    myGlobal->Set(String::New("loadScript"), FunctionTemplate::New(VirtualMachine_loadScript));
81
    myGlobal->Set(String::New("loadScript"), FunctionTemplate::New(VirtualMachine_loadScript));
82
    myGlobal->Set(String::New("startIntervalThread"), FunctionTemplate::New(VirtualMachine_startIntervalThread));
82
    myGlobal->Set(String::New("startIntervalThread"), FunctionTemplate::New(VirtualMachine_startIntervalThread));
83
    myGlobal->Set(String::New("stopIntervalThread"), FunctionTemplate::New(VirtualMachine_stopIntervalThread));
83
    myGlobal->Set(String::New("stopIntervalThread"), FunctionTemplate::New(VirtualMachine_stopIntervalThread));
84
    myGlobal->Set(String::New("startSocketThread"), FunctionTemplate::New(VirtualMachine_startSocketThread));
84
    myGlobal->Set(String::New("startSocketThread"), FunctionTemplate::New(VirtualMachine_startSocketThread));
85
    myGlobal->Set(String::New("stopSocketThread"), FunctionTemplate::New(VirtualMachine_stopSocketThread));
85
    myGlobal->Set(String::New("stopSocketThread"), FunctionTemplate::New(VirtualMachine_stopSocketThread));
86
    myGlobal->Set(String::New("sendToSocketThread"), FunctionTemplate::New(VirtualMachine_sendToSocketThread));
86
    myGlobal->Set(String::New("sendToSocketThread"), FunctionTemplate::New(VirtualMachine_sendToSocketThread));
87
    myGlobal->Set(String::New("uint2hex"), FunctionTemplate::New(VirtualMachine_uint2hex));
87
    myGlobal->Set(String::New("uint2hex"), FunctionTemplate::New(VirtualMachine_uint2hex));
88
 
88
 
89
    //create context for the script
89
    //create context for the script
90
    myContext = Context::New(NULL, myGlobal);
90
    myContext = Context::New(NULL, myGlobal);
91
 
91
 
92
 
92
 
93
    //access global context within this scope
93
    //access global context within this scope
94
    Context::Scope context_scope(myContext);
94
    Context::Scope context_scope(myContext);
95
    //exception handler
95
    //exception handler
96
    TryCatch try_catch;
96
    TryCatch tryCatch;
97
    //compile script to binary code - JIT
97
    //compile script to binary code - JIT
98
    Handle<Script> script = Script::Compile(source, name);
98
    Handle<Script> script = Script::Compile(source, name);
99
 
99
 
100
    //check if we got problems on compilation
100
    //check if we got problems on compilation
101
    if (script.IsEmpty())
101
    if (script.IsEmpty())
102
    {
102
    {
103
 
-
 
104
        // Print errors that happened during compilation.
-
 
105
        String::AsciiValue error(try_catch.Exception());
103
        printException(&tryCatch);
106
        string sError = *error;
104
        slog << "\n";
107
        slog << "Failed to compile script: " + sError + "\n";
105
        return;
108
    }
106
    }
109
    else
107
    else
110
    {
108
    {
111
        //no errors , let's continue
109
        //no errors , let's continue
112
        Handle<Value> result = script->Run();
110
        Handle<Value> result = script->Run();
113
 
111
 
114
        //check if execution ended with errors
112
        //check if execution ended with errors
115
        if (result.IsEmpty())
113
        if (result.IsEmpty())
116
        {
114
        {
117
            // Print errors that happened during execution.
-
 
118
            String::AsciiValue error(try_catch.Exception());
115
            printException(&tryCatch);
119
            string sError = *error;
116
            slog << "\n";
120
            slog << "Constructor: Failed to run script: " << sError << "\n";
117
            return;
121
        }
118
        }
122
        else
119
        else
123
        {
120
        {
124
            loadScript("System/Startup.js");
121
            loadScript("System/Startup.js");
125
 
122
 
126
            if (file_exists(basePath + "Autostart.js"))
123
            if (file_exists(basePath + "Autostart.js"))
127
            {
124
            {
128
                loadScript("Autostart.js");
125
                loadScript("Autostart.js");
129
            }
126
            }
130
           
127
           
131
            myFunctionHandleNMTMessage = Handle<Function>::Cast(myContext->Global()->Get(String::New("handleNMTMessage")));
128
            myFunctionHandleNMTMessage = Handle<Function>::Cast(myContext->Global()->Get(String::New("handleNMTMessage")));
132
            myFunctionOfflineCheck = Handle<Function>::Cast(myContext->Global()->Get(String::New("offlineCheck")));
129
            myFunctionOfflineCheck = Handle<Function>::Cast(myContext->Global()->Get(String::New("offlineCheck")));
133
            myFunctionHandleMessage = Handle<Function>::Cast(myContext->Global()->Get(String::New("handleMessage")));
130
            myFunctionHandleMessage = Handle<Function>::Cast(myContext->Global()->Get(String::New("handleMessage")));
134
            myFunctionStartup = Handle<Function>::Cast(myContext->Global()->Get(String::New("startup")));
131
            myFunctionStartup = Handle<Function>::Cast(myContext->Global()->Get(String::New("startup")));
135
        }
132
        }
136
    }
133
    }
137
 
134
 
138
    const int argc = 0;
135
    const int argc = 0;
139
    Handle<Value> argv[argc] = { };
136
    Handle<Value> argv[argc] = { };
140
 
137
 
141
    Handle<Value> result = myFunctionStartup->Call(myFunctionStartup, argc, argv); // argc and argv are your standard arguments to a function
138
    Handle<Value> result = myFunctionStartup->Call(myFunctionStartup, argc, argv); // argc and argv are your standard arguments to a function
142
 
139
 
143
    mySemaphore.lock();
140
    mySemaphore.lock();
144
 
141
 
145
    while (1)
142
    while (1)
146
    {
143
    {
147
        string expression;
144
        string expression;
148
 
145
 
149
        while (myExpressions.size() > 0)
146
        while (myExpressions.size() > 0)
150
        {
147
        {
151
            expression = myExpressions.pop();
148
            expression = myExpressions.pop();
152
 
149
 
153
            runExpression(expression);
150
            runExpression(expression);
154
        }
151
        }
155
 
152
 
156
        CanMessage canMessage;
153
        CanMessage canMessage;
157
 
154
 
158
        while (myCanMessages.size() > 0)
155
        while (myCanMessages.size() > 0)
159
        {
156
        {
160
            canMessage = myCanMessages.pop();
157
            canMessage = myCanMessages.pop();
161
 
158
 
162
            if (canMessage.getClassName() == "nmt")
159
            if (canMessage.getClassName() == "nmt")
163
            {
160
            {
164
                callHandleNMTMessage(canMessage);
161
                callHandleNMTMessage(canMessage);
165
            }
162
            }
166
            else
163
            else
167
            {
164
            {
168
                callHandleMessage(canMessage);
165
                callHandleMessage(canMessage);
169
            }
166
            }
170
        }
167
        }
171
 
168
 
172
        mySemaphore.wait();
169
        mySemaphore.wait();
173
    }
170
    }
174
 
171
 
175
    mySemaphore.unlock();
172
    mySemaphore.unlock();
176
}
173
}
177
 
174
 
178
void VirtualMachine::queueCanMessage(CanMessage canMessage)
175
void VirtualMachine::queueCanMessage(CanMessage canMessage)
179
{
176
{
180
    myCanMessages.push(canMessage);
177
    myCanMessages.push(canMessage);
181
    mySemaphore.broadcast();
178
    mySemaphore.broadcast();
182
}
179
}
183
 
180
 
184
void VirtualMachine::queueExpression(string expression)
181
void VirtualMachine::queueExpression(string expression)
185
{
182
{
186
    myExpressions.push(expression);
183
    myExpressions.push(expression);
187
    mySemaphore.broadcast();
184
    mySemaphore.broadcast();
188
}
185
}
189
 
186
 
190
bool VirtualMachine::loadScript(string scriptName)
187
bool VirtualMachine::loadScript(string scriptName)
191
{
188
{
192
    SyslogStream &slog = SyslogStream::getInstance();
189
    SyslogStream &slog = SyslogStream::getInstance();
193
 
190
 
194
    string basePath = Settings::get("BasePath") + "Services/";
191
    string basePath = Settings::get("BasePath") + "Services/";
195
    string scriptFileName = basePath + scriptName;
192
    string scriptFileName = basePath + scriptName;
196
 
193
 
197
    if (!file_exists(scriptFileName))
194
    if (!file_exists(scriptFileName))
198
    {
195
    {
199
        slog << "Failed to load " + scriptFileName + "\n";
196
        slog << "Failed to load " + scriptFileName + "\n";
200
        return false;
197
        return false;
201
    }
198
    }
202
 
-
 
203
    string scriptSource = file_get_contents(scriptFileName);
-
 
204
 
-
 
205
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
-
 
206
    //each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
-
 
207
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
-
 
208
 
-
 
209
    //access global context within this scope
-
 
210
    Context::Scope context_scope(myContext);
-
 
211
    //exception handler
-
 
212
    TryCatch try_catch;
-
 
213
    //compile script to binary code - JIT
-
 
214
    Handle<Script> script = Script::Compile(source, name);
-
 
215
 
-
 
216
    //check if we got problems on compilation
-
 
217
    if (script.IsEmpty())
-
 
218
    {
-
 
219
        // Print errors that happened during compilation.
-
 
220
        String::AsciiValue error(try_catch.Exception());
-
 
221
        string sError = *error;
-
 
222
        slog << "loadScript: Failed to compile script: " + sError + "\n";
-
 
223
        return false;
-
 
224
    }
-
 
225
    else
-
 
226
    {
-
 
227
        //no errors , let's continue
-
 
228
        Handle<Value> result = script->Run();
-
 
229
 
-
 
230
        //check if execution ended with errors
-
 
231
        if (result.IsEmpty())
-
 
232
        {
-
 
233
            // Print errors that happened during execution.
-
 
234
            String::AsciiValue error(try_catch.Exception());
-
 
235
            string sError = *error;
-
 
236
            slog << "loadScript: Failed to run script: " + sError + "\n";
-
 
237
            return false;
-
 
238
        }
-
 
239
 
199
 
-
 
200
    string scriptSource = file_get_contents(scriptFileName);
-
 
201
 
-
 
202
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
-
 
203
    //each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
-
 
204
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
-
 
205
 
-
 
206
    //access global context within this scope
-
 
207
    Context::Scope context_scope(myContext);
-
 
208
    //exception handler
-
 
209
    TryCatch tryCatch;
-
 
210
    //compile script to binary code - JIT
-
 
211
    Handle<Script> script = Script::Compile(source, name);
-
 
212
 
-
 
213
    //check if we got problems on compilation
-
 
214
    if (script.IsEmpty())
-
 
215
    {
-
 
216
        printException(&tryCatch);
-
 
217
        slog << "\n";
-
 
218
        return false;
-
 
219
    }
-
 
220
    else
-
 
221
    {
-
 
222
        //no errors , let's continue
-
 
223
        Handle<Value> result = script->Run();
-
 
224
 
-
 
225
        //check if execution ended with errors
-
 
226
        if (result.IsEmpty())
-
 
227
        {
-
 
228
            printException(&tryCatch);
-
 
229
            slog << "\n";
-
 
230
            return false;
-
 
231
        }
-
 
232
 
240
        slog << "Loaded " + scriptName + "\n";
233
        slog << "Loaded " + scriptName + "\n";
241
    }
234
    }
242
 
235
 
243
    return true;
236
    return true;
244
}
237
}
245
 
238
 
246
void VirtualMachine::callHandleNMTMessage(CanMessage canMessage)
239
void VirtualMachine::callHandleNMTMessage(CanMessage canMessage)
247
{
240
{
248
    const int argc = 3;
241
    const int argc = 3;
249
 
242
 
250
    string jsonData = canMessage.getJSONData();
243
    string jsonData = canMessage.getJSONData();
251
 
244
 
252
    Handle<Value> argv[argc] = {String::New(canMessage.getClassName().c_str()),
245
    Handle<Value> argv[argc] = {String::New(canMessage.getClassName().c_str()),
253
                                String::New(canMessage.getCommandName().c_str()),
246
                                String::New(canMessage.getCommandName().c_str()),
254
                                String::New(jsonData.c_str()) };
247
                                String::New(jsonData.c_str()) };
255
 
248
 
256
    Handle<Value> result = myFunctionHandleNMTMessage->Call(myFunctionHandleNMTMessage, argc, argv); // argc and argv are your standard arguments to a function
249
    Handle<Value> result = myFunctionHandleNMTMessage->Call(myFunctionHandleNMTMessage, argc, argv); // argc and argv are your standard arguments to a function
257
}
250
}
258
 
251
 
259
void VirtualMachine::callHandleMessage(CanMessage canMessage)
252
void VirtualMachine::callHandleMessage(CanMessage canMessage)
260
{
253
{
261
    const int argc = 6;
254
    const int argc = 6;
262
 
255
 
263
    string jsonData = canMessage.getJSONData();
256
    string jsonData = canMessage.getJSONData();
264
 
257
 
265
    Handle<Value> argv[argc] = {String::New(canMessage.getClassName().c_str()),
258
    Handle<Value> argv[argc] = {String::New(canMessage.getClassName().c_str()),
266
                                String::New(canMessage.getDirectionFlag().c_str()),
259
                                String::New(canMessage.getDirectionFlag().c_str()),
267
                                String::New(canMessage.getModuleName().c_str()),
260
                                String::New(canMessage.getModuleName().c_str()),
268
                                Integer::New(canMessage.getModuleId()),
261
                                Integer::New(canMessage.getModuleId()),
269
                                String::New(canMessage.getCommandName().c_str()),
262
                                String::New(canMessage.getCommandName().c_str()),
270
                                String::New(jsonData.c_str()) };
263
                                String::New(jsonData.c_str()) };
271
 
264
 
272
    Handle<Value> result = myFunctionHandleMessage->Call(myFunctionHandleMessage, argc, argv); // argc and argv are your standard arguments to a function
265
    Handle<Value> result = myFunctionHandleMessage->Call(myFunctionHandleMessage, argc, argv); // argc and argv are your standard arguments to a function
273
}
266
}
274
 
267
 
275
unsigned int VirtualMachine::startIntervalThread(unsigned int timeout)
268
unsigned int VirtualMachine::startIntervalThread(unsigned int timeout)
276
{
269
{
277
    IntervalThread intervalThread(timeout);
270
    IntervalThread intervalThread(timeout);
278
 
271
 
279
    myIntervalThreads[intervalThread.getId()] = intervalThread;
272
    myIntervalThreads[intervalThread.getId()] = intervalThread;
280
    myIntervalThreads[intervalThread.getId()].start();
273
    myIntervalThreads[intervalThread.getId()].start();
281
 
274
 
282
    return intervalThread.getId();
275
    return intervalThread.getId();
283
}
276
}
284
 
277
 
285
bool VirtualMachine::stopIntervalThread(unsigned int id)
278
bool VirtualMachine::stopIntervalThread(unsigned int id)
286
{
279
{
287
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
280
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
288
    {
281
    {
289
        myIntervalThreads.erase(id);
282
        myIntervalThreads.erase(id);
290
        return true;
283
        return true;
291
    }
284
    }
292
 
285
 
293
    return false;
286
    return false;
294
}
287
}
295
 
288
 
296
unsigned int VirtualMachine::startSocketThread(string address, int port, unsigned int reconnectTimeout)
289
unsigned int VirtualMachine::startSocketThread(string address, int port, unsigned int reconnectTimeout)
297
{
290
{
298
    SocketThread *socketThread = new SocketThread(address, port, reconnectTimeout);
291
    SocketThread *socketThread = new SocketThread(address, port, reconnectTimeout);
299
    mySocketThreads[socketThread->getId()] = socketThread;
292
    mySocketThreads[socketThread->getId()] = socketThread;
300
    mySocketThreads[socketThread->getId()]->start();
293
    mySocketThreads[socketThread->getId()]->start();
301
 
294
 
302
    return socketThread->getId();
295
    return socketThread->getId();
303
}
296
}
304
 
297
 
305
bool VirtualMachine::stopSocketThread(unsigned int id)
298
bool VirtualMachine::stopSocketThread(unsigned int id)
306
{
299
{
307
   
300
   
308
 
301
 
309
    if (mySocketThreads.find(id) != mySocketThreads.end())
302
    if (mySocketThreads.find(id) != mySocketThreads.end())
310
    {
303
    {
311
        //mySocketThreads[id]->stop();
304
        //mySocketThreads[id]->stop();
312
        delete mySocketThreads[id];
305
        delete mySocketThreads[id];
313
 
306
 
314
        mySocketThreads.erase(id);
307
        mySocketThreads.erase(id);
315
        return true;
308
        return true;
316
    }
309
    }
317
 
310
 
318
    return false;
311
    return false;
319
}
312
}
320
 
313
 
321
void VirtualMachine::sendToSocketThread(unsigned int id, string data)
314
void VirtualMachine::sendToSocketThread(unsigned int id, string data)
322
{
315
{
323
    if (mySocketThreads.find(id) != mySocketThreads.end())
316
    if (mySocketThreads.find(id) != mySocketThreads.end())
324
    {
317
    {
325
        mySocketThreads[id]->send(data);
318
        mySocketThreads[id]->send(data);
326
    }
319
    }
327
}
320
}
328
 
321
 
329
bool VirtualMachine::runExpression(string expression)
322
bool VirtualMachine::runExpression(string expression)
330
{
323
{
331
    SyslogStream &slog = SyslogStream::getInstance();
324
    SyslogStream &slog = SyslogStream::getInstance();
332
 
325
 
333
    string scriptName = "runExpression";
326
    string scriptName = "runExpression";
334
 
327
 
335
    Handle<String> source =  String::New(expression.c_str(), expression.length());
328
    Handle<String> source =  String::New(expression.c_str(), expression.length());
336
    //each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
329
    //each script name must be unique , for this demo I just run one embedded script, so the name can be fixed
337
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
330
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
338
 
331
 
339
    //access global context within this scope
332
    //access global context within this scope
340
    Context::Scope context_scope(myContext);
333
    Context::Scope context_scope(myContext);
341
    //exception handler
334
    //exception handler
342
    TryCatch try_catch;
335
    TryCatch tryCatch;
343
    //compile script to binary code - JIT
336
    //compile script to binary code - JIT
344
    Handle<Script> script = Script::Compile(source, name);
337
    Handle<Script> script = Script::Compile(source, name);
345
 
338
 
346
    //check if we got problems on compilation
339
    //check if we got problems on compilation
347
    if (script.IsEmpty())
340
    if (script.IsEmpty())
348
    {
341
    {
349
        // Print errors that happened during compilation.
-
 
350
        String::AsciiValue error(try_catch.Exception());
-
 
351
        string sError = *error;
342
        printException(&tryCatch);
352
        slog << "runExpression: Failed to compile script: " + sError + "\n";
-
 
353
        slog << expression << "\n\n";
343
        slog << "\n";
354
        return false;
344
        return false;
355
    }
345
    }
356
    else
346
    else
357
    {
347
    {
358
        //no errors , let's continue
348
        //no errors , let's continue
359
        Handle<Value> result = script->Run();
349
        Handle<Value> result = script->Run();
360
 
350
 
361
        //check if execution ended with errors
351
        //check if execution ended with errors
362
        if (result.IsEmpty())
352
        if (result.IsEmpty())
363
        {
353
        {
364
            // Print errors that happened during execution.
-
 
365
            String::AsciiValue error(try_catch.Exception());
354
            printException(&tryCatch);
366
            string sError = *error;
355
            slog << "\n";
367
            slog << "runExpression: Failed to run script: " + sError + "\n";
-
 
368
            return false;
356
            return false;
369
        }
357
        }
370
    }
358
    }
371
 
359
 
372
    return true;
360
    return true;
373
}
361
}
-
 
362
 
-
 
363
void VirtualMachine::printException(TryCatch* tryCatch)
-
 
364
{
-
 
365
    SyslogStream &slog = SyslogStream::getInstance();
-
 
366
 
-
 
367
    HandleScope handle_scope;
-
 
368
    String::Utf8Value exception(tryCatch->Exception());
-
 
369
    Handle<v8::Message> message = tryCatch->Message();
-
 
370
 
-
 
371
    string strException = *exception;
-
 
372
 
-
 
373
    if (message.IsEmpty())
-
 
374
    {
-
 
375
        // V8 didn't provide any extra information about this error; just print the exception.
-
 
376
        slog << strException + "\n";
-
 
377
    }
-
 
378
    else
-
 
379
    {
-
 
380
        // Print (filename):(line number): (message).
-
 
381
        String::Utf8Value filename(message->GetScriptResourceName());
-
 
382
        int linenum = message->GetLineNumber();
-
 
383
 
-
 
384
        string strFilename = *filename;
-
 
385
       
-
 
386
        slog << strFilename + ":" + itos(linenum) + ": " + strException + "\n";
-
 
387
 
-
 
388
        // Print line of source code.
-
 
389
        String::Utf8Value sourceline(message->GetSourceLine());
-
 
390
 
-
 
391
        string strSourceline = *sourceline;
-
 
392
 
-
 
393
        slog << strSourceline + "\n";
-
 
394
 
-
 
395
        string underline;
-
 
396
        // Print wavy underline (GetUnderline is deprecated).
-
 
397
        int start = message->GetStartColumn();
-
 
398
        for (int i = 0; i < start; i++)
-
 
399
        {
-
 
400
            underline += " ";
-
 
401
        }
-
 
402
 
-
 
403
        int end = message->GetEndColumn();
-
 
404
        for (int i = start; i < end; i++)
-
 
405
        {
-
 
406
            underline += "^";
-
 
407
        }
-
 
408
 
-
 
409
        slog << underline + "\n";
-
 
410
    }
-
 
411
}
-
 
412
 
374
 
413
 
375
Handle<Value> VirtualMachine_log(const Arguments& args)
414
Handle<Value> VirtualMachine_log(const Arguments& args)
376
{
415
{
377
    SyslogStream &slog = SyslogStream::getInstance();
416
    SyslogStream &slog = SyslogStream::getInstance();
378
 
417
 
379
    String::AsciiValue str(args[0]);
418
    String::AsciiValue str(args[0]);
380
 
419
 
381
    slog << *str;
420
    slog << *str;
382
 
421
 
383
    return Undefined();
422
    return Undefined();
384
}
423
}
385
 
424
 
386
Handle<Value> VirtualMachine_sendCanMessage(const Arguments& args)
425
Handle<Value> VirtualMachine_sendCanMessage(const Arguments& args)
387
{
426
{
388
    //SyslogStream &slog = SyslogStream::getInstance();
427
    //SyslogStream &slog = SyslogStream::getInstance();
389
    CanNetManager &canMan = CanNetManager::getInstance();
428
    CanNetManager &canMan = CanNetManager::getInstance();
390
 
429
 
391
    CanMessage canMessage;
430
    CanMessage canMessage;
392
 
431
 
393
    String::AsciiValue className(args[0]);
432
    String::AsciiValue className(args[0]);
394
    canMessage.setClassName(*className);
433
    canMessage.setClassName(*className);
395
    String::AsciiValue directionFlag(args[1]);
434
    String::AsciiValue directionFlag(args[1]);
396
    canMessage.setDirectionFlag(*directionFlag);
435
    canMessage.setDirectionFlag(*directionFlag);
397
    String::AsciiValue moduleName(args[2]);
436
    String::AsciiValue moduleName(args[2]);
398
    canMessage.setModuleName(*moduleName);
437
    canMessage.setModuleName(*moduleName);
399
    canMessage.setModuleId(args[3]->Uint32Value());
438
    canMessage.setModuleId(args[3]->Uint32Value());
400
    String::AsciiValue commandName(args[4]);
439
    String::AsciiValue commandName(args[4]);
401
    canMessage.setCommandName(*commandName);
440
    canMessage.setCommandName(*commandName);
402
 
441
 
403
    String::AsciiValue dataString(args[5]);
442
    String::AsciiValue dataString(args[5]);
404
 
443
 
405
    vector<string> parts = explode(",", trim(*dataString, ','));
444
    vector<string> parts = explode(",", trim(*dataString, ','));
406
    map<string, CanVariable> data;
445
    map<string, CanVariable> data;
407
 
446
 
408
    for (int n = 0; n < parts.size(); n++)
447
    for (int n = 0; n < parts.size(); n++)
409
    {
448
    {
410
        vector<string> keyAndValue = explode(":", parts[n]);
449
        vector<string> keyAndValue = explode(":", parts[n]);
411
 
450
 
412
        //string key = trim(keyAndValue[0], ' ');
451
        //string key = trim(keyAndValue[0], ' ');
413
        //string value = trim(keyAndValue[1], ' ');
452
        //string value = trim(keyAndValue[1], ' ');
414
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
453
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
415
    }
454
    }
416
 
455
 
417
    canMessage.setData(data);
456
    canMessage.setData(data);
418
   
457
   
419
    canMan.sendMessage(canMessage);
458
    canMan.sendMessage(canMessage);
420
 
459
 
421
    return Undefined();
460
    return Undefined();
422
}
461
}
423
 
462
 
424
Handle<Value> VirtualMachine_sendCanNMTMessage(const Arguments& args)
463
Handle<Value> VirtualMachine_sendCanNMTMessage(const Arguments& args)
425
{
464
{
426
    //SyslogStream &slog = SyslogStream::getInstance();
465
    //SyslogStream &slog = SyslogStream::getInstance();
427
    CanNetManager &canMan = CanNetManager::getInstance();
466
    CanNetManager &canMan = CanNetManager::getInstance();
428
 
467
 
429
    CanMessage canMessage;
468
    CanMessage canMessage;
430
 
469
 
431
    String::AsciiValue className(args[0]);
470
    String::AsciiValue className(args[0]);
432
    canMessage.setClassName(*className);
471
    canMessage.setClassName(*className);
433
    String::AsciiValue commandName(args[1]);
472
    String::AsciiValue commandName(args[1]);
434
    canMessage.setCommandName(*commandName);
473
    canMessage.setCommandName(*commandName);
435
 
474
 
436
    String::AsciiValue dataString(args[2]);
475
    String::AsciiValue dataString(args[2]);
437
 
476
 
438
    vector<string> parts = explode(",", trim(*dataString, ','));
477
    vector<string> parts = explode(",", trim(*dataString, ','));
439
    map<string, CanVariable> data;
478
    map<string, CanVariable> data;
440
 
479
 
441
    for (int n = 0; n < parts.size(); n++)
480
    for (int n = 0; n < parts.size(); n++)
442
    {
481
    {
443
        vector<string> keyAndValue = explode(":", parts[n]);
482
        vector<string> keyAndValue = explode(":", parts[n]);
444
 
483
 
445
        //string key = trim(keyAndValue[0], ' ');
484
        //string key = trim(keyAndValue[0], ' ');
446
        //string value = trim(keyAndValue[1], ' ');
485
        //string value = trim(keyAndValue[1], ' ');
447
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
486
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
448
    }
487
    }
449
 
488
 
450
    canMessage.setData(data);
489
    canMessage.setData(data);
451
 
490
 
452
    canMan.sendMessage(canMessage);
491
    canMan.sendMessage(canMessage);
453
 
492
 
454
    return Undefined();
493
    return Undefined();
455
}
494
}
456
 
495
 
457
Handle<Value> VirtualMachine_loadScript(const Arguments& args)
496
Handle<Value> VirtualMachine_loadScript(const Arguments& args)
458
{
497
{
459
    VirtualMachine &vm = VirtualMachine::getInstance();
498
    VirtualMachine &vm = VirtualMachine::getInstance();
460
 
499
 
461
    String::AsciiValue str(args[0]);
500
    String::AsciiValue str(args[0]);
462
 
501
 
463
    return Boolean::New(vm.loadScript(*str));
502
    return Boolean::New(vm.loadScript(*str));
464
}
503
}
465
 
504
 
466
Handle<Value> VirtualMachine_startIntervalThread(const Arguments& args)
505
Handle<Value> VirtualMachine_startIntervalThread(const Arguments& args)
467
{
506
{
468
    VirtualMachine &vm = VirtualMachine::getInstance();
507
    VirtualMachine &vm = VirtualMachine::getInstance();
469
 
508
 
470
    unsigned int timeout = args[0]->Uint32Value();
509
    unsigned int timeout = args[0]->Uint32Value();
471
 
510
 
472
    return Integer::New(vm.startIntervalThread(timeout));
511
    return Integer::New(vm.startIntervalThread(timeout));
473
}
512
}
474
 
513
 
475
Handle<Value> VirtualMachine_stopIntervalThread(const Arguments& args)
514
Handle<Value> VirtualMachine_stopIntervalThread(const Arguments& args)
476
{
515
{
477
    VirtualMachine &vm = VirtualMachine::getInstance();
516
    VirtualMachine &vm = VirtualMachine::getInstance();
478
 
517
 
479
    unsigned int id = args[0]->Uint32Value();
518
    unsigned int id = args[0]->Uint32Value();
480
 
519
 
481
    return Boolean::New(vm.stopIntervalThread(id));
520
    return Boolean::New(vm.stopIntervalThread(id));
482
}
521
}
483
 
522
 
484
Handle<Value> VirtualMachine_startSocketThread(const Arguments& args)
523
Handle<Value> VirtualMachine_startSocketThread(const Arguments& args)
485
{
524
{
486
    VirtualMachine &vm = VirtualMachine::getInstance();
525
    VirtualMachine &vm = VirtualMachine::getInstance();
487
 
526
 
488
    String::AsciiValue address(args[0]);
527
    String::AsciiValue address(args[0]);
489
    int port = args[1]->Uint32Value();
528
    int port = args[1]->Uint32Value();
490
    unsigned int reconnectTimeout = args[2]->Uint32Value();
529
    unsigned int reconnectTimeout = args[2]->Uint32Value();
491
 
530
 
492
    return Integer::New(vm.startSocketThread(*address, port, reconnectTimeout));
531
    return Integer::New(vm.startSocketThread(*address, port, reconnectTimeout));
493
}
532
}
494
 
533
 
495
Handle<Value> VirtualMachine_stopSocketThread(const Arguments& args)
534
Handle<Value> VirtualMachine_stopSocketThread(const Arguments& args)
496
{
535
{
497
    VirtualMachine &vm = VirtualMachine::getInstance();
536
    VirtualMachine &vm = VirtualMachine::getInstance();
498
 
537
 
499
    unsigned int id = args[0]->Uint32Value();
538
    unsigned int id = args[0]->Uint32Value();
500
 
539
 
501
    return Boolean::New(vm.stopSocketThread(id));
540
    return Boolean::New(vm.stopSocketThread(id));
502
}
541
}
503
 
542
 
504
Handle<Value> VirtualMachine_sendToSocketThread(const Arguments& args)
543
Handle<Value> VirtualMachine_sendToSocketThread(const Arguments& args)
505
{
544
{
506
    VirtualMachine &vm = VirtualMachine::getInstance();
545
    VirtualMachine &vm = VirtualMachine::getInstance();
507
 
546
 
508
    unsigned int id = args[0]->Uint32Value();
547
    unsigned int id = args[0]->Uint32Value();
509
    String::AsciiValue data(args[1]);
548
    String::AsciiValue data(args[1]);
510
 
549
 
511
    vm.sendToSocketThread(id, *data);
550
    vm.sendToSocketThread(id, *data);
512
 
551
 
513
    return Undefined();
552
    return Undefined();
514
}
553
}
515
 
554
 
516
Handle<Value> VirtualMachine_uint2hex(const Arguments& args)
555
Handle<Value> VirtualMachine_uint2hex(const Arguments& args)
517
{
556
{
518
    VirtualMachine &vm = VirtualMachine::getInstance();
557
    VirtualMachine &vm = VirtualMachine::getInstance();
519
 
558
 
520
    unsigned int id = args[0]->Uint32Value();
559
    unsigned int id = args[0]->Uint32Value();
521
    unsigned int length = args[1]->Uint32Value();
560
    unsigned int length = args[1]->Uint32Value();
522
    string hexId = uint2hex(id, length);
561
    string hexId = uint2hex(id, length);
523
 
562
 
524
    return String::New(hexId.c_str());
563
    return String::New(hexId.c_str());
525
}
564
}
526
 
565
 
527
 
566