Skip to content

Commit 6f55899

Browse files
committed
Add missing file
1 parent a14baba commit 6f55899

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

robotpy_build/autowrap/writer.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import json
2+
from os.path import join
3+
import pathlib
4+
import typing
5+
6+
import jinja2
7+
8+
from .j2_context import HeaderContext
9+
10+
templates_path = pathlib.Path(__file__).parent.absolute()
11+
12+
13+
class WrapperWriter:
14+
def __init__(self) -> None:
15+
#
16+
# Load all the templates first
17+
#
18+
19+
self.env = jinja2.Environment(
20+
loader=jinja2.FileSystemLoader(searchpath=templates_path),
21+
undefined=jinja2.StrictUndefined,
22+
autoescape=False,
23+
auto_reload=False,
24+
# trim_blocks=True,
25+
# lstrip_blocks=True,
26+
)
27+
28+
# c++ file generated per-header
29+
self.header_cpp_j2 = self.env.get_template("header.cpp.j2")
30+
31+
# class templates
32+
self.cls_tmpl_inst_cpp_j2 = self.env.get_template("cls_tmpl_inst.cpp.j2")
33+
self.cls_tmpl_inst_hpp_j2 = self.env.get_template("cls_tmpl_inst.hpp.j2")
34+
35+
# rpy-include trampoline file
36+
self.rpy_include_hpp_j2 = self.env.get_template("cls_rpy_include.hpp.j2")
37+
38+
def write_files(
39+
self,
40+
hctx: HeaderContext,
41+
name: str,
42+
cxx_gen_dir: str,
43+
hppoutdir: str,
44+
classdeps_json_fname: str,
45+
) -> typing.List[str]:
46+
"""Generates all files needed for a single processed header"""
47+
48+
generated_sources: typing.List[str] = []
49+
50+
# Jinja requires input as a dictionary
51+
data = hctx.__dict__
52+
53+
# Write the cpp file first
54+
fname = join(cxx_gen_dir, f"{name}.cpp")
55+
generated_sources.append(fname)
56+
with open(fname, "w", encoding="utf-8") as fp:
57+
fp.write(self.header_cpp_j2.render(data))
58+
59+
# Then the json, no need for jinja here
60+
with open(classdeps_json_fname, "w", encoding="utf-8") as fp:
61+
json.dump(hctx.class_hierarchy, fp)
62+
63+
# Generate an rpy-include file for each class that has either a trampoline
64+
# or a template class
65+
for cls in hctx.classes:
66+
if not cls.template and not cls.trampoline:
67+
continue
68+
69+
data["cls"] = cls
70+
fname = join(
71+
hppoutdir, f"{cls.namespace.replace(':', '_')}__{cls.cpp_name}.hpp"
72+
)
73+
with open(fname, "w", encoding="utf-8") as fp:
74+
fp.write(self.rpy_include_hpp_j2.render(data))
75+
76+
# Each class template is instantiated in a separate cpp file to lessen
77+
# compiler memory requirements when compiling obnoxious templates
78+
if hctx.template_instances:
79+
# Single header output that holds all the struct outlines
80+
fname = join(cxx_gen_dir, f"{name}_tmpl.hpp")
81+
with open(fname, "w", encoding="utf-8") as fp:
82+
fp.write(self.cls_tmpl_inst_hpp_j2.render(data))
83+
84+
# Each cpp file has a single class template instance
85+
for i, tmpl_data in enumerate(hctx.template_instances):
86+
data["tmpl_data"] = tmpl_data
87+
fname = join(hppoutdir, f"{name}_tmpl{i+1}.cpp")
88+
generated_sources.append(fname)
89+
with open(fname, "w", encoding="utf-8") as fp:
90+
fp.write(self.cls_tmpl_inst_cpp_j2.render(data))
91+
92+
return generated_sources
93+
94+
def _render_template(self, tmpl_src: str, dst: str, data: dict):
95+
jtmpl = self.env.get_template(tmpl_src)
96+
content = jtmpl.render(data)
97+
with open(dst, "w", encoding="utf-8") as fp:
98+
fp.write(content)

0 commit comments

Comments
 (0)