Core class managing AngelScript initialization, contexts, and instance tracking.
srph::Engine scripting;
srph::EngineConfiguration config;
config.scriptTimeoutMillis = 1000.0f;
scripting.Initialize(config);| Method | Description |
|---|---|
void Initialize(EngineConfiguration config) |
Initialize AngelScript engine with configuration |
void Shutdown() |
Release all resources, modules, and instances |
void AttachDebugger() |
Attach VSCode-compatible DAP debugger |
void StopDebugger() |
Detach debugger |
bool Built() const |
Returns true if scripts compiled successfully |
void Namespace(const std::string& ns) |
Set default namespace for subsequent registrations |
void GeneratePredefined(const std::string& path) |
Generate as.predefined for LSP autocompletion |
void RegisterTimeoutCallback(std::function<void()> f) |
Callback invoked when script execution times out |
All registration uses builder pattern via srph::TypeRegistration::* classes.
Stack-allocated types that are copied. Cannot use handles.
srph::TypeRegistration::Class<glm::vec3, srph::ClassType::Value>(engine, "vec3")
.BehavioursByTraits() // Auto-register ctor/dtor/copy/assign
.Constructor<float>("float scalar") // Custom constructor
.Constructor<float, float, float>("float x, float y, float z")
.Property("float x", offsetof(glm::vec3, x))
.Property("float y", offsetof(glm::vec3, y))
.Property("float z", offsetof(glm::vec3, z))
.Operator(SRPH_OPERATOR(glm::operator+, (const vec3&, const vec3&), vec3),
srph::TypeRegistration::OperatorType::Add, "vec3", "vec3")
.Operator(SRPH_OPERATOR_MEMBER(vec3, operator+=, (const vec3&), vec3&),
srph::TypeRegistration::OperatorType::AddAssign, "vec3", "vec3");Heap-allocated types supporting handles (@).
srph::TypeRegistration::Class<Transform, srph::ClassType::Reference>(engine, "Transform", asOBJ_NOCOUNT)
.OperatorAssign()
.Method("vec3 GetPosition()", &Transform::GetPosition)
.Method("void SetPosition(const vec3&in)", &Transform::SetPosition)
.Property("vec3 position", offsetof(Transform, position));| Method | Description |
|---|---|
BehavioursByTraits() |
Auto-register default ctor, dtor, copy ctor, assign based on C++ type traits |
DefaultConstructor() |
Register default constructor |
CopyConstructor() |
Register copy constructor |
Destructor() |
Register destructor |
OperatorAssign() |
Register assignment operator |
Constructor<Args...>(const char* decl) |
Register constructor with specified parameter types |
Property(const std::string& decl, size_t offset) |
Register member variable |
Method(const char* decl, MemberFnPtr method) |
Register member function |
Method(const std::string& decl, Lambda func) |
Register method via lambda (receives T& as first arg) |
Operator(asSFuncPtr, OperatorType, returnType, paramType) |
Register operator overload |
Behaviour(asEBehaviours, const char* decl, asSFuncPtr, asDWORD callConv) |
Register custom behaviour |
// Free function operator
SRPH_OPERATOR(glm::operator+, (const vec3&, const vec3&), vec3)
// Member function operator
SRPH_OPERATOR_MEMBER(vec3, operator+=, (const vec3&), vec3&)Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign
Automatic registration via magic_enum.
// Uses enum type name
srph::TypeRegistration::Enum<KeyCode>(engine).Register();
// Custom name
srph::TypeRegistration::Enum<KeyCode>(engine).Name("Key").Register();With namespaces:
engine->Namespace("Input");
srph::TypeRegistration::Enum<Input::KeyCode>(engine).Register();
// Registers as Input::KeyCodeDefine required methods for script classes.
srph::TypeRegistration::Interface(engine, "IAngelBehaviour")
.Method("void Start()")
.Method("void Update(float dt)");Script implementation:
class Player : IAngelBehaviour {
void Start() { }
void Update(float dt) { }
}Register free functions callable from any script.
engine->Namespace("Math");
srph::TypeRegistration::Global(engine)
.Function("float sin(float)", [](float x) { return std::sin(x); })
.Function("float cos(float)", [](float x) { return std::cos(x); })
.Function("float lerp(float, float, float)",
[](float a, float b, float t) { return a + t * (b - a); });srph::ScriptLoader loader(&engine);
loader.Module("Game")
.LoadScript("scripts/player.as")
.LoadScript("scripts/enemy.as");
if (loader.Build()) {
// Compilation successful
} else {
// Errors logged via MessageCallback
}| Method | Description |
|---|---|
Module(const std::string& name) |
Set target module name |
LoadScript(const std::string& path) |
Add script file to compilation |
bool Build() |
Compile all added scripts, returns success |
Builder pattern for invoking script functions and methods.
srph::FunctionCaller(&engine)
.Module("Game")
.Function("void Update(float)", instanceHandle)
.Push(deltaTime)
.Call();srph::FunctionCaller(&engine)
.Module("Game")
.Function("void Initialize()")
.Call();srph::FunctionCaller(&engine)
.Module("Game")
.Function("void OnCollision()", handle, srph::FunctionPolicy::Optional)
.Call();
// No error if function doesn't existsrph::FunctionResult result = srph::FunctionCaller(&engine)
.Module("Game")
.Factory("Enemy@ Enemy(const vec3&in)", typeInfo)
.Push(spawnPosition)
.Call(srph::ReturnType::Object);
asIScriptObject* obj = std::get<asIScriptObject*>(result.value);Byte, Word, DWord, QWord, Float, Double, Object
| Method | Description |
|---|---|
Module(const std::string& name) |
Set module to search |
Function(const std::string& sig, InstanceHandle, FunctionPolicy) |
Prepare function/method call |
Factory(const std::string& decl, const std::string& typeName) |
Prepare factory (constructor) call |
Push<T>(T value) |
Push argument (primitives and registered types) |
void Call() |
Execute without return value |
FunctionResult Call(ReturnType) |
Execute and retrieve return value |
Retrieve property information from script instances at runtime.
std::vector<srph::ReflectedProperty> props = engine.Reflect(handle);
for (auto& prop : props) {
// prop.type - "int", "float", "vec3", etc.
// prop.name - property name
// prop.data - void* to actual data (read/write)
}std::vector<srph::ReflectedProperty> serialized = engine.Reflect(handle, "Serialize");
std::vector<srph::ReflectedProperty> editorVisible = engine.Reflect(handle, "ShowInInspector");Script with metadata:
class Player : IAngelBehaviour {
[Serialize]
int health = 100;
[ShowInInspector]
float speed = 5.0f;
[Serialize] [ShowInInspector]
vec3 position;
int internalState; // Not reflected with metadata filter
}struct ReflectedProperty {
std::string type; // AngelScript type name
std::string name; // Property name
void* data; // Pointer to value (cast to appropriate type)
};for (auto& field : engine.Reflect(handle, "ShowInInspector")) {
if (field.type == "int") {
int* val = static_cast<int*>(field.data);
// Read or write *val
} else if (field.type == "float") {
float* val = static_cast<float*>(field.data);
} else if (field.type == "vec3") {
glm::vec3* val = static_cast<glm::vec3*>(field.data);
}
}std::vector<std::string> meta = engine.GetMetadata("Player", "health");
// Returns {"Serialize"} for the example aboveDefault constructor:
srph::InstanceHandle handle = engine.CreateInstance("Player", "Game");Custom constructor via factory:
srph::FunctionCaller factory(&engine);
factory.Module("Game").Factory("Enemy@ Enemy(const vec3&in)", "Enemy").Push(spawnPos);
srph::InstanceHandle handle = engine.CreateInstance(factory);asIScriptObject* obj = engine.GetNativeObject(handle);Returns the underlying AngelScript object pointer. Use with caution, because caller is responsible for AddRef()/Release() if retaining the pointer.
struct InstanceHandle {
InstanceID id;
bool Valid() const;
};// Get type name
std::string name = engine.GetTypeName(handle);
// Get all active instances
std::vector<srph::InstanceHandle> instances = engine.GetInstances();
// Query classes implementing interface
std::vector<std::string> behaviours = engine.QueryImplementations("IAngelBehaviour", "Game");
// Query derived classes
std::vector<std::string> enemies = engine.QueryDerivedClasses("BaseEnemy", "Game");Register method to retrieve scripts from entities:
srph::TypeRegistration::Class<UUID, srph::ClassType::Value>(engine, "Entity", asOBJ_POD)
.Method("IAngelBehaviour@ GetScript(const string&in)",
[](const UUID& entity, const std::string& scriptName) -> asIScriptObject* {
// Lookup and return script instance
// Must call obj->AddRef() before returning
});Script usage:
Entity target = GetTarget();
Health@ health = cast<Health>(target.GetScript("Health"));
health.Damage(10);Errors reported via MessageCallback during ScriptLoader::Build():
[ERROR] scripts/player.as:15,8: 'speed' is not declared
Exceptions logged automatically with file, line, column:
Exception 'Null pointer access' in scripts/enemy.as:42,12 while calling method Enemy::Update
Configure via EngineConfiguration::scriptTimeoutMillis. Register callback:
engine.RegisterTimeoutCallback([]() {
// Handle timeout (e.g., stop game, show error)
});Generate autocompletion data:
engine.GeneratePredefined("path/to/as.predefined");Attach DAP debugger:
engine.AttachDebugger();
// Debugger listens for VSCode connectionRequires the Seraph Debugger extension.