diff --git a/src/xrt/auxiliary/util/u_builders.c b/src/xrt/auxiliary/util/u_builders.c index bafdbc16f..4868b9116 100644 --- a/src/xrt/auxiliary/util/u_builders.c +++ b/src/xrt/auxiliary/util/u_builders.c @@ -13,6 +13,7 @@ #include "util/u_debug.h" #include "util/u_builders.h" +#include "util/u_system_helpers.h" #include "util/u_space_overseer.h" @@ -180,3 +181,79 @@ u_builder_create_space_overseer_legacy(struct xrt_device *head, *out_xso = (struct xrt_space_overseer *)uso; } + +xrt_result_t +u_builder_roles_helper_open_system(struct xrt_builder *xb, + cJSON *config, + struct xrt_prober *xp, + struct xrt_system_devices **out_xsysd, + struct xrt_space_overseer **out_xso, + u_builder_open_system_fn fn) +{ + struct u_builder_roles_helper ubrh = XRT_STRUCT_INIT; + xrt_result_t xret; + + // Use the static system devices helper, no dynamic roles. + struct u_system_devices_static *usysds = u_system_devices_static_allocate(); + struct xrt_tracking_origin *origin = &usysds->base.origin; + struct xrt_system_devices *xsysd = &usysds->base.base; + struct xrt_frame_context *xfctx = &usysds->base.xfctx; + + xret = fn( // + xb, // xb + config, // config + xp, // xp + origin, // origin + xsysd, // xsysd + xfctx, // xfctx + &ubrh); // ubrh + if (xret != XRT_SUCCESS) { + xrt_system_devices_destroy(&xsysd); + return xret; + } + + /* + * Assign to role(s). + */ + + xsysd->static_roles.head = ubrh.head; + + u_system_devices_static_finalize( // + usysds, // usysds + ubrh.left, // left + ubrh.right); // right + + + /* + * Create the space overseer. + */ + + *out_xsysd = xsysd; + u_builder_create_space_overseer_legacy( // + ubrh.head, // head + ubrh.left, // left + ubrh.right, // right + xsysd->xdevs, // xdevs + xsysd->xdev_count, // xdev_count + out_xso); // out_xso + + return XRT_SUCCESS; +} + +xrt_result_t +u_builder_open_system_static_roles(struct xrt_builder *xb, + cJSON *config, + struct xrt_prober *xp, + struct xrt_system_devices **out_xsysd, + struct xrt_space_overseer **out_xso) +{ + struct u_builder *ub = (struct u_builder *)xb; + + return u_builder_roles_helper_open_system( // + xb, // + config, // + xp, // + out_xsysd, // + out_xso, // + ub->open_system_static_roles); // +} diff --git a/src/xrt/auxiliary/util/u_builders.h b/src/xrt/auxiliary/util/u_builders.h index ac62d14ed..6ea32796d 100644 --- a/src/xrt/auxiliary/util/u_builders.h +++ b/src/xrt/auxiliary/util/u_builders.h @@ -18,6 +18,8 @@ extern "C" { #endif struct xrt_prober_device; +struct u_builder_roles_helper; + /*! * Max return of the number @ref xrt_prober_device. @@ -26,6 +28,25 @@ struct xrt_prober_device; */ #define U_BUILDER_SEARCH_MAX (16) // 16 Vive trackers +/*! + * Argument to @ref u_builder_roles_helper_open_system and implemented by + * @ref u_builder::open_system_static_roles function. + * + * A builder implement this function is free to focus on only creating the + * devices and assigning them initial roles. With this implementation details + * of the @ref xrt_system_devices and @ref xrt_space_overseer is taken care of + * by the caller of this function. + * + * @ingroup aux_util + */ +typedef xrt_result_t (*u_builder_open_system_fn)(struct xrt_builder *xb, + cJSON *config, + struct xrt_prober *xp, + struct xrt_tracking_origin *origin, + struct xrt_system_devices *xsysd, + struct xrt_frame_context *xfctx, + struct u_builder_roles_helper *ubrh); + /*! * A filter to match the against. * @@ -52,6 +73,54 @@ struct u_builder_search_results size_t xpdev_count; }; +/*! + * This small helper struct is for @ref u_builder_roles_helper_open_system, + * lets a builder focus on opening devices rather then dealing with Monado + * structs like @ref xrt_system_devices and the like. + * + * @ingroup aux_util + */ +struct u_builder_roles_helper +{ + struct xrt_device *head; + struct xrt_device *left; + struct xrt_device *right; + + struct + { + struct xrt_device *left; + struct xrt_device *right; + } hand_tracking; +}; + +/*! + * This helper struct makes it easier to implement the builder interface, but it + * also comes with a set of integration that may not be what all builders want. + * See the below functions for more information. + * + * * @ref u_builder_open_system_static_roles + * * @ref u_builder_roles_helper_open_system + * + * @ingroup aux_util + */ +struct u_builder +{ + //! Base for this struct. + struct xrt_builder base; + + /*! + * @copydoc u_builder_open_system_fn + */ + u_builder_open_system_fn open_system_static_roles; +}; + + +/* + * + * Functions. + * + */ + /*! * Find the first @ref xrt_prober_device in the prober list. * @@ -105,6 +174,43 @@ u_builder_create_space_overseer_legacy(struct xrt_device *head, uint32_t xdev_count, struct xrt_space_overseer **out_xso); +/*! + * Helper to create a system devices that has static roles and a appropriate + * space overseer. Currently uses the functions below to create a full system + * with the help of @p fn argument. But this might change in the future. + * + * * @ref u_system_devices_static_allocate + * * @ref u_system_devices_static_finalize + * * @ref u_builder_create_space_overseer_legacy + * + * @ingroup aux_util + */ +xrt_result_t +u_builder_roles_helper_open_system(struct xrt_builder *xb, + cJSON *config, + struct xrt_prober *xp, + struct xrt_system_devices **out_xsysd, + struct xrt_space_overseer **out_xso, + u_builder_open_system_fn fn); + +/*! + * Implementation for xrt_builder::open_system to be used with @ref u_builder. + * Uses @ref u_builder_roles_helper_open_system internally, a builder that uses + * the @ref u_builder should use this function for xrt_builder::open_system. + * + * When using this function the builder must have @ref u_builder and implement + * the @ref u_builder::open_static_roles function, see documentation for + * @ref u_builder_open_system_fn about requirements. + * + * @ingroup aux_util + */ +xrt_result_t +u_builder_open_system_static_roles(struct xrt_builder *xb, + cJSON *config, + struct xrt_prober *xp, + struct xrt_system_devices **out_xsysd, + struct xrt_space_overseer **out_xso); + #ifdef __cplusplus }