Leviathan  0.8.0.0
Leviathan game engine
Leviathan::GameModule Class Reference

Represents a scriptable part of a program. More...

#include <GameModule.h>

+ Inheritance diagram for Leviathan::GameModule:

Public Member Functions

DLLEXPORT GameModule (const std::string &modulename, const std::string &ownername, const std::string &extension="txt|levgm")
 
DLLEXPORT ~GameModule ()
 
DLLEXPORT bool Init ()
 Makes the scripts usable. More...
 
DLLEXPORT void ReleaseScript ()
 Releases the script. More...
 
DLLEXPORT auto GetScriptModule ()
 
template<typename ReturnT , class... Args>
ScriptRunResult< ReturnT > ExecuteOnModule (ScriptRunningSetup &setup, bool passself, Args &&... args)
 
DLLEXPORT std::string GetDescription (bool full)
 Returns a string describing this module. More...
 
 REFERENCE_COUNTED_PTR_TYPE (GameModule)
 
- Public Member Functions inherited from Leviathan::ReferenceCounted
 ReferenceCounted (const ReferenceCounted &other)=delete
 
ReferenceCountedoperator= (const ReferenceCounted &other)=delete
 
FORCE_INLINE void AddRef ()
 
FORCE_INLINE void Release ()
 removes a reference and deletes the object if reference count reaches zero More...
 
int32_t GetRefCount () const
 Returns the reference count. More...
 

Protected Member Functions

virtual ScriptRunResult< int > _DoCallWithParams (ScriptRunningSetup &sargs, Event *event, GenericEvent *event2) override
 
- Protected Member Functions inherited from Leviathan::ReferenceCounted
DLLEXPORT ReferenceCounted ()
 
virtual DLLEXPORT ~ReferenceCounted ()
 

Additional Inherited Members

- Public Types inherited from Leviathan::ReferenceCounted
using basepointer = boost::intrusive_ptr< ReferenceCounted >
 
using refcountedpointer = boost::intrusive_ptr< ReferenceCounted >
 
- Static Public Member Functions inherited from Leviathan::ReferenceCounted
template<class ActualType >
static boost::intrusive_ptr< ActualType > WrapPtr (ActualType *ptr)
 Creates an intrusive_ptr from raw pointer. More...
 
template<class ActualType , class... Args>
static boost::intrusive_ptr< ActualType > MakeShared (Args &&... args)
 Constructs a new instance and wraps it. More...
 

Detailed Description

Represents a scriptable part of a program.

Definition at line 15 of file GameModule.h.

Constructor & Destructor Documentation

◆ GameModule()

DLLEXPORT GameModule::GameModule ( const std::string &  modulename,
const std::string &  ownername,
const std::string &  extension = "txt|levgm" 
)
Warning
Quite expensive constructor since it loads the definition file
Todo:
Make load all source files, instead of loading just the first

Definition at line 12 of file GameModule.cpp.

13  :
14  EventableScriptObject(nullptr),
15  OwnerName(ownername)
16 {
17  std::string file = modulename + ".levgm";
18 
19  if(!boost::filesystem::is_regular_file(file)) {
20  // Find the actual file //
21  file =
22  FileSystem::Get()->SearchForFile(FILEGROUP_SCRIPT, modulename, extension, false);
23 
24  if(file.size() == 0) {
25 
26  // One more search attempt //
28  StringOperations::RemoveExtension(modulename), extension, false);
29  }
30 
31  if(file.size() == 0) {
32  // Couldn't find file //
33 
34  throw InvalidArgument("File doesn't exist and full search also failed for "
35  "module '" +
36  modulename + "'");
37  }
38  }
39 
40  LoadedFromFile = file;
41 
42  // Load the file //
44 
45  if(!ofile) {
46 
47  throw InvalidArgument("File is invalid");
48  }
49 
50  // Process the objects //
51  if(ofile->GetTotalObjectCount() != 1) {
52 
53  throw InvalidArgument("File contains invalid number of objects, single GameModule "
54  "expected");
55  }
56 
57  // Get various data from the header //
58  ObjectFileProcessor::LoadValueFromNamedVars<std::string>(
59  ofile->GetVariables(), "Version", Name, "-1", Logger::Get(), "GameModule:");
60 
61  auto gmobject = ofile->GetObjectFromIndex(0);
62 
63  Name = gmobject->GetName();
64 
65  // handle the single object //
66  ObjectFileList* properties = gmobject->GetListWithName("properties");
67  ObjectFileTextBlock* sources = gmobject->GetTextBlockWithName("sourcefiles");
68 
69  if(!properties || !sources) {
70 
71  throw InvalidArgument("File contains invalid GameModule, properties or "
72  "sourcefiles not found");
73  }
74 
75  // Copy data //
76  if(sources->GetLineCount() < 1) {
77 
78  throw InvalidArgument("At least one source file expected in sourcefiles");
79  }
80 
81  const std::string moduleFilePath =
82  boost::filesystem::path(StringOperations::GetPath(LoadedFromFile)).generic_string();
83 
84  // Resolve all files to their actual paths //
85  for(size_t i = 0; i < sources->GetLineCount(); ++i) {
86 
87  // Skip empty lines to allow commenting out things //
88  if(sources->GetLine(i).empty())
89  continue;
90 
91  const std::string codeFile =
92  ScriptModule::ResolvePathToScriptFile(sources->GetLine(i), moduleFilePath);
93 
94  if(codeFile.empty()) {
95  throw InvalidArgument("GameModule(" + LoadedFromFile +
96  ") can't find "
97  "source file: " +
98  sources->GetLine(i));
99  } else {
100 
101  SourceFiles.push_back(codeFile);
102  }
103  }
104 
105  // Read properties //
106  if(auto* data = properties->GetVariables().GetValueDirectRaw("ExtraAccess");
107  data != nullptr) {
108 
109  std::string flags;
110  if(data->GetVariableCount() != 1 ||
111  !data->GetValue().ConvertAndAssingToVariable(flags)) {
112 
113  throw InvalidArgument(
114  "GameModule(" + LoadedFromFile +
115  ") has an invalid value for property 'ExtraAccess': not string");
116  }
117 
118  try {
119  ExtraAccess = ParseScriptAccess(flags);
120  } catch(const InvalidArgument& e) {
121  throw InvalidArgument(
122  "GameModule(" + LoadedFromFile +
123  ") has an invalid value for property 'ExtraAccess': " + e.what());
124  }
125  }
126 
127 
128  LEVIATHAN_ASSERT(!SourceFiles.empty(), "GameModule: empty source files");
129 }
Interface for object file lists to implement.
Definition: ObjectFile.h:21
virtual DLLEXPORT size_t GetLineCount() const =0
Returns the number of text lines.
static const StringTypeN GetPath(const StringTypeN &filepath)
Returns the path part of a path+filename.
static const StringTypeN RemoveExtension(const StringTypeN &filepath, bool delpath=true)
static DLLEXPORT std::unique_ptr< ObjectFile > ProcessObjectFile(const std::string &file, LErrorReporter *reporterror)
Reads an ObjectFile to an in-memory data structure.
Interface for object file text blocks to implement.
Definition: ObjectFile.h:71
virtual DLLEXPORT const std::string & GetLine(size_t index) const =0
Gets a line from index ExceptionInvalidArgument when the index is out of bounds. ...
DLLEXPORT const char * what() const noexcept override
Definition: Exceptions.cpp:29
static DLLEXPORT FileSystem * Get()
Definition: FileSystem.cpp:79
static DLLEXPORT std::string ResolvePathToScriptFile(const std::string &inputfilename, const std::string &relativepath, bool checkworkdirrelative=true)
Finds a path to source file or returns an empty string.
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
virtual DLLEXPORT NamedVars & GetVariables()=0
Gets a reference to the underlying variables.
DLLEXPORT std::string SearchForFile(FILEGROUP which, const std::string &name, const std::string &extensions, bool searchall=true)
Searches for a file.
Definition: FileSystem.cpp:672
DLLEXPORT NamedVariableList * GetValueDirectRaw(const std::string &name) const
Definition: NamedVars.cpp:1088
DLLEXPORT AccessFlags ParseScriptAccess(std::string_view flagstring)
Parses a string for access flags.
Definition: AccessMask.cpp:7

◆ ~GameModule()

DLLEXPORT GameModule::~GameModule ( )

Definition at line 131 of file GameModule.cpp.

132 {
133  UnRegisterAllEvents();
134 
135  if(Scripting) {
136 
137  LOG_FATAL("GameModule: 'ReleaseScript' not called before destructor");
138  }
139 }
#define LOG_FATAL(x)
Definition: Define.h:85

Member Function Documentation

◆ _DoCallWithParams()

ScriptRunResult< int > GameModule::_DoCallWithParams ( ScriptRunningSetup sargs,
Event event,
GenericEvent event2 
)
overrideprotectedvirtual

Definition at line 242 of file GameModule.cpp.

244 {
245  if(event)
246  return ScriptExecutor::Get()->RunScript<int>(
247  Scripting->GetModuleSafe(), sargs, this, event);
248  else
249  return ScriptExecutor::Get()->RunScript<int>(
250  Scripting->GetModuleSafe(), sargs, this, event2);
251 }
ScriptRunResult< ReturnT > RunScript(const std::shared_ptr< ScriptModule > &module, ScriptRunningSetup &parameters, Args &&... args)
Runs a function in a script.
static DLLEXPORT ScriptExecutor * Get()

◆ ExecuteOnModule()

template<typename ReturnT , class... Args>
ScriptRunResult<ReturnT> Leviathan::GameModule::ExecuteOnModule ( ScriptRunningSetup setup,
bool  passself,
Args &&...  args 
)
inline

Executes something on the module and returns the result. Adds the module as first parameter and existed is set to true if something was executed pasself If true this object is added as the first parameter

Definition at line 44 of file GameModule.h.

46  {
47  if(!Scripting)
48  return ScriptRunResult<ReturnT>(SCRIPT_RUN_RESULT::Error);
49 
50  if(passself) {
51  return ScriptExecutor::Get()->RunScript<ReturnT>(
52  Scripting->GetModuleSafe(), setup, this, std::forward<Args>(args)...);
53  } else {
54  return ScriptExecutor::Get()->RunScript<ReturnT>(
55  Scripting->GetModuleSafe(), setup, std::forward<Args>(args)...);
56  }
57  }
ScriptRunResult< ReturnT > RunScript(const std::shared_ptr< ScriptModule > &module, ScriptRunningSetup &parameters, Args &&... args)
Runs a function in a script.
static DLLEXPORT ScriptExecutor * Get()

◆ GetDescription()

DLLEXPORT std::string GameModule::GetDescription ( bool  full)

Returns a string describing this module.

Definition at line 235 of file GameModule.cpp.

236 {
237  return "GameModule(" + Name + (full ? " v" + Version + ") " : ") ") +
238  " owned by: " + OwnerName +
239  (full ? ", loaded from file: " + LoadedFromFile + "." : ".");
240 }
Definition: lz4.c:260

◆ GetScriptModule()

DLLEXPORT auto Leviathan::GameModule::GetScriptModule ( )
inline
Returns
The script module

Definition at line 33 of file GameModule.h.

34  {
35  return ScriptMain;
36  }

◆ Init()

DLLEXPORT bool GameModule::Init ( )

Makes the scripts usable.

Definition at line 141 of file GameModule.cpp.

142 {
143  // Compile a new module //
144  ScriptModule* mod = NULL;
145 
146  if(!Scripting) {
147 
148  Scripting = std::shared_ptr<ScriptScript>(
149  new ScriptScript(ScriptExecutor::Get()->CreateNewModule(
150  "GameModule(" + Name + ") ScriptModule", LoadedFromFile)));
151 
152  // Get the newly created module //
153  mod = Scripting->GetModule();
154 
155  for(const auto& file : SourceFiles) {
156  mod->AddScriptSegmentFromFile(file);
157  }
158 
159  } else {
160 
161  // Get already created module //
162  mod = Scripting->GetModule();
163  }
164 
165  // Set access flags //
166  if(ExtraAccess != 0)
167  mod->AddAccessRight(ExtraAccess);
168 
169  // Build the module (by creating a callback list) //
170  std::vector<std::shared_ptr<ValidListenerData>> containedlisteners;
171 
172  mod->GetListOfListeners(containedlisteners);
173 
174  if(mod->GetModule() == nullptr) {
175  // Fail to build //
176  Logger::Get()->Error("GameModule: Init: failed to build AngelScript module");
177  return false;
178  }
179 
180  RegisterStandardScriptEvents(containedlisteners);
181 
182  for(size_t i = 0; i < containedlisteners.size(); i++) {
183  // Bind generic event //
184  if(containedlisteners[i]->GenericTypeName &&
185  containedlisteners[i]->GenericTypeName->size() > 0) {
186 
187  // Registered in RegisterStandardScriptEvents
188  continue;
189  }
190 
191  // Skip global events
192  EVENT_TYPE etype = ResolveStringToType(*containedlisteners[i]->ListenerName);
193 
194  // Skip types that we handle ourselves //
195  if(etype == EVENT_TYPE_ERROR)
196  etype = GetCommonEventType(*containedlisteners[i]->ListenerName);
197 
198  if(etype != EVENT_TYPE_ERROR) {
199 
200  continue;
201  }
202 
203  Logger::Get()->Warning("GameModule: unknown event type " +
204  *containedlisteners[i]->ListenerName +
205  ", did you intent to use Generic type?");
206  }
207 
208  // Call init callbacks //
209 
210  // fire an event //
211  Event* initEvent = new Event(EVENT_TYPE_INIT, nullptr);
212  OnEvent(initEvent);
213  // Release our initial reference
214  initEvent->Release();
215 
216  return true;
217 }
DLLEXPORT asIScriptModule * GetModule(Lock &guard)
Builds the script if applicable.
Class that represents a statically defined event.
Definition: Event.h:128
EVENT_TYPE
Engine events that are triggered at certain times.
Definition: Event.h:13
static DLLEXPORT ScriptExecutor * Get()
DLLEXPORT void Warning(const std::string &data) override
Definition: Logger.cpp:190
FORCE_INLINE void Release()
removes a reference and deletes the object if reference count reaches zero
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
DLLEXPORT void Error(const std::string &data) override
Definition: Logger.cpp:177

◆ REFERENCE_COUNTED_PTR_TYPE()

Leviathan::GameModule::REFERENCE_COUNTED_PTR_TYPE ( GameModule  )

◆ ReleaseScript()

DLLEXPORT void GameModule::ReleaseScript ( )

Releases the script.

Use to release script before releasing any other objects

Definition at line 219 of file GameModule.cpp.

220 {
221  // Call release callback and destroy everything //
222  // fire an event //
223  Event* releaseEvent = new Event(EVENT_TYPE_RELEASE, nullptr);
224  OnEvent(releaseEvent);
225  // Release our initial reference
226  releaseEvent->Release();
227 
228  // Remove our reference //
229  int tmpid = Scripting->GetModule()->GetID();
230  Scripting.reset();
231 
233 }
Class that represents a statically defined event.
Definition: Event.h:128
static DLLEXPORT ScriptExecutor * Get()
DLLEXPORT bool DeleteModuleIfNoExternalReferences(int ID)
FORCE_INLINE void Release()
removes a reference and deletes the object if reference count reaches zero

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