Leviathan  0.8.0.0
Leviathan game engine
Leviathan::NonOwningScriptCallback Class Reference

A helper for keeping a weak reference to a script delegate or function. More...

#include <NonOwningScriptCallback.h>

Public Member Functions

 NonOwningScriptCallback (asIScriptFunction *callback=nullptr)
 
 ~NonOwningScriptCallback ()
 
void SetCallback (asIScriptFunction *callback)
 Sets the bound function / delegate. More...
 
template<typename ReturnT , class... Args>
ScriptRunResult< ReturnT > Run (ScriptRunningSetup &setup, Args &&... args)
 
bool HasCallback () const
 
void Reset ()
 

Detailed Description

A helper for keeping a weak reference to a script delegate or function.

Useful for breaking circular references without implementing container semantics

Definition at line 13 of file NonOwningScriptCallback.h.

Constructor & Destructor Documentation

◆ NonOwningScriptCallback()

NonOwningScriptCallback::NonOwningScriptCallback ( asIScriptFunction *  callback = nullptr)

Definition at line 7 of file NonOwningScriptCallback.cpp.

8 {
9  if(callback)
10  SetCallback(callback);
11 }
void SetCallback(asIScriptFunction *callback)
Sets the bound function / delegate.

◆ ~NonOwningScriptCallback()

NonOwningScriptCallback::~NonOwningScriptCallback ( )

Definition at line 13 of file NonOwningScriptCallback.cpp.

14 {
15  _ReleaseCallback();
16 }

Member Function Documentation

◆ HasCallback()

bool Leviathan::NonOwningScriptCallback::HasCallback ( ) const
inline

Definition at line 78 of file NonOwningScriptCallback.h.

79  {
80  return Callback != nullptr;
81  }

◆ Reset()

void Leviathan::NonOwningScriptCallback::Reset ( )
inline

Definition at line 83 of file NonOwningScriptCallback.h.

84  {
85  _ReleaseCallback();
86  }

◆ Run()

template<typename ReturnT , class... Args>
ScriptRunResult<ReturnT> Leviathan::NonOwningScriptCallback::Run ( ScriptRunningSetup setup,
Args &&...  args 
)
inline
Note
setup is mainly ignored, only error reporting properties are used
Todo:
It might be possible to just keep this locked while calling the method instead of increasing and decrementing the reference count

Definition at line 25 of file NonOwningScriptCallback.h.

26  {
27  if(!Callback)
28  return ScriptRunResult<ReturnT>(SCRIPT_RUN_RESULT::Error);
29 
30  // Normal function
31  if(!CallbackObject) {
32  return ScriptExecutor::Get()->RunScript<ReturnT>(
33  Callback, nullptr, setup, std::forward<Args>(args)...);
34  } else {
35  // Delegate
36  if(DelegateObjectWeak) {
37 
38  // Must ensure that the object will be alive.
39 
40  // To atomically get a reference to the object we must lock the weak flag
41  DelegateObjectWeak->Lock();
42  if(!DelegateObjectWeak->Get()) {
43  asIScriptEngine* engine = CallbackObjectType->GetEngine();
44 
45  // It might be possible to just keep this locked while calling the method
46  // instead of increasing and decrementing the reference count
47  engine->AddRefScriptObject(CallbackObject, CallbackObjectType);
48 
49  DelegateObjectWeak->Unlock();
50 
51 
52  const auto result = ScriptExecutor::Get()->RunScriptMethod<ReturnT>(
53  setup, Callback, CallbackObject, std::forward<Args>(args)...);
54 
55  // Release the reference we added
56  engine->ReleaseScriptObject(CallbackObject, CallbackObjectType);
57 
58  return result;
59  }
60 
61  DelegateObjectWeak->Unlock();
62 
63  LOG_WARNING("NonOwningScriptCallback: delegate object is no longer alive. "
64  "Resetting state");
65  _ReleaseCallback();
66 
67  return ScriptRunResult<ReturnT>(SCRIPT_RUN_RESULT::Error);
68 
69  } else {
70 
71  // Strong refernce is used
72  return ScriptExecutor::Get()->RunScriptMethod<ReturnT>(
73  setup, Callback, CallbackObject, std::forward<Args>(args)...);
74  }
75  }
76  }
ScriptRunResult< ReturnT > RunScript(const std::shared_ptr< ScriptModule > &module, ScriptRunningSetup &parameters, Args &&... args)
Runs a function in a script.
#define LOG_WARNING(x)
Definition: Define.h:93
static DLLEXPORT ScriptExecutor * Get()
ScriptRunResult< ReturnT > RunScriptMethod(ScriptRunningSetup &parameters, asIScriptFunction *func, void *obj, Args &&... args)
Runs a method in a script.

◆ SetCallback()

void NonOwningScriptCallback::SetCallback ( asIScriptFunction *  callback)

Sets the bound function / delegate.

Definition at line 48 of file NonOwningScriptCallback.cpp.

49 {
50  if(Callback)
51  _ReleaseCallback();
52 
53  if(!callback)
54  return;
55 
56  if(callback->GetFuncType() == asFUNC_DELEGATE) {
57 
58  asIScriptEngine* engine = callback->GetEngine();
59 
60  // Keep a hold of the type
61  CallbackObjectType = callback->GetDelegateObjectType();
62  CallbackObjectType->AddRef();
63 
64  // Hold a weak reference to the object if possible
65  CallbackObject = callback->GetDelegateObject();
66 
67  DelegateObjectWeak =
68  engine->GetWeakRefFlagOfScriptObject(CallbackObject, CallbackObjectType);
69 
70  // If not possible to have a weak reference hold a strong reference
71  if(!DelegateObjectWeak) {
72  LOG_WARNING("NonOwningScriptCallback: SetCallback: passed a delegate of an object "
73  "type that "
74  "doesn't support weak references, this reference won't be non-owning");
75  engine->AddRefScriptObject(CallbackObject, CallbackObjectType);
76  } else {
77  DelegateObjectWeak->AddRef();
78  }
79 
80  // Hold on to the method strongly
81  Callback = callback->GetDelegateFunction();
82  Callback->AddRef();
83 
84  // And release our reference to the delegate
85  callback->Release();
86 
87  } else {
88 
89  Callback = callback;
90  }
91 }
#define LOG_WARNING(x)
Definition: Define.h:93

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