Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

as-reflect
Runtime reflection add-on for AngelScript

C++17 MIT License API

as-reflect

Runtime reflection add-on for AngelScript. Inspect script class properties, read and write field values, and invoke methods dynamically: all from within script, under the reflect namespace.

Overview

as-reflect exposes a small reflection API to AngelScript scripts. Given any object, you can enumerate and change its properties and call methods. It is built for tooling that needs to operate on script types generically: serializers, editor inspectors, or save systems.

Features

  • Type introspection - reflect::TypeOf(obj) returns a Type describing the object.
  • Property access - enumerate properties, read declared type and name.
  • Value get/set - read field values with Get<T>(), write with Set(value), type-checked at runtime using Is<T>.
  • Method invocation - look up methods by signature, invoke with arguments, capture return values.

Usage

Inspecting properties

class Player {
    int   health;
    float speed;
    Vec3  position;
}

Player p;
p.health = 100;

reflect::Type@ t = reflect::TypeOf(p);
print(t.GetName());                     // "Player"

auto@ props = t.GetProperties();
for (uint i = 0; i < props.length(); i++) {
    reflect::Property@ prop = props[i];
    print(prop.GetName() + " : " + prop.GetType().GetName());
}

Reading and writing values

reflect::Value@ v = props[0].GetValue(p);

if (v.Is<int>()) {
    // Read value
    int hp = v.Get<int>();

    // Type-safe write
    v.Set(50);
}

Get<T>() returns a copy for value types and primitives, and aliasing handle (Get<T@>) for reference types.

Invoking methods

class Calculator {
    int Add(int a, int b) { return a + b; }
    void Reset() {}
}

Calculator c;
reflect::Type@ t = reflect::TypeOf(c);

// Look up by full signature
reflect::Value@ result = t.GetMethod("int Add(int, int)").Invoke(c, 2, 3);
if (result !is null && result.Is<int>()) {
    print("" + result.Get<int>());   // 5
}

// Void method returns a non-null (void typed) Value on success
reflect::Value@ ok = t.GetMethod("void Reset()").Invoke(c);

Invoke returns a Value@:

  • null means that the call failed (wrong argument count or type).
  • non-null, void-typed means that a void method succeeded.
  • non-null, typed gives the returned value.

Methods are resolved by exact signature, so overloads are selected correctly:

t.GetMethod("void Set(int)").Invoke(obj, 42);
t.GetMethod("void Set(bool)").Invoke(obj, true);

Building

as-reflect is a single .h and a .cpp file. Register the API against your engine after registering the string and array add-ons (these are unfortunately a dependency I rely on as of now):

#include "as-reflect.hpp"

RegisterStdString(engine);
RegisterScriptArray(engine, true);
RegisterAsReflect(engine);

Limitations

  • The generic registration is not finished.
  • Script reference types cannot be returned by value from Invoke. You need to use handle returns (T@).
  • Static methods and free functions are not yet supported, all invokes need an instance.
  • Enum, container (array, ...) reflection, and construction (instantiating a type by name) are not yet implemented.
  • Metadata readback is not implemented.

License

MIT

About

Runtime reflection add-on for AngelScript: enumerate types, read/write properties, and call methods dynamically

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages