Skip to content

Commit 0163705

Browse files
committed
SCons: Add method to generate raw cstrings
1 parent 1d57b81 commit 0163705

11 files changed

+175
-76
lines changed

editor/icons/editor_icons_builders.py

+5-15
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,18 @@
33
import os
44
from io import StringIO
55

6+
from methods import to_raw_cstring
7+
68

79
# See also `scene/theme/icons/default_theme_icons_builders.py`.
810
def make_editor_icons_action(target, source, env):
911
dst = str(target[0])
1012
svg_icons = source
1113

1214
with StringIO() as icons_string, StringIO() as s:
13-
for f in svg_icons:
14-
fname = str(f)
15-
16-
icons_string.write('\t"')
17-
18-
with open(fname, "rb") as svgf:
19-
b = svgf.read(1)
20-
while len(b) == 1:
21-
icons_string.write("\\" + str(hex(ord(b)))[1:])
22-
b = svgf.read(1)
23-
24-
icons_string.write('"')
25-
if fname != svg_icons[-1]:
26-
icons_string.write(",")
27-
icons_string.write("\n")
15+
for svg in svg_icons:
16+
with open(str(svg), "r") as svgf:
17+
icons_string.write("\t%s,\n" % to_raw_cstring(svgf.read()))
2818

2919
s.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
3020
s.write("#ifndef _EDITOR_ICONS_H\n")

gles3_builders.py

+5-13
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os.path
44
from typing import Optional
55

6-
from methods import print_error
6+
from methods import print_error, to_raw_cstring
77

88

99
class GLES3HeaderStruct:
@@ -553,20 +553,12 @@ def build_gles3_header(
553553
fd.write("\t\tstatic const Feedback* _feedbacks=nullptr;\n")
554554

555555
fd.write("\t\tstatic const char _vertex_code[]={\n")
556-
for x in header_data.vertex_lines:
557-
for c in x:
558-
fd.write(str(ord(c)) + ",")
559-
560-
fd.write(str(ord("\n")) + ",")
561-
fd.write("\t\t0};\n\n")
556+
fd.write(to_raw_cstring(header_data.vertex_lines))
557+
fd.write("\n\t\t};\n\n")
562558

563559
fd.write("\t\tstatic const char _fragment_code[]={\n")
564-
for x in header_data.fragment_lines:
565-
for c in x:
566-
fd.write(str(ord(c)) + ",")
567-
568-
fd.write(str(ord("\n")) + ",")
569-
fd.write("\t\t0};\n\n")
560+
fd.write(to_raw_cstring(header_data.fragment_lines))
561+
fd.write("\n\t\t};\n\n")
570562

571563
fd.write(
572564
'\t\t_setup(_vertex_code,_fragment_code,"'

glsl_builders.py

+6-22
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,9 @@
11
"""Functions used to generate source files during build time"""
22

33
import os.path
4-
from typing import Iterable, Optional
4+
from typing import Optional
55

6-
from methods import print_error
7-
8-
9-
def generate_inline_code(input_lines: Iterable[str], insert_newline: bool = True):
10-
"""Take header data and generate inline code
11-
12-
:param: input_lines: values for shared inline code
13-
:return: str - generated inline value
14-
"""
15-
output = []
16-
for line in input_lines:
17-
if line:
18-
output.append(",".join(str(ord(c)) for c in line))
19-
if insert_newline:
20-
output.append("%s" % ord("\n"))
21-
output.append("0")
22-
return ",".join(output)
6+
from methods import print_error, to_raw_cstring
237

248

259
class RDHeaderStruct:
@@ -127,13 +111,13 @@ def build_rd_header(
127111

128112
if header_data.compute_lines:
129113
body_parts = [
130-
"static const char _compute_code[] = {\n%s\n\t\t};" % generate_inline_code(header_data.compute_lines),
114+
"static const char _compute_code[] = {\n%s\n\t\t};" % to_raw_cstring(header_data.compute_lines),
131115
f'setup(nullptr, nullptr, _compute_code, "{out_file_class}");',
132116
]
133117
else:
134118
body_parts = [
135-
"static const char _vertex_code[] = {\n%s\n\t\t};" % generate_inline_code(header_data.vertex_lines),
136-
"static const char _fragment_code[] = {\n%s\n\t\t};" % generate_inline_code(header_data.fragment_lines),
119+
"static const char _vertex_code[] = {\n%s\n\t\t};" % to_raw_cstring(header_data.vertex_lines),
120+
"static const char _fragment_code[] = {\n%s\n\t\t};" % to_raw_cstring(header_data.fragment_lines),
137121
f'setup(_vertex_code, _fragment_code, nullptr, "{out_file_class}");',
138122
]
139123

@@ -211,7 +195,7 @@ def build_raw_header(
211195
#define {out_file_ifdef}_RAW_H
212196
213197
static const char {out_file_base}[] = {{
214-
{generate_inline_code(header_data.code, insert_newline=False)}
198+
{to_raw_cstring(header_data.code)}
215199
}};
216200
#endif
217201
"""

methods.py

+41-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from enum import Enum
99
from io import StringIO, TextIOWrapper
1010
from pathlib import Path
11-
from typing import Generator, Optional
11+
from typing import Generator, List, Optional, Union
1212

1313
# Get the "Godot" folder name ahead of time
1414
base_folder_path = str(os.path.abspath(Path(__file__).parent)) + "/"
@@ -1641,3 +1641,43 @@ def generated_wrapper(
16411641
file.write(f"\n\n#endif // {header_guard}")
16421642

16431643
file.write("\n")
1644+
1645+
1646+
def to_raw_cstring(value: Union[str, List[str]]) -> str:
1647+
MAX_LITERAL = 16 * 1024
1648+
1649+
if isinstance(value, list):
1650+
value = "\n".join(value) + "\n"
1651+
1652+
split: List[bytes] = []
1653+
offset = 0
1654+
encoded = value.encode()
1655+
1656+
while offset <= len(encoded):
1657+
segment = encoded[offset : offset + MAX_LITERAL]
1658+
offset += MAX_LITERAL
1659+
if len(segment) == MAX_LITERAL:
1660+
# Try to segment raw strings at double newlines to keep readable.
1661+
pretty_break = segment.rfind(b"\n\n")
1662+
if pretty_break != -1:
1663+
segment = segment[: pretty_break + 1]
1664+
offset -= MAX_LITERAL - pretty_break - 1
1665+
# If none found, ensure we end with valid utf8.
1666+
# https://github.com/halloleo/unicut/blob/master/truncate.py
1667+
elif segment[-1] & 0b10000000:
1668+
last_11xxxxxx_index = [i for i in range(-1, -5, -1) if segment[i] & 0b11000000 == 0b11000000][0]
1669+
last_11xxxxxx = segment[last_11xxxxxx_index]
1670+
if not last_11xxxxxx & 0b00100000:
1671+
last_char_length = 2
1672+
elif not last_11xxxxxx & 0b0010000:
1673+
last_char_length = 3
1674+
elif not last_11xxxxxx & 0b0001000:
1675+
last_char_length = 4
1676+
1677+
if last_char_length > -last_11xxxxxx_index:
1678+
segment = segment[:last_11xxxxxx_index]
1679+
offset += last_11xxxxxx_index
1680+
1681+
split += [segment]
1682+
1683+
return " ".join(f'R"<!>({x.decode()})<!>"' for x in split)

platform/SCsub

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ def export_icon_builder(target, source, env):
1515
src_path = Path(str(source[0]))
1616
src_name = src_path.stem
1717
platform = src_path.parent.parent.stem
18-
with open(str(source[0]), "rb") as file:
19-
svg = "".join([f"\\{hex(x)[1:]}" for x in file.read()])
18+
with open(str(source[0]), "r") as file:
19+
svg = file.read()
2020
with methods.generated_wrapper(target, prefix=platform) as file:
2121
file.write(
2222
f"""\
23-
static const char *_{platform}_{src_name}_svg = "{svg}";
23+
static const char *_{platform}_{src_name}_svg = {methods.to_raw_cstring(svg)};
2424
"""
2525
)
2626

scene/theme/icons/default_theme_icons_builders.py

+5-15
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,18 @@
33
import os
44
from io import StringIO
55

6+
from methods import to_raw_cstring
7+
68

79
# See also `editor/icons/editor_icons_builders.py`.
810
def make_default_theme_icons_action(target, source, env):
911
dst = str(target[0])
1012
svg_icons = [str(x) for x in source]
1113

1214
with StringIO() as icons_string, StringIO() as s:
13-
for f in svg_icons:
14-
fname = str(f)
15-
16-
icons_string.write('\t"')
17-
18-
with open(fname, "rb") as svgf:
19-
b = svgf.read(1)
20-
while len(b) == 1:
21-
icons_string.write("\\" + str(hex(ord(b)))[1:])
22-
b = svgf.read(1)
23-
24-
icons_string.write('"')
25-
if fname != svg_icons[-1]:
26-
icons_string.write(",")
27-
icons_string.write("\n")
15+
for svg in svg_icons:
16+
with open(svg, "r") as svgf:
17+
icons_string.write("\t%s,\n" % to_raw_cstring(svgf.read()))
2818

2919
s.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n\n")
3020
s.write('#include "modules/modules_enabled.gen.h"\n\n')

tests/python_build/fixtures/gles3/vertex_fragment_expected_full.glsl

+26-2
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,34 @@ protected:
3737

3838
static const Feedback* _feedbacks=nullptr;
3939
static const char _vertex_code[]={
40-
10,112,114,101,99,105,115,105,111,110,32,104,105,103,104,112,32,102,108,111,97,116,59,10,112,114,101,99,105,115,105,111,110,32,104,105,103,104,112,32,105,110,116,59,10,10,108,97,121,111,117,116,40,108,111,99,97,116,105,111,110,32,61,32,48,41,32,105,110,32,104,105,103,104,112,32,118,101,99,51,32,118,101,114,116,101,120,59,10,10,111,117,116,32,104,105,103,104,112,32,118,101,99,52,32,112,111,115,105,116,105,111,110,95,105,110,116,101,114,112,59,10,10,118,111,105,100,32,109,97,105,110,40,41,32,123,10,9,112,111,115,105,116,105,111,110,95,105,110,116,101,114,112,32,61,32,118,101,99,52,40,118,101,114,116,101,120,46,120,44,49,44,48,44,49,41,59,10,125,10,10, 0};
40+
R"<!>(
41+
precision highp float;
42+
precision highp int;
43+
44+
layout(location = 0) in highp vec3 vertex;
45+
46+
out highp vec4 position_interp;
47+
48+
void main() {
49+
position_interp = vec4(vertex.x,1,0,1);
50+
}
51+
52+
)<!>"
53+
};
4154

4255
static const char _fragment_code[]={
43-
10,112,114,101,99,105,115,105,111,110,32,104,105,103,104,112,32,102,108,111,97,116,59,10,112,114,101,99,105,115,105,111,110,32,104,105,103,104,112,32,105,110,116,59,10,10,105,110,32,104,105,103,104,112,32,118,101,99,52,32,112,111,115,105,116,105,111,110,95,105,110,116,101,114,112,59,10,10,118,111,105,100,32,109,97,105,110,40,41,32,123,10,9,104,105,103,104,112,32,102,108,111,97,116,32,100,101,112,116,104,32,61,32,40,40,112,111,115,105,116,105,111,110,95,105,110,116,101,114,112,46,122,32,47,32,112,111,115,105,116,105,111,110,95,105,110,116,101,114,112,46,119,41,32,43,32,49,46,48,41,59,10,9,102,114,97,103,95,99,111,108,111,114,32,61,32,118,101,99,52,40,100,101,112,116,104,41,59,10,125,10, 0};
56+
R"<!>(
57+
precision highp float;
58+
precision highp int;
59+
60+
in highp vec4 position_interp;
61+
62+
void main() {
63+
highp float depth = ((position_interp.z / position_interp.w) + 1.0);
64+
frag_color = vec4(depth);
65+
}
66+
)<!>"
67+
};
4468

4569
_setup(_vertex_code,_fragment_code,"VertexFragmentShaderGLES3",0,_uniform_strings,0,_ubo_pairs,0,_feedbacks,0,_texunit_pairs,1,_spec_pairs,1,_variant_defines);
4670
}

tests/python_build/fixtures/glsl/compute_expected_full.glsl

+13-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33
#define COMPUTE_SHADER_GLSL_RAW_H
44

55
static const char compute_shader_glsl[] = {
6-
35,91,99,111,109,112,117,116,101,93,10,10,35,118,101,114,115,105,111,110,32,52,53,48,10,10,35,86,69,82,83,73,79,78,95,68,69,70,73,78,69,83,10,10,10,35,100,101,102,105,110,101,32,77,95,80,73,32,51,46,49,52,49,53,57,50,54,53,51,53,57,10,10,118,111,105,100,32,109,97,105,110,40,41,32,123,10,9,118,101,99,51,32,115,116,97,116,105,99,95,108,105,103,104,116,32,61,32,118,101,99,51,40,48,44,32,49,44,32,48,41,59,10,125,10,0
6+
R"<!>(#[compute]
7+
8+
#version 450
9+
10+
#VERSION_DEFINES
11+
12+
13+
#define M_PI 3.14159265359
14+
15+
void main() {
16+
vec3 static_light = vec3(0, 1, 0);
17+
}
18+
)<!>"
719
};
820
#endif

tests/python_build/fixtures/glsl/vertex_fragment_expected_full.glsl

+33-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,38 @@
33
#define VERTEX_FRAGMENT_SHADER_GLSL_RAW_H
44

55
static const char vertex_fragment_shader_glsl[] = {
6-
35,91,118,101,114,115,105,111,110,115,93,10,10,108,105,110,101,115,32,61,32,34,35,100,101,102,105,110,101,32,77,79,68,69,95,76,73,78,69,83,34,59,10,10,35,91,118,101,114,116,101,120,93,10,10,35,118,101,114,115,105,111,110,32,52,53,48,10,10,35,86,69,82,83,73,79,78,95,68,69,70,73,78,69,83,10,10,108,97,121,111,117,116,40,108,111,99,97,116,105,111,110,32,61,32,48,41,32,111,117,116,32,118,101,99,51,32,117,118,95,105,110,116,101,114,112,59,10,10,118,111,105,100,32,109,97,105,110,40,41,32,123,10,10,35,105,102,100,101,102,32,77,79,68,69,95,76,73,78,69,83,10,9,117,118,95,105,110,116,101,114,112,32,61,32,118,101,99,51,40,48,44,48,44,49,41,59,10,35,101,110,100,105,102,10,125,10,10,35,91,102,114,97,103,109,101,110,116,93,10,10,35,118,101,114,115,105,111,110,32,52,53,48,10,10,35,86,69,82,83,73,79,78,95,68,69,70,73,78,69,83,10,10,35,100,101,102,105,110,101,32,77,95,80,73,32,51,46,49,52,49,53,57,50,54,53,51,53,57,10,10,108,97,121,111,117,116,40,108,111,99,97,116,105,111,110,32,61,32,48,41,32,111,117,116,32,118,101,99,52,32,100,115,116,95,99,111,108,111,114,59,10,10,118,111,105,100,32,109,97,105,110,40,41,32,123,10,9,100,115,116,95,99,111,108,111,114,32,61,32,118,101,99,52,40,49,44,49,44,48,44,48,41,59,10,125,10,0
6+
R"<!>(#[versions]
7+
8+
lines = "#define MODE_LINES";
9+
10+
#[vertex]
11+
12+
#version 450
13+
14+
#VERSION_DEFINES
15+
16+
layout(location = 0) out vec3 uv_interp;
17+
18+
void main() {
19+
20+
#ifdef MODE_LINES
21+
uv_interp = vec3(0,0,1);
22+
#endif
23+
}
24+
25+
#[fragment]
26+
27+
#version 450
28+
29+
#VERSION_DEFINES
30+
31+
#define M_PI 3.14159265359
32+
33+
layout(location = 0) out vec4 dst_color;
34+
35+
void main() {
36+
dst_color = vec4(1,1,0,0);
37+
}
38+
)<!>"
739
};
840
#endif

tests/python_build/fixtures/rd_glsl/compute_expected_full.glsl

+13-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,19 @@ public:
1111
ComputeShaderRD() {
1212

1313
static const char _compute_code[] = {
14-
10,35,118,101,114,115,105,111,110,32,52,53,48,10,10,35,86,69,82,83,73,79,78,95,68,69,70,73,78,69,83,10,10,35,100,101,102,105,110,101,32,66,76,79,67,75,95,83,73,90,69,32,56,10,10,35,100,101,102,105,110,101,32,77,95,80,73,32,51,46,49,52,49,53,57,50,54,53,51,53,57,10,10,118,111,105,100,32,109,97,105,110,40,41,32,123,10,9,117,105,110,116,32,116,32,61,32,66,76,79,67,75,95,83,73,90,69,32,43,32,49,59,10,125,10,0
14+
R"<!>(
15+
#version 450
16+
17+
#VERSION_DEFINES
18+
19+
#define BLOCK_SIZE 8
20+
21+
#define M_PI 3.14159265359
22+
23+
void main() {
24+
uint t = BLOCK_SIZE + 1;
25+
}
26+
)<!>"
1527
};
1628
setup(nullptr, nullptr, _compute_code, "ComputeShaderRD");
1729
}

tests/python_build/fixtures/rd_glsl/vertex_fragment_expected_full.glsl

+25-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,33 @@ public:
1111
VertexFragmentShaderRD() {
1212

1313
static const char _vertex_code[] = {
14-
10,35,118,101,114,115,105,111,110,32,52,53,48,10,10,35,86,69,82,83,73,79,78,95,68,69,70,73,78,69,83,10,10,35,100,101,102,105,110,101,32,77,95,80,73,32,51,46,49,52,49,53,57,50,54,53,51,53,57,10,10,108,97,121,111,117,116,40,108,111,99,97,116,105,111,110,32,61,32,48,41,32,111,117,116,32,118,101,99,50,32,117,118,95,105,110,116,101,114,112,59,10,10,118,111,105,100,32,109,97,105,110,40,41,32,123,10,9,117,118,95,105,110,116,101,114,112,32,61,32,118,101,99,50,40,48,44,32,49,41,59,10,125,10,10,0
14+
R"<!>(
15+
#version 450
16+
17+
#VERSION_DEFINES
18+
19+
#define M_PI 3.14159265359
20+
21+
layout(location = 0) out vec2 uv_interp;
22+
23+
void main() {
24+
uv_interp = vec2(0, 1);
25+
}
26+
27+
)<!>"
1528
};
1629
static const char _fragment_code[] = {
17-
10,35,118,101,114,115,105,111,110,32,52,53,48,10,10,35,86,69,82,83,73,79,78,95,68,69,70,73,78,69,83,10,10,108,97,121,111,117,116,40,108,111,99,97,116,105,111,110,32,61,32,48,41,32,105,110,32,118,101,99,50,32,117,118,95,105,110,116,101,114,112,59,10,10,118,111,105,100,32,109,97,105,110,40,41,32,123,10,9,117,118,95,105,110,116,101,114,112,32,61,32,118,101,99,50,40,49,44,32,48,41,59,10,125,10,0
30+
R"<!>(
31+
#version 450
32+
33+
#VERSION_DEFINES
34+
35+
layout(location = 0) in vec2 uv_interp;
36+
37+
void main() {
38+
uv_interp = vec2(1, 0);
39+
}
40+
)<!>"
1841
};
1942
setup(_vertex_code, _fragment_code, nullptr, "VertexFragmentShaderRD");
2043
}

0 commit comments

Comments
 (0)