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

- 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 {
13 
14 }

◆ ~ScriptConsole()

DLLEXPORT Leviathan::ScriptConsole::~ScriptConsole ( )

Definition at line 16 of file Console.cpp.

16  {
17 
18 }

Member Function Documentation

◆ AddFunctionStringDefinition()

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

Definition at line 321 of file Console.cpp.

323 {
324  // adds a function using the method in the Console example of AngelScript SDK //
325  bool result = false;
326 
327  asIScriptModule* mod = ConsoleModule.lock()->GetModule();
328 
329 
330  asIScriptFunction* func = 0;
331  int r = mod->CompileFunction("ConsoleAddFunc", statement.c_str(), 0,
332  asCOMP_ADD_TO_MODULE, &func);
333  if(r < 0){
334 
335  ConsoleOutput("Failed to add the function");
336  result = false;
337  } else {
338 
339  result = true;
340 
341  // we could disallow same function name with different arguments //
342  //if(mod->GetFunctionByName(func->GetName()) == 0){
343 
344  // mod->RemoveFunction(func);
345  // ConsoleOutput("Function with that name already exists");
346  // result = false;
347  //}
348  }
349 
350  // We must release the function object //
351  if(func)
352  func->Release();
353  if(result)
354  ConsoleOutput("Function added");
355  return result;
356 }

◆ AddVariableStringDefinition()

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

Definition at line 287 of file Console.cpp.

289 {
290  // adds a variable using the method in the Console example of AngelScript SDK //
291 
292  int result = ConsoleModule.lock()->GetModule()->CompileGlobalVar("ConsoleAddVar",
293  statement.c_str(), 0);
294  if(result < 0){
295 
296  ConsoleOutput("Failed to add a new variable, log might have some more info");
297  return false;
298  }
299 
300  return true;
301 }

◆ DeleteFunctionStringDefinition()

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

Definition at line 358 of file Console.cpp.

360 {
361  // deletes a function using the method in the Console example of AngelScript SDK //
362  asIScriptModule* mod = ConsoleModule.lock()->GetModule();
363 
364  // try to find by name //
365  asIScriptFunction* func = mod->GetFunctionByName(statement.c_str());
366  if(func){
367  // found, remove it //
368  mod->RemoveFunction(func);
369 
370  goto funcdeletesucceedendgarbagecollectlabel;
371  }
372  // we couldn't find it by name //
373 
374  // try to find by declaration //
375  func = mod->GetFunctionByDecl(statement.c_str());
376  if(func){
377  // found, remove it //
378  mod->RemoveFunction(func);
379 
380  goto funcdeletesucceedendgarbagecollectlabel;
381 
382  }
383 
384  ConsoleOutput("Function not found, if you tried with just the name try full declaration \n"
385  "\"int func(int arg1, int arg2)\"");
386 
387  return false;
388 
389 funcdeletesucceedendgarbagecollectlabel:
390 
391  ConsoleOutput("Function deleted");
392 
393  // Since functions can be recursive, we'll call the garbage
394  // collector to make sure the object is really freed
395  // \todo make engine garbage collect stop all running scripts //
396  Logger::Get()->Warning("Console: doing garbage cleanup, scripts might be running...");
397  InterfaceInstance->GetASEngine()->GarbageCollect();
398 
399  return true;
400 }
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 303 of file Console.cpp.

305 {
306  // deletes a variable using the method in the Console example of AngelScript SDK //
307  // get the variable by name //
308  asIScriptModule* mod = ConsoleModule.lock()->GetModule();
309 
310  int index = mod->GetGlobalVarIndexByName(statement.c_str());
311  if(index >= 0 ){
312 
313  mod->RemoveGlobalVar(index);
314  ConsoleOutput("Variable removed");
315  return true;
316  }
317  ConsoleOutput("Variable not found");
318  return false;
319 }

◆ 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 251 of file Console.cpp.

253 {
254  std::unique_ptr<asIScriptContext, std::function<void(asIScriptContext*)>> context(
255  InterfaceInstance->GetASEngine()->RequestContext(), [this](asIScriptContext* context){
256  InterfaceInstance->GetASEngine()->ReturnContext(context);
257  });
258 
259  // Use ScriptHelper class to execute this statement in the module //
260  int result = ExecuteString(InterfaceInstance->GetASEngine(), statement.c_str(),
261  ConsoleModule.lock()->GetModule(), context.get());
262  if(result < 0){
263 
264  LOG_WRITE("Error in: " + statement);
265  ConsoleOutput("Invalid command syntax, please refer to the AngelScript manual");
266  return false;
267 
268  } else if(result == asEXECUTION_EXCEPTION){
269 
270  // This is duplicated from ScriptExecutor. Should probably
271  // refactor to merge this reporting to some function that
272  // takes a report source
273 
274  InterfaceInstance->PrintExceptionInfo(context.get(), LogOutput);
275 
276  ConsoleOutput("Command caused an exception, more info is in the log, \n"
277  "depending on the exception it may or may not have been your command, \n"
278  "but rather a bug in someone else's code...");
279 
280  return false;
281  }
282 
283  // Couldn't fail that badly //
284  return true;
285 }
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:84

◆ 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:251
#define GUARD_LOCK()
Definition: ThreadSafe.h:91

◆ Init()

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

Definition at line 32 of file Console.cpp.

32  {
33 
34  // store pointer //
35  InterfaceInstance = MainScript;
36 
37  // get a new module to be the console module //
38  ConsoleModule = InterfaceInstance->CreateNewModule("ConsoleModule", "console");
39 
40  return true;
41 }
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 402 of file Console.cpp.

402  {
403 
404  // list global functions //
405  Logger::Get()->Info("Global functions: ");
406 
407  // get pointer to engine //
408  asIScriptEngine* engine = InterfaceInstance->GetASEngine();
409 
410  for(asUINT n = 0; n < engine->GetGlobalFunctionCount(); n++){
411  // get function pointer //
412  asIScriptFunction* func = engine->GetGlobalFunctionByIndex(n);
413 
414  // Skip the functions that start with _ as these are not meant to be called explicitly
415  // by the user
416  if(func->GetName()[0] != '_')
417  Logger::Get()->Write(std::string("\t> ")+func->GetDeclaration());
418  }
419 
420  // list consoles' global variables //
421  Logger::Get()->Info("Console instance functions: ");
422 
423  // List the user functions in the module
424  asIScriptModule* mod = ConsoleModule.lock()->GetModule();
425 
426  for(asUINT n = 0; n < mod->GetFunctionCount(); n++ ){
427  // get function //
428  asIScriptFunction* func = mod->GetFunctionByIndex(n);
429 
430  // Print the function //
431  Logger::Get()->Write(std::string("\t> ")+func->GetDeclaration());
432  }
433 
434 }
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 436 of file Console.cpp.

436  {
437 
438  // list global variables //
439  Logger::Get()->Info("Global script variables: ");
440 
441  // get pointer to engine //
442  asIScriptEngine* engine = InterfaceInstance->GetASEngine();
443 
444  for(asUINT n = 0; n < engine->GetGlobalPropertyCount(); n++){
445  // get info about variable //
446  const char* name;
447  int vartypeid;
448  bool conststate;
449  engine->GetGlobalPropertyByIndex(n, &name, 0, &vartypeid, &conststate);
450  // construct info string //
451  std::string decl(conststate ? "const " : "");
452  decl += engine->GetTypeDeclaration(vartypeid);
453  decl += " ";
454  decl += name;
455 
456  Logger::Get()->Write("\t> " + decl);
457  }
458 
459  // list consoles' global variables //
460  Logger::Get()->Info("Console instance variables: ");
461 
462  // List the user variables in the module
463  asIScriptModule* mod = ConsoleModule.lock()->GetModule();
464 
465  for(asUINT n = 0; n < mod->GetGlobalVarCount(); n++ ){
466  // print //
467  Logger::Get()->Write(std::string("\t#> ") + mod->GetGlobalVarDeclaration(n));
468  }
469 }
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 43 of file Console.cpp.

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

◆ RunConsoleCommand()

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

Definition at line 52 of file Console.cpp.

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

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