• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

diegoarjz / aswpp / 13214259888

08 Feb 2025 09:11AM UTC coverage: 81.59% (+0.8%) from 80.753%
13214259888

Pull #11

github

diegoarjz
Avoid releasing after running

This was preventing the engine from running more than once. Instead
release on engine destruction.
Pull Request #11: Avoid releasing after running

1 of 1 new or added line in 1 file covered. (100.0%)

2 existing lines in 1 file now uncovered.

585 of 717 relevant lines covered (81.59%)

10.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.98
/src/script_engine.cpp
1
#include "aswpp/script_engine.h"
2

3
#include "scriptstdstring.h"
4

5
#include <iostream>
6
#include <map>
7

8
namespace aswpp {
9
//----------------------------------------
10
// Engine class
11
static void StaticMessageCallback(const asSMessageInfo *msg) {
70✔
12
  switch (msg->type) {
70✔
13
  case asMSGTYPE_ERROR:
2✔
14
    std::cerr << "[Error] (" << msg->section << "@" << msg->row << ":"
2✔
15
              << msg->col << ")" << msg->message << std::endl;
2✔
16
    break;
2✔
17
  case asMSGTYPE_WARNING:
34✔
18
    std::cerr << "[Warning] (" << msg->section << "@" << msg->row << ":"
34✔
19
              << msg->col << ")" << msg->message << std::endl;
34✔
20
    break;
34✔
21
  case asMSGTYPE_INFORMATION:
34✔
22
    std::cerr << "[Info] (" << msg->section << "@" << msg->row << ":"
34✔
23
              << msg->col << ")" << msg->message << std::endl;
34✔
24
    break;
34✔
25
  };
26
}
70✔
27

28
class Engine::Impl {
29
public:
30
  Impl(Engine &engine) : m_scriptEngine{engine} {
45✔
31
    m_asEngine = asCreateScriptEngine();
45✔
32

33
    int r = m_asEngine->SetMessageCallback(asFUNCTION(StaticMessageCallback), 0,
45✔
34
                                           asCALL_CDECL);
35

36
    m_asEngine->SetMessageCallback(asFUNCTION(StaticMessageCallback), nullptr,
45✔
37
                                   asCALL_CDECL);
38

39
    /*
40
    if (r == asINVALID_ARG) {
41
    } else if (r == asNOT_SUPPORTED) {
42
    }
43
    */
44

45
    m_context = m_asEngine->CreateContext();
45✔
46

47
    if (m_context == nullptr) {
45✔
48
      m_asEngine->ShutDownAndRelease();
×
49
      m_asEngine = nullptr;
×
50
    }
51

52
    RegisterStdString(m_asEngine);
45✔
53
  }
45✔
54

55
  ~Impl() {
45✔
56
    if (m_asEngine != nullptr) {
45✔
57
      m_asEngine->ShutDownAndRelease();
45✔
58
    }
59
  }
45✔
60

61
  bool prepare(const std::string &moduleName, const std::string &function) {
34✔
62
    if (m_asEngine == nullptr) {
34✔
63
      std::cerr << "Tried running an invalid script." << std::endl;
×
64
      return false;
×
65
    }
66

67
    asIScriptModule *module = m_asEngine->GetModule(moduleName.c_str());
34✔
68

69
    auto *func = module->GetFunctionByDecl(function.c_str());
34✔
70
    if (func == nullptr) {
34✔
71
      std::cerr << "Could not find function '" << function << "'." << std::endl;
×
72
      return false;
×
73
    }
74

75
    if (m_context == nullptr) {
34✔
76
      std::cerr << "Could not create context." << std::endl;
×
77
      return false;
×
78
    }
79

80
    if (m_context->Prepare(func) != 0) {
34✔
81
      std::cerr << "Could not prepare context." << std::endl;
×
82
      m_context->Release();
×
83
      return false;
×
84
    }
85

86
    return true;
34✔
87
  }
88

89
  bool run(const std::string &moduleName, const std::string &function) {
34✔
90
    if (m_context->Execute() != asEXECUTION_FINISHED) {
34✔
91
      std::cerr << "Could not execute context." << std::endl;
×
92
      return false;
×
93
    }
94
    return true;
34✔
95
  }
96

UNCOV
97
  bool release() { return m_context->Release() == 0; }
×
98

99
  Engine &m_scriptEngine;
100
  asIScriptEngine *m_asEngine{nullptr};
101
  asIScriptContext *m_context{nullptr};
102
  std::map<std::string, ModulePtr> m_modules;
103
};
104

105
Engine::Engine() : m_impl(std::make_unique<Engine::Impl>(*this)) {}
45✔
106

107
Engine::~Engine() {}
45✔
108

109
bool Engine::IsValid() const { return m_impl->m_asEngine != nullptr; }
1✔
110

111
ModulePtr Engine::CreateModule(const std::string &name,
10✔
112
                               const std::string &source) {
113
  auto module = std::make_shared<Module>(name, source);
10✔
114
  if (!Attach(module)) {
10✔
115
    return nullptr;
×
116
  }
117
  return module;
10✔
118
}
10✔
119

120
bool Engine::Attach(const ModulePtr &module) {
41✔
121
  // Keep track of which engine this module is attached to
122
  if (module->IsAttached()) {
41✔
123
    return false;
1✔
124
  }
125

126
  const bool wasInserted =
127
      m_impl->m_modules.emplace(module->GetName(), module).second;
40✔
128
  if (!wasInserted) {
40✔
129
    return false;
×
130
  }
131
  module->attachTo(this);
40✔
132

133
  if (!module->prepareModule(
80✔
134
          reinterpret_cast<asScriptEngineHandle *>(m_impl->m_asEngine))) {
40✔
135
    return false;
1✔
136
  }
137

138
  return true;
39✔
139
}
140

141
//----------------------------------------
142
//! \section Register Enum Methods
143
bool Engine::RegisterEnum(const std::string &enumName) {
6✔
144
  const int r = m_impl->m_asEngine->RegisterEnum(enumName.c_str());
6✔
145
  return r >= 0;
6✔
146
}
147
bool Engine::RegisterEnumValue(const std::string &enumName,
10✔
148
                               const std::string &valueName, int value) {
149
  const int r = m_impl->m_asEngine->RegisterEnumValue(enumName.c_str(),
10✔
150
                                                      valueName.c_str(), value);
151
  return r >= 0;
10✔
152
}
153

154
bool Engine::prepare(const std::string &moduleName,
34✔
155
                     const std::string &function) {
156
  return m_impl->prepare(moduleName, function);
34✔
157
}
158

159
bool Engine::run(const std::string &module, const std::string &function) {
34✔
160
  return m_impl->run(module, function);
34✔
161
}
162

UNCOV
163
bool Engine::release() { return m_impl->release(); }
×
164

165
asIScriptEngine *Engine::engine() { return m_impl->m_asEngine; }
18✔
166

167
namespace {
168
void reportSetFunctionError(int error) {
×
169
  if (error != asSUCCESS) {
×
170
    if (error == asCONTEXT_NOT_PREPARED) {
×
171
      std::cerr << " Context not prepared" << std::endl;
×
172
    } else if (error == asINVALID_ARG) {
×
173
      std::cerr << " Argument number is larger than the number of arguments in "
174
                   "the prepared function."
×
175
                << std::endl;
×
176
    } else if (error == asINVALID_TYPE) {
×
177
      std::cerr << " The argument is not an object or handle." << std::endl;
×
178
    }
179
  }
180
}
×
181
} // namespace
182

183
template <> bool Engine::setFunctionArg<int64_t>(int i, int64_t val) {
1✔
184
  const int r = m_impl->m_context->SetArgQWord(i, val);
1✔
185
  if (r != asSUCCESS) {
1✔
186
    std::cerr << "Unable to set argument " << i << " to value at address "
×
187
              << val << std::endl;
×
188
    reportSetFunctionError(r);
×
189
  }
190
  return r == asSUCCESS;
1✔
191
}
192

193
template <> bool Engine::setFunctionArg<uint64_t>(int i, uint64_t val) {
1✔
194
  const int r = m_impl->m_context->SetArgQWord(i, val);
1✔
195
  if (r != asSUCCESS) {
1✔
196
    std::cerr << "Unable to set argument " << i << " to value at address "
×
197
              << val << std::endl;
×
198
    reportSetFunctionError(r);
×
199
  }
200
  return r == asSUCCESS;
1✔
201
}
202

203
template <> bool Engine::setFunctionArg<int32_t>(int i, int32_t val) {
3✔
204
  const int r = m_impl->m_context->SetArgDWord(i, val);
3✔
205
  if (r != asSUCCESS) {
3✔
206
    std::cerr << "Unable to set argument " << i << " to value at address "
×
207
              << val << std::endl;
×
208
    reportSetFunctionError(r);
×
209
  }
210
  return r == asSUCCESS;
3✔
211
}
212

213
template <> bool Engine::setFunctionArg<uint32_t>(int i, uint32_t val) {
1✔
214
  const int r = m_impl->m_context->SetArgDWord(i, val);
1✔
215
  if (r != asSUCCESS) {
1✔
216
    std::cerr << "Unable to set argument " << i << " to value at address "
×
217
              << val << std::endl;
×
218
    reportSetFunctionError(r);
×
219
  }
220
  return r == asSUCCESS;
1✔
221
}
222

223
template <> bool Engine::setFunctionArg<int16_t>(int i, int16_t val) {
1✔
224
  const int r = m_impl->m_context->SetArgWord(i, val);
1✔
225
  if (r != asSUCCESS) {
1✔
226
    std::cerr << "Unable to set argument " << i << " to value at address "
×
227
              << val << std::endl;
×
228
    reportSetFunctionError(r);
×
229
  }
230
  return r == asSUCCESS;
1✔
231
}
232

233
template <> bool Engine::setFunctionArg<uint16_t>(int i, uint16_t val) {
1✔
234
  const int r = m_impl->m_context->SetArgWord(i, val);
1✔
235
  if (r != asSUCCESS) {
1✔
236
    std::cerr << "Unable to set argument " << i << " to value at address "
×
237
              << val << std::endl;
×
238
    reportSetFunctionError(r);
×
239
  }
240
  return r == asSUCCESS;
1✔
241
}
242

243
template <> bool Engine::setFunctionArg<int8_t>(int i, int8_t val) {
1✔
244
  const int r = m_impl->m_context->SetArgByte(i, val);
1✔
245
  if (r != asSUCCESS) {
1✔
246
    std::cerr << "Unable to set argument " << i << " to value at address "
×
247
              << val << std::endl;
×
248
    reportSetFunctionError(r);
×
249
  }
250
  return r == asSUCCESS;
1✔
251
}
252

253
template <> bool Engine::setFunctionArg<uint8_t>(int i, uint8_t val) {
1✔
254
  const int r = m_impl->m_context->SetArgByte(i, val);
1✔
255
  if (r != asSUCCESS) {
1✔
256
    std::cerr << "Unable to set argument " << i << " to value at address "
×
257
              << val << std::endl;
×
258
    reportSetFunctionError(r);
×
259
  }
260
  return r == asSUCCESS;
1✔
261
}
262

263
template <> bool Engine::setFunctionArg<char>(int i, char val) {
×
264
  const int r = m_impl->m_context->SetArgByte(i, val);
×
265
  if (r != asSUCCESS) {
×
266
    std::cerr << "Unable to set argument " << i << " to value at address "
×
267
              << val << std::endl;
×
268
    reportSetFunctionError(r);
×
269
  }
270
  return r == asSUCCESS;
×
271
}
272

273
template <> bool Engine::setFunctionArg<float>(int i, float val) {
2✔
274
  const int r = m_impl->m_context->SetArgFloat(i, val);
2✔
275
  if (r != asSUCCESS) {
2✔
276
    std::cerr << "Unable to set argument " << i << " to value at address "
×
277
              << val << std::endl;
×
278
    reportSetFunctionError(r);
×
279
  }
280
  return r == asSUCCESS;
2✔
281
}
282

283
template <> bool Engine::setFunctionArg<double>(int i, double val) {
1✔
284
  const int r = m_impl->m_context->SetArgDouble(i, val);
1✔
285
  if (r != asSUCCESS) {
1✔
286
    std::cerr << "Unable to set argument " << i << " to value at address "
×
287
              << val << std::endl;
×
288
    reportSetFunctionError(r);
×
289
  }
290
  return r == asSUCCESS;
1✔
291
}
292

293
bool Engine::setFunctionObjectArg(int i, void *val) {
×
294
  const int r = m_impl->m_context->SetArgObject(i, val);
×
295
  if (r != asSUCCESS) {
×
296
    std::cerr << "Unable to set argument " << i << " to value at address "
×
297
              << val << std::endl;
×
298
    reportSetFunctionError(r);
×
299
  }
300
  return r == asSUCCESS;
×
301
}
302

303
template <> void Engine::getReturnValue(int64_t *value) {
×
304
  *value = m_impl->m_context->GetReturnQWord();
×
305
}
×
306

307
template <> void Engine::getReturnValue(uint64_t *value) {
×
308
  *value = m_impl->m_context->GetReturnQWord();
×
309
}
×
310

311
template <> void Engine::getReturnValue(int32_t *value) {
4✔
312
  *value = m_impl->m_context->GetReturnDWord();
4✔
313
}
4✔
314

315
template <> void Engine::getReturnValue(uint32_t *value) {
1✔
316
  *value = m_impl->m_context->GetReturnDWord();
1✔
317
}
1✔
318

319
template <> void Engine::getReturnValue(int16_t *value) {
1✔
320
  *value = m_impl->m_context->GetReturnWord();
1✔
321
}
1✔
322

323
template <> void Engine::getReturnValue(uint16_t *value) {
1✔
324
  *value = m_impl->m_context->GetReturnWord();
1✔
325
}
1✔
326

327
template <> void Engine::getReturnValue(int8_t *value) {
2✔
328
  *value = m_impl->m_context->GetReturnByte();
2✔
329
}
2✔
330

331
template <> void Engine::getReturnValue(uint8_t *value) {
2✔
332
  *value = m_impl->m_context->GetReturnByte();
2✔
333
}
2✔
334

335
template <> void Engine::getReturnValue(float *value) {
9✔
336
  *value = m_impl->m_context->GetReturnFloat();
9✔
337
}
9✔
338

339
template <> void Engine::getReturnValue(double *value) {
1✔
340
  *value = m_impl->m_context->GetReturnDouble();
1✔
341
}
1✔
342
} // namespace aswpp
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc