Leviathan  0.8.0.0
Leviathan game engine
Leviathan::ScriptComponentHolder Class Reference

#include <ScriptComponentHolder.h>

+ Inheritance diagram for Leviathan::ScriptComponentHolder:

Public Member Functions

DLLEXPORT ~ScriptComponentHolder ()
 
DLLEXPORT bool ReleaseComponent (ObjectID entity)
 Releases a single component. More...
 
DLLEXPORT void ReleaseAllComponents ()
 Releases all components. More...
 
DLLEXPORT asIScriptObject * Create (ObjectID entity)
 Creates a new component of held type. More...
 
DLLEXPORT asIScriptObject * Find (ObjectID entity)
 Finds a component for entity. More...
 
DLLEXPORT bool Destroy (ObjectID entity)
 Destroys a component of held type for entity. More...
 
DLLEXPORT CScriptArray * GetIndex () const
 Returns all the created components. More...
 
const auto & GetRemoved () const
 Returns a reference to the vector of removed elements. More...
 
auto & GetAdded ()
 Returns a reference to the vector of added elements. More...
 
void ClearAdded ()
 Clears the added list. More...
 
void ClearRemoved ()
 Clears the removed list. More...
 
 REFERENCE_COUNTED_PTR_TYPE (ScriptComponentHolder)
 
- 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...
 

Public Attributes

const std::string ComponentType
 

Protected Member Functions

DLLEXPORT ScriptComponentHolder (const std::string &name, asIScriptFunction *factory, GameWorld *world)
 
- Protected Member Functions inherited from Leviathan::ReferenceCounted
DLLEXPORT ReferenceCounted ()
 
virtual DLLEXPORT ~ReferenceCounted ()
 

Protected Attributes

friend 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

Todo:
Allow defining if release should be called on the script object. and then calling it now only the object is dereferenced so that it probably gets garbage collected soon

Definition at line 18 of file ScriptComponentHolder.h.

Constructor & Destructor Documentation

◆ ScriptComponentHolder()

DLLEXPORT ScriptComponentHolder::ScriptComponentHolder ( const std::string &  name,
asIScriptFunction *  factory,
GameWorld world 
)
protected
Note
This expects that caller has increased factory refcount
Parameters
worldPointer to world that is passed to the script factory

Definition at line 12 of file ScriptComponentHolder.cpp.

13  :
14  ComponentType(name),
15  Factory(factory), World(world)
16 {
17  if(!Factory)
18  throw InvalidArgument("ScriptComponentHolder not given a factory function");
19 }

◆ ~ScriptComponentHolder()

DLLEXPORT ScriptComponentHolder::~ScriptComponentHolder ( )

Definition at line 21 of file ScriptComponentHolder.cpp.

22 {
23  // Make sure all are released
25 
26  Factory->Release();
27 
28  LEVIATHAN_ASSERT(CreatedObjects.empty(), "ScriptComponentHolder didn't properly clear");
29 }
DLLEXPORT void ReleaseAllComponents()
Releases all components.

Member Function Documentation

◆ ClearAdded()

void Leviathan::ScriptComponentHolder::ClearAdded ( )
inline

Clears the added list.

Definition at line 79 of file ScriptComponentHolder.h.

80  {
81  Added.clear();
82  }

◆ ClearRemoved()

void Leviathan::ScriptComponentHolder::ClearRemoved ( )
inline

Clears the removed list.

Definition at line 85 of file ScriptComponentHolder.h.

86  {
87  Removed.clear();
88  }

◆ Create()

DLLEXPORT asIScriptObject * ScriptComponentHolder::Create ( ObjectID  entity)

Creates a new component of held type.

Note
Increases refcount on returned object
Warning
Some script components need Init to be called on them afterwards, so you must cast this to the child type and call Init on it. See CustomScriptComponentTest.as file in the Scripts/tests directory

Definition at line 73 of file ScriptComponentHolder.cpp.

74 {
75  // Fail if already exists //
76  asIScriptObject* found = Find(entity);
77  if(found != nullptr) {
78 
79  LOG_WARNING("ScriptComponentHolder: Create: called for existing component, id: " +
80  std::to_string(entity));
81 
82  // Must release reference
83  found->Release();
84  return nullptr;
85  }
86 
87  ScriptRunningSetup setup;
88 
89  auto result = static_cast<ScriptExecutor*>(Factory->GetEngine()->GetUserData())
90  ->RunScript<asIScriptObject*>(Factory, nullptr, setup, World);
91 
92  if(result.Result != SCRIPT_RUN_RESULT::Success || result.Value == nullptr) {
93 
94  LOG_ERROR("ScriptComponentHolder: Create: failed to run the angelscript factory "
95  "function for this type (" +
96  ComponentType + ")");
97  return nullptr;
98  }
99 
100  Added.push_back(std::make_tuple(result.Value, entity));
101 
102  // Remove from removed if there //
103  for(auto iter = Removed.begin(); iter != Removed.end(); ++iter) {
104 
105  if(std::get<1>(*iter) == entity) {
106 
107  std::iter_swap(iter, Removed.rbegin());
108  Removed.pop_back();
109  break;
110  }
111  }
112 
113  // Remember that we take a reference to it
114  result.Value->AddRef();
115 
116  CreatedObjects[entity] = result.Value;
117 
118  // And we return it so increase refcount for that too //
119  result.Value->AddRef();
120  return result.Value;
121 }
DLLEXPORT asIScriptObject * Find(ObjectID entity)
Finds a component for entity.
#define LOG_ERROR(x)
Definition: Define.h:83
Handles ScriptModule creation and AngelScript code execution.
#define LOG_WARNING(x)
Definition: Define.h:82

◆ Destroy()

DLLEXPORT bool Leviathan::ScriptComponentHolder::Destroy ( ObjectID  entity)
inline

Destroys a component of held type for entity.

Note
This is just a wrapper for ReleaseComponent to be more consistent with c++ component types

Definition at line 54 of file ScriptComponentHolder.h.

54  {
55  return ReleaseComponent(entity);
56  }
DLLEXPORT bool ReleaseComponent(ObjectID entity)
Releases a single component.

◆ Find()

DLLEXPORT asIScriptObject * ScriptComponentHolder::Find ( ObjectID  entity)

Finds a component for entity.

Note
Increases refcount on returned object

Definition at line 123 of file ScriptComponentHolder.cpp.

124 {
125  auto iter = CreatedObjects.find(entity);
126 
127  if(iter == CreatedObjects.end())
128  return nullptr;
129 
130  iter->second->AddRef();
131  return iter->second;
132 }

◆ GetAdded()

auto& Leviathan::ScriptComponentHolder::GetAdded ( )
inline

Returns a reference to the vector of added elements.

Definition at line 73 of file ScriptComponentHolder.h.

74  {
75  return Added;
76  }

◆ GetIndex()

DLLEXPORT CScriptArray * ScriptComponentHolder::GetIndex ( ) const

Returns all the created components.

Caller must release reference

Todo:
Check can we somehow return all the keys and the objects to avoid having to call Find from scripts after this

Definition at line 134 of file ScriptComponentHolder.cpp.

135 {
136  asIScriptContext* ctx = asGetActiveContext();
137 
138  asIScriptEngine* engine = ctx ? ctx->GetEngine() : ScriptExecutor::Get()->GetASEngine();
139 
140  return ConvertIteratorToASArray((CreatedObjects | boost::adaptors::map_keys).begin(),
141  (CreatedObjects | boost::adaptors::map_keys).end(), engine, "array<ObjectID>");
142 }
DLLEXPORT asIScriptEngine * GetASEngine()
CScriptArray * ConvertIteratorToASArray(T begin, T end, asIScriptEngine *engine, const char *arraytype=nullptr)
Variant that converts from iterator range to an AngelScript array.
static DLLEXPORT ScriptExecutor * Get()

◆ GetRemoved()

const auto& Leviathan::ScriptComponentHolder::GetRemoved ( ) const
inline

Returns a reference to the vector of removed elements.

Definition at line 67 of file ScriptComponentHolder.h.

68  {
69  return Removed;
70  }

◆ REFERENCE_COUNTED_PTR_TYPE()

Leviathan::ScriptComponentHolder::REFERENCE_COUNTED_PTR_TYPE ( ScriptComponentHolder  )

◆ ReleaseAllComponents()

DLLEXPORT void ScriptComponentHolder::ReleaseAllComponents ( )

Releases all components.

Definition at line 60 of file ScriptComponentHolder.cpp.

61 {
62  for(auto iter = CreatedObjects.begin(); iter != CreatedObjects.end(); ++iter) {
63 
64  // TODO: also call release here
65  iter->second->Release();
66  }
67 
68  CreatedObjects.clear();
69  Added.clear();
70  Removed.clear();
71 }

◆ ReleaseComponent()

DLLEXPORT bool ScriptComponentHolder::ReleaseComponent ( ObjectID  entity)

Releases a single component.

Note
If a script is holding a reference to the object it may not be released yet
Returns
True if object existed and was released

Definition at line 31 of file ScriptComponentHolder.cpp.

32 {
33  auto iter = CreatedObjects.find(entity);
34 
35  if(iter == CreatedObjects.end())
36  return false;
37 
38  Removed.push_back(std::make_tuple(iter->second, entity));
39 
40  // Remove from added if there //
41  for(auto iter = Added.begin(); iter != Added.end(); ++iter) {
42 
43  if(std::get<1>(*iter) == entity) {
44 
45  std::iter_swap(iter, Added.rbegin());
46  Added.pop_back();
47  break;
48  }
49  }
50 
51  // TODO: call release on the actual script object to let it do shutdown stuff
52  // Release our reference to let the object be destroyed once all references are released
53  iter->second->Release();
54 
55  CreatedObjects.erase(iter);
56 
57  return true;
58 }

Member Data Documentation

◆ ComponentType

const std::string Leviathan::ScriptComponentHolder::ComponentType

Definition at line 93 of file ScriptComponentHolder.h.

◆ ReferenceCounted

friend Leviathan::ScriptComponentHolder::ReferenceCounted
protected

Definition at line 22 of file ScriptComponentHolder.h.


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