Skip to content

Commit c6dcc6d

Browse files
committed
removing openw class
1 parent 47b24db commit c6dcc6d

File tree

2 files changed

+164
-250
lines changed

2 files changed

+164
-250
lines changed

create_shadertext.py

Lines changed: 89 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,113 @@
1-
import io as cStringIO
2-
3-
import sys, os
1+
import sys
42
import time
5-
import re
6-
import glob
73
from collections import defaultdict
4+
from itertools import chain
85
from os.path import dirname
9-
from subprocess import Popen, PIPE
6+
from pathlib import Path
7+
from subprocess import PIPE, Popen
108

11-
def create_all(generated_dir, pymoldir="."):
12-
'''
13-
Generate various stuff
14-
'''
15-
create_shadertext(
16-
os.path.join(pymoldir, "data", "shaders"),
17-
generated_dir,
18-
os.path.join(generated_dir, "ShaderText.h"),
19-
os.path.join(generated_dir, "ShaderText.cpp"))
20-
create_buildinfo(generated_dir, pymoldir)
219

22-
class openw(object):
10+
def create_all(generated_dir: str, pymol_dir: str = "."):
2311
"""
24-
File-like object for writing files. File is actually only
25-
written if the content changed.
12+
Generate various stuff
2613
"""
27-
def __init__(self, filename):
28-
if os.path.exists(filename):
29-
self.out = cStringIO.StringIO()
30-
self.filename = filename
31-
else:
32-
os.makedirs(os.path.dirname(filename), exist_ok=True)
33-
self.out = open(filename, "w")
34-
self.filename = None
35-
def close(self):
36-
if self.out.closed:
37-
return
38-
if self.filename:
39-
with open(self.filename) as handle:
40-
oldcontents = handle.read()
41-
newcontents = self.out.getvalue()
42-
if oldcontents != newcontents:
43-
self.out = open(self.filename, "w")
44-
self.out.write(newcontents)
45-
self.out.close()
46-
def __getattr__(self, name):
47-
return getattr(self.out, name)
48-
def __enter__(self):
49-
return self
50-
def __exit__(self, *a, **k):
51-
self.close()
52-
def __del__(self):
53-
self.close()
54-
55-
def create_shadertext(shaderdir, shaderdir2, outputheader, outputfile):
56-
57-
outputheader = openw(outputheader)
58-
outputfile = openw(outputfile)
14+
generated_dir_path = Path(generated_dir)
15+
pymol_dir_path = Path(pymol_dir)
5916

17+
generated_dir_path.mkdir(parents=True, exist_ok=True)
18+
pymol_dir_path.mkdir(parents=True, exist_ok=True)
19+
20+
create_shadertext(
21+
shader_dir=generated_dir_path / "data" / "shaders",
22+
shader_dir2=pymol_dir_path,
23+
output_header=generated_dir_path / "ShaderText.h",
24+
output_source=generated_dir_path / "ShaderText.cpp",
25+
)
26+
create_buildinfo(generated_dir, pymol_dir)
27+
28+
29+
def create_shadertext(
30+
shader_dir: Path,
31+
shader_dir2: Path,
32+
output_header: Path,
33+
output_source: Path,
34+
):
35+
varname = "_shader_cache_raw"
6036
include_deps = defaultdict(set)
6137
ifdef_deps = defaultdict(set)
38+
extension_regexp = {".gs", ".vs", ".fs", ".shared", ".tsc", ".tse"}
6239

6340
# get all *.gs *.vs *.fs *.shared from the two input directories
64-
shaderfiles = set()
65-
for sdir in [shaderdir, shaderdir2]:
66-
for ext in ['gs', 'vs', 'fs', 'shared', 'tsc', 'tse']:
67-
shaderfiles.update(map(os.path.basename,
68-
sorted(glob.glob(os.path.join(sdir, '*.' + ext)))))
69-
70-
varname = '_shader_cache_raw'
71-
outputheader.write('extern const char * %s[];\n' % varname)
72-
outputfile.write('const char * %s[] = {\n' % varname)
73-
74-
for filename in sorted(shaderfiles):
75-
shaderfile = os.path.join(shaderdir, filename)
76-
if not os.path.exists(shaderfile):
77-
shaderfile = os.path.join(shaderdir2, filename)
78-
79-
with open(shaderfile, 'r') as handle:
80-
contents = handle.read()
81-
82-
if True:
83-
outputfile.write('"%s", ""\n' % (filename))
84-
41+
shader_files = set(
42+
chain(
43+
(path for path in shader_dir.glob("**/*") if path.suffix in extension_regexp),
44+
(path for path in shader_dir2.glob("**/*") if path.suffix in extension_regexp)
45+
)
46+
)
47+
48+
with (
49+
open(output_header, "w") as output_header_file,
50+
open(output_source, "w") as output_source_file,
51+
):
52+
output_header_file.write(f"extern const char * {varname}[];\n")
53+
output_source_file.write(f"const char * {varname}[] = {{\n")
54+
55+
for shader_file in shader_files:
56+
output_source_file.write(f'"{shader_file.name}", ""\n')
57+
58+
contents = shader_file.read_text()
8559
for line in contents.splitlines():
8660
line = line.strip()
8761

8862
# skip blank lines and obvious comments
89-
if not line or line.startswith('//') and not '*/' in line:
63+
if not line or line.startswith("//") and not "*/" in line:
9064
continue
9165

9266
# write line, quoted, escaped and with a line feed
93-
outputfile.write("\"%s\\n\"\n" % line.replace('\\', '\\\\').replace('"', r'\"'))
67+
escaped_line = line.replace("\\", "\\\\").replace('"', r"\"")
68+
output_source_file.write(f'"{escaped_line}\\n"\n')
9469

9570
# include and ifdef dependencies
96-
if line.startswith('#include'):
97-
include_deps[line.split()[1]].add(filename)
98-
elif line.startswith('#ifdef') or line.startswith('#ifndef'):
99-
ifdef_deps[line.split()[1]].add(filename)
100-
101-
outputfile.write(',\n')
102-
103-
outputfile.write('0};\n')
104-
105-
# include and ifdef dependencies
106-
for varname, deps in [
107-
('_include_deps', include_deps),
108-
('_ifdef_deps', ifdef_deps)]:
109-
outputheader.write('extern const char * %s[];\n' % varname)
110-
outputfile.write('const char * %s[] = {\n' % varname)
111-
for name, itemdeps in deps.items():
112-
outputfile.write('"%s", "%s", 0,\n' % (name, '", "'.join(sorted(itemdeps))))
113-
outputfile.write('0};\n')
114-
115-
outputheader.close()
116-
outputfile.close()
117-
118-
def create_buildinfo(outputdir, pymoldir='.'):
119-
120-
try:
121-
sha = Popen(['git', 'rev-parse', 'HEAD'], cwd=pymoldir,
122-
stdout=PIPE).stdout.read().strip().decode()
123-
except OSError:
124-
sha = ''
125-
126-
with openw(os.path.join(outputdir, 'PyMOLBuildInfo.h')) as out:
127-
print('''
128-
#define _PyMOL_BUILD_DATE %d
129-
#define _PYMOL_BUILD_GIT_SHA "%s"
130-
''' % (int(os.environ.get('SOURCE_DATE_EPOCH', time.time())), sha), file=out)
71+
if line.startswith("#include"):
72+
include_deps[line.split()[1]].add(shader_file.name)
73+
elif line.startswith("#ifdef") or line.startswith("#ifndef"):
74+
ifdef_deps[line.split()[1]].add(shader_file.name)
75+
76+
output_source_file.write(",\n")
77+
output_source_file.write("0};\n")
78+
79+
# include and ifdef dependencies
80+
for varname, deps in [
81+
("_include_deps", include_deps),
82+
("_ifdef_deps", ifdef_deps),
83+
]:
84+
output_header_file.write(f"extern const char * {varname}[];\n")
85+
output_source_file.write(f"const char * {varname}[] = {{\n")
86+
for name, item_deps in deps.items():
87+
item_deps = '", "'.join(sorted(item_deps))
88+
output_source_file.write(f'"{name}", "{item_deps}", 0,\n')
89+
output_source_file.write("0};\n")
90+
91+
92+
def create_buildinfo(output_dir_path: str, pymoldir: str = "."):
93+
output_dir = Path(output_dir_path)
94+
sha_raw = Popen(["git", "rev-parse", "HEAD"], cwd=pymoldir, stdout=PIPE).stdout
95+
sha = sha_raw.read().strip().decode() if sha_raw is not None else ""
96+
97+
info_file = output_dir / "PyMOLBuildInfo.h"
98+
info_file.write_text(
99+
f"""
100+
#define _PyMOL_BUILD_DATE {time.time()}
101+
#define _PYMOL_BUILD_GIT_SHA "{sha}"
102+
"""
103+
)
104+
131105

132106
if __name__ == "__main__":
133-
create_shadertext(*sys.argv[1:6])
107+
create_shadertext(
108+
shader_dir=Path(sys.argv[1]),
109+
shader_dir2=Path(sys.argv[2]),
110+
output_header=Path(sys.argv[3]),
111+
output_source=Path(sys.argv[4]),
112+
)
134113
create_buildinfo(dirname(sys.argv[4]), dirname(dirname(sys.argv[1])))

0 commit comments

Comments
 (0)