Skip to content

EmilianC/Loupe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Loupe Logo

An extendible reflection library for modern C++, designed with game development in mind.

Design goals

Loupe's API is designed to be small and easy to use. Instead of scanning pre-main, Loupe produces your application's reflection tables when requested - you may store the result of this globally if you wish. Your reflection tables can be serialized to disk along with your data, allowing you to read data back safely even as your application continues to change.

The core Loupe API does not require Run-Time Type Information (RTTI) or Exceptions, and is dependent only on the C++ standard library. Serialization backends should be implemented user-side so that you can chose your own archiver and better handle custom data. However, an archiver using Cereal is provided by default (which can at least serve as an example for creating your own).

1.0 Target Features

  • Diff between blobs to detect and reconcile changes
  • Support for standard containers (vector, array, map, set, etc.)
  • Support for user defined containers
  • Reflecting getters + setters
  • Serialization ready (bring your own archiver)
  • User-defined metadata attributes

Post 1.0 Features

  • Reflecting and invoking functions
  • Single header include option
  • Blob coverage detection, serializing only visited properties
  • Support beyond the Windows platform
  • Debugger .natvis files
  • Support for custom allocators
  • Stateful Metadata (such as a range bound for floats)

Quick Usage

//-- data.h --//
struct hidden {};

enum class small_enum : uint16_t
{
	value0,
	value1,
	COUNT
};

struct vec4
{
	float x = 0.0f;
	float y = 0.0f;
	float z = 0.0f;
	float w = 1.0f;
};


//-- data.cpp --//
#include "loupe.h"

// Metadata tags must also be reflected.
REFLECT_SIMPLE(hidden);

REFLECT(small_enum) ENUM_VALUES {
	REF_VALUE(value0)
	REF_VALUE(value1)
	REF_VALUE(COUNT, hidden)
} REF_END;

REFLECT(vec4) MEMBERS {
	REF_MEMBER(x)
	REF_MEMBER(y)
	REF_MEMBER(z)
	REF_MEMBER(w, hidden)
} REF_END;


//-- main.cpp --//
#include "data.h"
#include "loupe.h"

int main()
{
	loupe::reflection_blob blob = loupe::reflect();
	// Reclaim a little memory if you don't plan on calling reflect() again.
	loupe::clear_reflect_tasks();

	const loupe::type* descriptor = blob.find("small_enum");
	// Direct type category access.
	const loupe::enumeration& data = std::get<loupe::enumeration>(descriptor->data);
	for (const loupe::enum_entry& entry : data.entires)
	{
		print(entry.name);                   // "value0", "value1", "COUNT"
		print(entry.value);                  //  0,        1,        2
		print(entry.has_metadata<hidden>()); // "false",  "false",  "true"
	}

	// Type lookup can also be done directly with known types.
	const loupe::type* vec4_type = blob.find<vec4>();
	// Visitation can respond to any of the type categories.
	vec4_type->visit(
		[&](const loupe::fundamental& data) { /*...*/ },
		[&](const loupe::structure& data) {
			const loupe::property* float_property = blob.find_property<float>();
			for (const loupe::member& member : data.members)
			{
				print(member.name);                   // "x",     "y",     "z",     "w"
				print(member.offset);                 //  0,       4,       8,       12
				print(member.data == float_property); // "true",  "true",  "true",  "true"
				print(member.has_metadata<hidden>()); // "false", "false", "false", "true"
			}
		},
		[&](const loupe::enumeration& data) { /*...*/ }
	);
}

Default Serialization Dependencies

Test Project Dependencies

About

An extendible reflection library for modern C++ with metadata support - designed with game development in mind.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published