diff --git a/README.md b/README.md index 67cf557..f44c3ec 100644 --- a/README.md +++ b/README.md @@ -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 +``` diff --git a/codegen/abstract_facet.hpp.j2 b/codegen/abstract_facet.hpp.j2 index 59e6127..0861b2a 100644 --- a/codegen/abstract_facet.hpp.j2 +++ b/codegen/abstract_facet.hpp.j2 @@ -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; diff --git a/codegen/genfacet b/codegen/genfacet index ff809d5..03e6ceb 100755 --- a/codegen/genfacet +++ b/codegen/genfacet @@ -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() diff --git a/codegen/iface_facet_any.cpp.j2 b/codegen/iface_facet_any.cpp.j2 index 603686c..0454bb2 100644 --- a/codegen/iface_facet_any.cpp.j2 +++ b/codegen/iface_facet_any.cpp.j2 @@ -25,7 +25,7 @@ void std::terminate(); } -int32_t +typeseq {{iface_facet_any}}::s_typeseq = typeseq::id(); bool diff --git a/codegen/iface_facet_any.hpp.j2 b/codegen/iface_facet_any.hpp.j2 index 70a27a9..cd8b99c 100644 --- a/codegen/iface_facet_any.hpp.j2 +++ b/codegen/iface_facet_any.hpp.j2 @@ -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 %} diff --git a/codegen/iface_facet_xfer.hpp.j2 b/codegen/iface_facet_xfer.hpp.j2 index bdfd615..ad65907 100644 --- a/codegen/iface_facet_xfer.hpp.j2 +++ b/codegen/iface_facet_xfer.hpp.j2 @@ -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 %}