Leviathan  0.8.0.0
Leviathan game engine
Leviathan::ScriptConsole Class Reference

#include <Console.h>

+ Inheritance diagram for Leviathan::ScriptConsole:

Public Member Functions

DLLEXPORT ScriptConsole ()
 
DLLEXPORT ~ScriptConsole ()
 
DLLEXPORT bool Init (ScriptExecutor *MainScript)
 
DLLEXPORT void Release ()
 
DLLEXPORT int RunConsoleCommand (std::string cmd)
 
DLLEXPORT bool ExecuteStringInstruction (Lock &guard, const std::string &statement)
 calls script helper and runs this statement on the console module More...
 
DLLEXPORT bool ExecuteStringInstruction (const std::string &statement)
 
DLLEXPORT bool AddVariableStringDefinition (Lock &guard, std::string statement)
 
DLLEXPORT bool DeleteVariableStringDefinition (Lock &guard, const std::string &statement)
 
DLLEXPORT bool AddFunctionStringDefinition (Lock &guard, const std::string &statement)
 
DLLEXPORT bool DeleteFunctionStringDefinition (Lock &guard, const std::string &statement)
 
DLLEXPORT void ListFunctions (Lock &guard)
 
DLLEXPORT void ListVariables (Lock &guard)
 
- Public Member Functions inherited from Leviathan::ThreadSafeGeneric< MutexType >
DLLEXPORT ThreadSafeGeneric ()
 
DLLEXPORT ~ThreadSafeGeneric ()
 
FORCE_INLINE void VerifyLock (RecursiveLock &guard) const
 
FORCE_INLINE void VerifyLock (Lock &lockit) const
 

Additional Inherited Members

- Public Types inherited from Leviathan::ThreadSafeGeneric< MutexType >
using LockT = typename LockTypeResolver< MutexType >::LType
 
- Protected Attributes inherited from Leviathan::ThreadSafeGeneric< MutexType >
MutexType ObjectsLock
 

Detailed Description

class used to execute script functions in the Console module

Note
console IS thread safe (at least should, work in progress

Definition at line 46 of file Console.h.

Constructor & Destructor Documentation

◆ ScriptConsole()

DLLEXPORT Leviathan::ScriptConsole::ScriptConsole ( )

Definition at line 10 of file Console.cpp.

10  :
11  InterfaceInstance(NULL), ConsoleModule(), consoleemptyspam(0)
12 {}

◆ ~ScriptConsole()

DLLEXPORT Leviathan::ScriptConsole::~ScriptConsole ( )

Definition at line 14 of file Console.cpp.

14 {}

Member Function Documentation

◆ AddFunctionStringDefinition()

DLLEXPORT bool Leviathan::ScriptConsole::AddFunctionStringDefinition ( Lock guard,
const std::string &  statement 
)

Definition at line 303 of file Console.cpp.

305 {
306  // adds a function using the method in the Console example of AngelScript SDK //
307  bool result = false;
308 
309  asIScriptModule* mod = ConsoleModule.lock()->GetModule();
310 
311 
312  asIScriptFunction* func = 0;
313  int r = mod->CompileFunction(
314  "ConsoleAddFunc", statement.c_str(), 0, asCOMP_ADD_TO_MODULE, &func);
315  if(r < 0) {
316 
317  ConsoleOutput("Failed to add the function");
318  result = false;
319  } else {
320 
321  result = true;
322 
323  // we could disallow same function name with different arguments //
324  // if(mod->GetFunctionByName(func->GetName()) == 0){
325 
326  // mod->RemoveFunction(func);
327  // ConsoleOutput("Function with that name already exists");
328  // result = false;
329  //}
330  }
331 
332  // We must release the function object //
333  if(func)
334  func->Release();
335  if(result)
336  ConsoleOutput("Function added");
337  return result;
338 }

◆ AddVariableStringDefinition()

DLLEXPORT bool Leviathan::ScriptConsole::AddVariableStringDefinition ( Lock guard,
std::string  statement 
)

Definition at line 269 of file Console.cpp.

271 {
272  // adds a variable using the method in the Console example of AngelScript SDK //
273 
274  int result = ConsoleModule.lock()->GetModule()->CompileGlobalVar(
275  "ConsoleAddVar", statement.c_str(), 0);
276  if(result < 0) {
277 
278  ConsoleOutput("Failed to add a new variable, log might have some more info");
279  return false;
280  }
281 
282  return true;
283 }

◆ DeleteFunctionStringDefinition()

DLLEXPORT bool Leviathan::ScriptConsole::DeleteFunctionStringDefinition ( Lock guard,
const std::string &  statement 
)

Definition at line 340 of file Console.cpp.

342 {
343  // deletes a function using the method in the Console example of AngelScript SDK //
344  asIScriptModule* mod = ConsoleModule.lock()->GetModule();
345 
346  // try to find by name //
347  asIScriptFunction* func = mod->GetFunctionByName(statement.c_str());
348  if(func) {
349  // found, remove it //
350  mod->RemoveFunction(func);
351 
352  goto funcdeletesucceedendgarbagecollectlabel;
353  }
354  // we couldn't find it by name //
355 
356  // try to find by declaration //
357  func = mod->GetFunctionByDecl(statement.c_str());
358  if(func) {
359  // found, remove it //
360  mod->RemoveFunction(func);
361 
362  goto funcdeletesucceedendgarbagecollectlabel;
363  }
364 
365  ConsoleOutput("Function not found, if you tried with just the name try full declaration \n"
366  "\"int func(int arg1, int arg2)\"");
367 
368  return false;
369 
370 funcdeletesucceedendgarbagecollectlabel:
371 
372  ConsoleOutput("Function deleted");
373 
374  // Since functions can be recursive, we'll call the garbage
375  // collector to make sure the object is really freed
376  // \todo make engine garbage collect stop all running scripts //
377  Logger::Get()->Warning("Console: doing garbage cleanup, scripts might be running...");
378  InterfaceInstance->GetASEngine()->GarbageCollect();
379 
380  return true;
381 }
DLLEXPORT asIScriptEngine * GetASEngine()
DLLEXPORT void Warning(const std::string &data) override
Definition: Logger.cpp:190
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106

◆ DeleteVariableStringDefinition()

DLLEXPORT bool Leviathan::ScriptConsole::DeleteVariableStringDefinition ( Lock guard,
const std::string &  statement 
)

Definition at line 285 of file Console.cpp.

287 {
288  // deletes a variable using the method in the Console example of AngelScript SDK //
289  // get the variable by name //
290  asIScriptModule* mod = ConsoleModule.lock()->GetModule();
291 
292  int index = mod->GetGlobalVarIndexByName(statement.c_str());
293  if(index >= 0) {
294 
295  mod->RemoveGlobalVar(index);
296  ConsoleOutput("Variable removed");
297  return true;
298  }
299  ConsoleOutput("Variable not found");
300  return false;
301 }

◆ ExecuteStringInstruction() [1/2]

DLLEXPORT bool Leviathan::ScriptConsole::ExecuteStringInstruction ( Lock guard,
const std::string &  statement 
)

calls script helper and runs this statement on the console module

Definition at line 232 of file Console.cpp.

234 {
235  std::unique_ptr<asIScriptContext, std::function<void(asIScriptContext*)>> context(
236  InterfaceInstance->GetASEngine()->RequestContext(), [this](asIScriptContext* context) {
237  InterfaceInstance->GetASEngine()->ReturnContext(context);
238  });
239 
240  // Use ScriptHelper class to execute this statement in the module //
241  int result = ExecuteString(InterfaceInstance->GetASEngine(), statement.c_str(),
242  ConsoleModule.lock()->GetModule(), context.get());
243  if(result < 0) {
244 
245  LOG_WRITE("Error in: " + statement);
246  ConsoleOutput(
247  "Invalid command syntax, type 'help' or refer to the AngelScript manual");
248  return false;
249 
250  } else if(result == asEXECUTION_EXCEPTION) {
251 
252  // This is duplicated from ScriptExecutor. Should probably
253  // refactor to merge this reporting to some function that
254  // takes a report source
255 
256  InterfaceInstance->PrintExceptionInfo(context.get(), LogOutput);
257 
258  ConsoleOutput("Command caused an exception, more info is in the log, \n"
259  "depending on the exception it may or may not have been your command, \n"
260  "but rather a bug in someone else's code...");
261 
262  return false;
263  }
264 
265  // Couldn't fail that badly //
266  return true;
267 }
DLLEXPORT asIScriptEngine * GetASEngine()
static DLLEXPORT void PrintExceptionInfo(asIScriptContext *ctx, LErrorReporter &output, asIScriptFunction *func=nullptr, ScriptModule *scrptmodule=nullptr)
Prints exception info and stacktrace to a logger.
#define LOG_WRITE(x)
Definition: Define.h:95

◆ ExecuteStringInstruction() [2/2]

DLLEXPORT bool Leviathan::ScriptConsole::ExecuteStringInstruction ( const std::string &  statement)
inline

Definition at line 65 of file Console.h.

65  {
66 
67  GUARD_LOCK();
68  return ExecuteStringInstruction(guard, statement);
69  }
DLLEXPORT bool ExecuteStringInstruction(Lock &guard, const std::string &statement)
calls script helper and runs this statement on the console module
Definition: Console.cpp:232
#define GUARD_LOCK()
Definition: ThreadSafe.h:111

◆ Init()

DLLEXPORT bool Leviathan::ScriptConsole::Init ( ScriptExecutor MainScript)

Definition at line 27 of file Console.cpp.

28 {
29 
30  // store pointer //
31  InterfaceInstance = MainScript;
32 
33  // get a new module to be the console module //
34  ConsoleModule = InterfaceInstance->CreateNewModule("ConsoleModule", "console");
35 
36  return true;
37 }
DLLEXPORT std::weak_ptr< ScriptModule > CreateNewModule(const std::string &name, const std::string &source, const int &modulesid=IDFactory::GetID())

◆ ListFunctions()

DLLEXPORT void Leviathan::ScriptConsole::ListFunctions ( Lock guard)

Definition at line 383 of file Console.cpp.

384 {
385 
386  // list global functions //
387  Logger::Get()->Info("Global functions: ");
388 
389  // get pointer to engine //
390  asIScriptEngine* engine = InterfaceInstance->GetASEngine();
391 
392  for(asUINT n = 0; n < engine->GetGlobalFunctionCount(); n++) {
393  // get function pointer //
394  asIScriptFunction* func = engine->GetGlobalFunctionByIndex(n);
395 
396  // Skip the functions that start with _ as these are not meant to be called explicitly
397  // by the user
398  if(func->GetName()[0] != '_')
399  Logger::Get()->Write(std::string("\t> ") + func->GetDeclaration());
400  }
401 
402  // list consoles' global variables //
403  Logger::Get()->Info("Console instance functions: ");
404 
405  // List the user functions in the module
406  asIScriptModule* mod = ConsoleModule.lock()->GetModule();
407 
408  for(asUINT n = 0; n < mod->GetFunctionCount(); n++) {
409  // get function //
410  asIScriptFunction* func = mod->GetFunctionByIndex(n);
411 
412  // Print the function //
413  Logger::Get()->Write(std::string("\t> ") + func->GetDeclaration());
414  }
415 }
DLLEXPORT void Write(const std::string &data) override
Definition: Logger.cpp:113
DLLEXPORT asIScriptEngine * GetASEngine()
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106

◆ ListVariables()

DLLEXPORT void Leviathan::ScriptConsole::ListVariables ( Lock guard)

Definition at line 417 of file Console.cpp.

418 {
419 
420  // list global variables //
421  Logger::Get()->Info("Global script variables: ");
422 
423  // get pointer to engine //
424  asIScriptEngine* engine = InterfaceInstance->GetASEngine();
425 
426  for(asUINT n = 0; n < engine->GetGlobalPropertyCount(); n++) {
427  // get info about variable //
428  const char* name;
429  int vartypeid;
430  bool conststate;
431  engine->GetGlobalPropertyByIndex(n, &name, 0, &vartypeid, &conststate);
432  // construct info string //
433  std::string decl(conststate ? "const " : "");
434  decl += engine->GetTypeDeclaration(vartypeid);
435  decl += " ";
436  decl += name;
437 
438  Logger::Get()->Write("\t> " + decl);
439  }
440 
441  // list consoles' global variables //
442  Logger::Get()->Info("Console instance variables: ");
443 
444  // List the user variables in the module
445  asIScriptModule* mod = ConsoleModule.lock()->GetModule();
446 
447  for(asUINT n = 0; n < mod->GetGlobalVarCount(); n++) {
448  // print //
449  Logger::Get()->Write(std::string("\t#> ") + mod->GetGlobalVarDeclaration(n));
450  }
451 }
DLLEXPORT void Write(const std::string &data) override
Definition: Logger.cpp:113
DLLEXPORT asIScriptEngine * GetASEngine()
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106

◆ Release()

DLLEXPORT void Leviathan::ScriptConsole::Release ( )

Definition at line 39 of file Console.cpp.

40 {
41  GUARD_LOCK();
42  // set the module to release itself since it won't be used anymore //
43  auto tmpptre = ConsoleModule.lock();
44 
45  if(tmpptre)
46  tmpptre->DeleteThisModule();
47 }
#define GUARD_LOCK()
Definition: ThreadSafe.h:111

◆ RunConsoleCommand()

DLLEXPORT int Leviathan::ScriptConsole::RunConsoleCommand ( std::string  cmd)

Definition at line 49 of file Console.cpp.

50 {
51 
52  // Trim the end to make sure there aren't newline characters
54 
55  GUARD_LOCK();
56 
57 
58  // First thing to check is the user wanting help //
59  if(cmd == "help") {
60 
61  ConsoleOutput("// ------------------ Help ------------------ //\n"
62  "\t> Console commands are a custom command followed by it's parameters\n"
63  "\t or just plain AngelScript code. (Optionally starting with a '>')\n"
64  "\t> Running a custom command: \">[TYPE=\"\"] [COMMAND]\" eg. \n"
65  "\t \">ADDVAR int newglobal = 25\"\n"
66  "\t You can view custom commands with the \"commands\" command.\n"
67  "\t> Running arbitrary commands:\n "
68  "\t \"> for(int i = 0; i < 5; i++) GlobalFunc();\"\n"
69  "\t> Multiline commands are done by putting '\\' (a backwards slash) \n"
70  "\tto the end of each line.\n"
71  "\t> For example:\n"
72  "\t >ADDFUNC void MyFunc(int i){ Print(\"Val is: \"+i); }\n"
73  "\t(int i = 0; i < 10; i++){ MyFunc(i); }\n"
74  "\t> Would output \"Val is: 0 Val is: 1 ...\"");
76 
77  } else if(cmd == "commands") {
78  // List custom commands //
79  ConsoleOutput("// ------------------ Custom commands ------------------ //\n"
80  "Available custom commands are:\n");
81 
82  std::string messagecommand = "";
83  bool first = true;
84 
85  for(auto iter = CommandTypeDefinitions.begin(); iter != CommandTypeDefinitions.end();
86  ++iter) {
87  // Add it's name //
88  if(!first) {
89  messagecommand += ", ";
90  }
91 
92  messagecommand += iter->first;
93 
94  first = false;
95  }
96 
97  ConsoleOutput("\t> " + messagecommand);
99 
100  } else if(cmd == "exit" || cmd == "quit" || cmd == "q") {
101 
102  ConsoleOutput("Marking the program as closing");
105  }
106 
107  // first check if ">" is first character, we can easily reject command if it is missing //
108  if(cmd.size() < 1) {
109  // invalid format //
110  ConsoleOutput("Invalid command format, empty command");
111  consoleemptyspam++;
112  if(consoleemptyspam > 5) {
113  // \todo tell user how to close console //
114  ConsoleOutput("You seem to be spamming empty lines, maybe you'd like to close "
115  "the console? \"quit\" \nor \"help\" might help you on your quest.");
116  }
117 
119  }
120 
121  StringIterator itr(cmd);
122 
123  if(itr.GetCharacter() == '>') {
124  // Skip first character since it is now handled //
125  itr.MoveToNext();
126  }
127 
128  // get the console main command type //
129  auto ccmd = itr.GetNextCharacterSequence<std::string>(
131 
132  // check if the length is too long or too short to actually be any specific command //
134  if(ccmd && (ccmd->size() > 0)) {
135  // Check for types //
136  auto matchpos = CommandTypeDefinitions.find(*ccmd);
137 
138  if(matchpos == CommandTypeDefinitions.end()) {
139  // Not found //
140  commandtype = CONSOLECOMMANDTYPE_NONE;
141  } else {
142  // Set matching type //
143  commandtype = matchpos->second;
144  }
145 
146  } else {
147 
148  commandtype = CONSOLECOMMANDTYPE_ERROR;
149  }
150 
151  auto restofcommand = itr.GetUntilEnd<std::string>();
152 
153  if((!restofcommand || restofcommand->empty()) && commandtype == CONSOLECOMMANDTYPE_NONE) {
154 
155  restofcommand.swap(ccmd);
156  }
157 
158  // Switch on type and handle rest //
159  switch(commandtype) {
161  // We just need to check if this is multiple lines command //
162  if(restofcommand->back() == '\\') {
163 
164  // Multi line command //
165  if(ccmd) {
166 
167  PendingCommand +=
168  (*ccmd) + (restofcommand->substr(0, restofcommand->size() - 1)) + "\n";
169  } else {
170 
171  PendingCommand += restofcommand->substr(0, restofcommand->size() - 1) + "\n";
172  }
173 
174  // waiting for more //
176 
177  } else {
178 
179  // run command (and possibly previous multi line parts) //
181  guard, PendingCommand.size() != 0 ?
182  PendingCommand + ((ccmd ? (*ccmd) : "")) + (*restofcommand) :
183  ((ccmd ? (*ccmd) : "")) + (*restofcommand))) {
184  // Clear the pending command //
185  PendingCommand.clear();
186  // The command execution has failed... //
188  }
189  // clear pending command //
190  PendingCommand.clear();
191  // succeeded //
193  }
194  } break;
196  return AddVariableStringDefinition(guard, *restofcommand) ?
199  } break;
201  return AddFunctionStringDefinition(guard, *restofcommand) ?
204  } break;
206  return DeleteVariableStringDefinition(guard, *restofcommand) ?
209  } break;
211  return DeleteFunctionStringDefinition(guard, *restofcommand) ?
214  } break;
216  ListFunctions(guard);
217  } break;
219  ListVariables(guard);
220  } break;
221  default: {
222  ConsoleOutput("Invalid command type, if you don't know what a command type is you"
223  "probably should add space after > \n"
224  "like: \"> yourstuffhere();\" OR just don't type the '>' \n"
225  "and everything should be fine.");
226  }
227  }
228  // commands will return their codes if they succeed //
230 }
DLLEXPORT bool DeleteFunctionStringDefinition(Lock &guard, const std::string &statement)
Definition: Console.cpp:340
CONSOLECOMMANDTYPE
Definition: Console.h:17
DLLEXPORT bool ExecuteStringInstruction(Lock &guard, const std::string &statement)
calls script helper and runs this statement on the console module
Definition: Console.cpp:232
DLLEXPORT void ListVariables(Lock &guard)
Definition: Console.cpp:417
DLLEXPORT bool AddFunctionStringDefinition(Lock &guard, const std::string &statement)
Definition: Console.cpp:303
DLLEXPORT void MarkAsClosing()
Thread safely marks the game to close sometime.
Iterator class for getting parts of a string.
DLLEXPORT void ListFunctions(Lock &guard)
Definition: Console.cpp:383
DLLEXPORT bool DeleteVariableStringDefinition(Lock &guard, const std::string &statement)
Definition: Console.cpp:285
DLLEXPORT bool AddVariableStringDefinition(Lock &guard, std::string statement)
Definition: Console.cpp:269
static DLLEXPORT LeviathanApplication * Get()
Definition: Application.cpp:32
static void RemovePreceedingTrailingSpaces(StringTypeN &str)
#define GUARD_LOCK()
Definition: ThreadSafe.h:111

The documentation for this class was generated from the following files: