C++ Logo

sg7

Advanced search

Re: Request for supporting and enumerating user-defined attributes

From: Corentin Jabot <corentinjabot_at_[hidden]>
Date: Mon, 16 Oct 2023 06:58:00 +0200
You might be interested in https://wg21.link/p1887 which is an old paper of
mine on that topic. I'm not sure it aged well though.

I do agree that reflection on attribute would be useful but it's a
surprisingly open design space.
We probably want a slightly different syntax because user defined
attributes should not be ignorable, they should be declared, have arguments
of defined types and so forth.

Then there is the question of whether they can act a bit like decorators.

So because all of this needs a more throughout exploration it seems
reasonable to me to not propose them as part of an initial effort. But I do
hope we end up there.




On Mon, Oct 16, 2023, 04:59 Jeremy Ong via SG7 <sg7_at_[hidden]> wrote:

> First, a hearty thanks to the authors of P2996R0 (
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2996r0.html).
>
> One item that appeared to be absent from the discussion is the notion of
> user-defined attributes. My feedback largely stems from the games industry,
> where virtually every game and game engine employs reflection to some
> degree, but I suspect that these use cases generalize well. To be clear,
> the intent isn't to wave my hands and create work, but hopefully to offer a
> different perspective regarding how custom C++ serialization is used in the
> games industry today.
>
> Given a data struct, this type of pattern will be seen in many game
> engines (fairly contrived pseudocode):
>
> ```
> class PlayerState
> {
> public:
> // This is a member function that is exposed to gameplay scripts
> automatically (e.g. Lua)
> [[scriptable]]
> void teleport(float3 position);
>
> // This is a property that is serialized when the player is serialized.
> // In addition, when the property changes, the changes are replicated
> across the network
> // for multiplayer games.
> [[serializable]]
> [[client_server]]
> int health;
>
> // ...
> };
> ```
>
> The functionality above is generally provided by some sort of compiler
> extension or (more commonly) a custom parser/preprocessing step. The idea
> is to embed additional metadata about member variables, functions, and
> types that are used across the build and tooling ecosystem. Other examples
> of such attributes that I've seen:
>
> - A "client only" or "server only" attribute used to control how and where
> data is replicated for multiplayer games
> - An "editor function" attribute used to indicate that a function should
> be bound to the engine's scripting context
> - A "gpu constant" attribute used to inform the build system to validate
> that the member alignments match the layout expected by the GPU
> - A "description" attribute used to populate tooltips and help text for a
> given enum field, member variable, or function.
> A "quantization" attribute used to indicate that on serialization, the
> value may be compressed/packed.
>
> These are just a few examples among hundreds of attributes that I have
> encountered across multiple large-scale game engines at multiple companies.
> Notice also that some attributes given in the last couple of examples are
> parameterized to accept a value as well (e.g. [[description = "some helpful
> text"]]).
>
> To give more concrete examples, here are example attributes supported by
> Unreal Engine (which they refer to as "specifiers"):
>
> - Class attributes:
> https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/GameplayArchitecture/Classes/Specifiers/
> - Function attributes:
> https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/GameplayArchitecture/Functions/Specifiers/
> - Property attributes:
> https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/GameplayArchitecture/Properties/Specifiers/
> - Struct attributes:
> https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/GameplayArchitecture/Structs/Specifiers/
>
> Such systems are sufficiently mature that I don't think anyone could
> reasonably expect the first real incarnation of C++ reflection to cover all
> existing use-cases, but perhaps such examples in the wild may be useful in
> motivating additional feature coverage. I think even just non-parameterized
> attributes supported by the splice and meta concepts introduced in the
> reflection proposal would get significant mileage and go a long way towards
> eventually deprecating existing custom pre-compiler frontends.
>
> Thanks for reading,
> Jeremy
> --
> SG7 mailing list
> SG7_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg7
>

Received on 2023-10-16 04:58:12