+ xo-printable2 + build fixes for cmake config

This commit is contained in:
Roland Conybeare 2026-01-04 23:03:18 -05:00
commit a5916b1f48
6 changed files with 85 additions and 23 deletions

View file

@ -1 +1,56 @@
# xo-facet
## Codegen
To scaffold a new facet Foo we need several c++ classes
* `AFoo` abstract FOMO interface, with opaque data pointer
* `IFoo_Any` variant placeholder, all methods terminate
* `IFoo_Xfer` template, delegates methods to a separate implementation class
* `RFoo` template, inherits from a 2x-wide fat pointer (iface+data).
These classes all have parallel methods
Can generate these as follows:
1. write `xo-foo/idl/Foo.json5`.
Supply attributes:
- mode :: string
- includes :: [string]
- namespace1 :: string
- namespace2 :: string
- facet :: string
- detail_subdir :: string
- brief :: string
- using_doxygen :: bool
- doc :: [string]
- types :: [{name, doc, definition}]
- const_methods :: [{name, doc, return_type, args, const, noexcept, attributes}]
- nonconst_methods :: [{name, doc, return_type, args, const, noexcept, attributes}]
Example in xo-object2/idl/Sequence.json5
2. generate:
```
$ cd xo-foo
$ ../xo-facet/codegen/genfacet.py --input ./idl/Foo.json5 --output include/xo/foo2
```
Alternatively in `xo-foo/CMakeLists.txt`
```
xo_add_genfacet(
TARGET xo-foo2-facet-foo
FACET Foo
INPUT idl/Foo.json5
OUTPUT_HTTP_DIR include/xo/foo2
OUTPUT_IMPL_SUBDIR detail
OUTPUT_CPP_DIR src/foo2)
```
then generate with:
```
cmake --build path/to/build -- xo-foo2-facet-foo
```

View file

@ -37,6 +37,8 @@ public:
///@{
{% endif %}
// types
/** integer identifying a type **/
using typeseq = xo::facet::typeseq;
{% for ty in types %}
/** {{ty.doc}} **/
using {{ty.name}} = {{ty.definition}};
@ -51,7 +53,7 @@ public:
{% endif %}
// const methods
/** RTTI: unique id# for actual runtime data representation **/
virtual int32_t _typeseq() const noexcept = 0;
virtual typeseq _typeseq() const noexcept = 0;
{% for md in const_methods %}
/** {{md.doc}} **/
virtual {{md.return_type}} {{md.name}}({{md.args | args}}) {{md | qualifiers}} = 0;

View file

@ -77,9 +77,8 @@ def format_args_impl(args, drepr):
def gen_facet(env,
idl_fname,
idl,
input_json5,
output_hpp_dir,
output_impl_hpp_dir,
#output_impl_hpp_subdir,
output_cpp_dir):
@ -88,6 +87,8 @@ def gen_facet(env,
# extra include files (or perhaps other definitions)
facet_includes = idl['includes']
# detail
facet_detail_subdir = idl['detail_subdir']
facet_ns1 = idl['namespace1']
facet_ns2 = idl['namespace2']
facet_name = idl['facet'] # e.g. Sequence
@ -95,6 +96,8 @@ def gen_facet(env,
facet_brief = idl['brief']
facet_doc = '\n'.join(idl['doc'])
output_impl_hpp_dir = output_hpp_dir / facet_detail_subdir
types = idl['types']
for ty in types:
ty['doc'] = '\n'.join(ty['doc'])
@ -143,7 +146,7 @@ def gen_facet(env,
'genfacet': __file__,
'genfacet_input': idl_fname,
'using_dox': using_dox,
'impl_hpp_subdir': output_impl_hpp_subdir,
'impl_hpp_subdir': facet_detail_subdir,
#
'facet_hpp_j2': 'facet.hpp.j2',
'facet_includes': facet_includes,
@ -475,23 +478,23 @@ def main():
env.filters['argimpl'] = format_args_impl
if idl['mode'] == 'facet':
gen_facet(env,
idl_fname,
idl,
output_hpp_dir,
output_impl_hpp_dir,
output_cpp_dir)
gen_facet(env=env,
idl_fname=idl_fname,
idl=idl,
output_hpp_dir=output_hpp_dir,
#output_impl_hpp_dir=output_impl_hpp_dir,
output_cpp_dir=output_cpp_dir)
elif idl['mode'] == 'implementation':
facet_idl_fname = idl['facet_idl']
facet_idl = load_idl(facet_idl_fname)
gen_facet_impl(env,
idl_fname,
idl,
facet_idl,
output_hpp_dir,
output_impl_hpp_dir,
output_cpp_dir)
gen_facet_impl(env=env,
idl_fname=idl_fname,
idl=idl,
facet_idl=facet_idl,
output_hpp_dir=output_hpp_dir,
output_impl_hpp_dir=output_impl_hpp_dir,
output_cpp_dir=output_cpp_dir)
if __name__ == '__main__':
main()

View file

@ -25,7 +25,7 @@ void
std::terminate();
}
int32_t
typeseq
{{iface_facet_any}}::s_typeseq = typeseq::id<DVariantPlaceholder>();
bool

View file

@ -44,6 +44,8 @@ namespace {{facet_ns2}} {
///@{
{% endif %}
/** integer identifying a type **/
using typeseq = xo::facet::typeseq;
{% for ty in types %}
using {{ty.name}} = {{abstract_facet}}::{{ty.name}};
{% endfor %}
@ -61,14 +63,14 @@ namespace {{facet_ns2}} {
// from {{abstract_facet}}
// const methods
int32_t _typeseq() const noexcept override { return s_typeseq; }
typeseq _typeseq() const noexcept override { return s_typeseq; }
{% for md in const_methods %}
[[noreturn]] {{md.return_type}} {{md.name}}({{md.args | argtypes}}) {{md | qualifiers}} override { _fatal(); }
{% endfor %}
// nonconst methods
{% for md in nonconst_methods %}
[[noreturn]] {{md.return_type}} {{md.name}}({{md.args | argtypes}}) {{md | qualifiers}} override { _fatail(); }
[[noreturn]] {{md.return_type}} {{md.name}}({{md.args | argtypes}}) {{md | qualifiers}} override { _fatal(); }
{% endfor %}
{% if using_dox %}
@ -89,11 +91,11 @@ namespace {{facet_ns2}} {
public:
{% if using_dox %}
/** @defgraoup {{facet_ns2}}-{{facet_name_lc}}-any-member-vars **/
/** @defgroup {{facet_ns2}}-{{facet_name_lc}}-any-member-vars **/
///@{
{% endif %}
static int32_t s_typeseq;
static typeseq s_typeseq;
static bool _valid;
{% if using_dox %}

View file

@ -68,7 +68,7 @@ namespace {{facet_ns2}} {
public:
{% if using_dox %}
/** @defgraoup {{facet_ns2}}-{{facet_name_lc}}-xfer-member-vars **/
/** @defgroup {{facet_ns2}}-{{facet_name_lc}}-xfer-member-vars **/
///@{
{% endif %}