OSDN Git Service

[dennco] Implemented the plugin feature.
[dennco/dennco.git] / Source / layer3 / QtScript / dnqscellcode.cpp
1 //  Copyright (c) 2012 Dennco Project
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 //
17 //  Created by tkawata on 2/22/2012.
18 //
19 #include "dnqscellcode.h"
20
21 #include "DNUtils.h"
22 #include "TKLog.h"
23 #include "TKContainer.h"
24 #include "dnqscontainer.h"
25 #include "dnqscellbase.h"
26 #include "dnqscellcodeinstance.h"
27 #include "DNGlobal.h"
28
29 #include <QStringList>
30
31 DNQSCellCode::DNQSCellCode(std::string name, std::string cellapi, DNQSContainer *container, std::string code):
32     TKCellCode(name,cellapi), mCellContainer(container)
33 {
34     std::string jname = getJSEscapeString(name.c_str());
35     QString stmt = QString::fromStdString(parseCellCodeForScriptEngine(jname, code));
36
37     QScriptEngine *scriptEngine = mCellContainer->getScriptEngine();
38     QScriptValue  scriptGlobalObject = mCellContainer->getScriptGlobalObject();
39     scriptEngine->evaluate(QScriptProgram(stmt));
40     if (scriptEngine->hasUncaughtException())
41     {
42         QScriptValue error = scriptEngine->uncaughtException();
43         int lineNumber = scriptEngine->uncaughtExceptionLineNumber();
44         QStringList list = stmt.split("\n", QString::KeepEmptyParts);
45         QString errorStatement = "";
46         if (lineNumber <= list.length())
47         {
48             int i = lineNumber < 2 ? 0 : lineNumber - 2;
49             int j = i + 2 <= list.length() ? i + 2 : list.length() - 1;
50             while (i <= j)
51             {
52                 errorStatement += list.at(i);
53                 errorStatement += "\n";
54                 i++;
55             }
56         }
57         QString errorString = error.toString();
58         scriptEngine->clearExceptions();
59
60         std::string message = "Failed to construct Cell code : ";
61         message += getFQNName();
62         message += "\n";
63         if (errorStatement.length()>0)
64         {
65             message += ("Statement:\n...\n");
66             message += errorStatement.toStdString();
67             message += "...\n";
68         }
69         message += "Error Message:";
70         message += errorString.toStdString();
71         dnNotifyError("Initialization failed", message);
72         return;
73     }
74
75     mCellCodeConstructor = scriptGlobalObject.property(QString::fromStdString(jname), QScriptValue::ResolveLocal);
76     if (mCellCodeConstructor.isNull() || mCellCodeConstructor.isUndefined() || ! mCellCodeConstructor.isValid())
77     {
78         std::string message = "Failed to construct Cell code : ";
79         message.append(getFQNName()).append("\n");
80         message.append("The constructor is invalid.");
81         dnNotifyError("Initialization failed", message);
82         return;
83     }
84 }
85
86 DNQSCellCode::~DNQSCellCode()
87 {
88
89 }
90 TKCellCodeInstance* DNQSCellCode::createCellCodeInstance(TKCell *owner, const void *data)
91 {
92     if (!mCellContainer)
93     {
94         return NULL;
95     }
96     if (mCellCodeConstructor.isNull() || mCellCodeConstructor.isUndefined() || ! mCellCodeConstructor.isValid())
97     {
98         std::string message = "Failed to construct Cell code '";
99         message.append(owner->getName());
100         message.append("'  cellcode:");
101         message.append(getFQNName()).append("\n");
102         message.append("Cell code invalid");
103         dnNotifyError("Initialization failed", message);
104         return NULL;
105     }
106
107     TKCellCodeInstance *result = NULL;
108     QScriptEngine *scriptEngine = mCellContainer->getScriptEngine();
109
110     QScriptValueList args;
111     args << ((DNQSCellBase*)owner)->getCellAPI();
112     QScriptValue instance = mCellCodeConstructor.construct(args);
113     if (scriptEngine->hasUncaughtException())
114     {
115         QScriptValue error = scriptEngine->uncaughtException();
116         QString errorString = error.toString();
117         scriptEngine->clearExceptions();
118
119         std::string message = "Failed to construct Cell code '";
120         message.append(owner->getName()).append("'\n");
121         message.append("cellcode:");
122         message.append(getFQNName()).append("\n");
123         message.append("Error Message:").append(errorString.toStdString());
124         dnNotifyError("Initialization failed", message);
125         return NULL;
126     }
127
128     if (instance.isValid())
129     {
130         //
131         QScriptContext *context = scriptEngine->pushContext();
132         context->setThisObject(instance);
133         context->setActivationObject(instance);
134         QString customScriptStr((const char*)data);
135         QScriptProgram customScript(customScriptStr);
136         scriptEngine->evaluate(customScript);
137         if (scriptEngine->hasUncaughtException())
138         {
139             QScriptValue error = scriptEngine->uncaughtException();
140             int lineNumber = scriptEngine->uncaughtExceptionLineNumber();
141             QStringList list = customScriptStr.split("\n", QString::KeepEmptyParts);
142             QString errorStatement = "";
143             if (lineNumber <= list.length())
144             {
145                 int i = lineNumber < 2 ? 0 : lineNumber - 2;
146                 int j = i + 2 < list.length() ? i + 2 : list.length() - 1;
147                 while (i <= j)
148                 {
149                     errorStatement += list.at(i);
150                     errorStatement += "\n";
151                     i++;
152                 }
153             }
154             QString errorString = error.toString();
155             scriptEngine->clearExceptions();
156
157             std::string message = "Failed to construct Cell '";
158             message += owner->getName();
159             message += "'\n";
160             message += "cellcode:";
161             message += getFQNName();
162             message += "\n";
163             if (errorStatement.length()>0)
164             {
165                 message += ("Statement:\n...\n");
166                 message += errorStatement.toStdString();
167                 message += "...\n";
168             }
169             message += "Error Message:";
170             message += errorString.toStdString();
171             dnNotifyError("Initialization failed", message);
172         }
173
174         scriptEngine->popContext();
175
176         result = new DNQSCellCodeInstance(owner, instance);
177
178     }
179
180     return result;
181 }