Skip to content

Commit d9acf89

Browse files
improve stub generator by @ashleysommer
1 parent 594fe4d commit d9acf89

File tree

5 files changed

+1279
-2618
lines changed

5 files changed

+1279
-2618
lines changed

create_stub_pyray.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,23 @@
1212
#
1313
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
1414

15+
from pathlib import Path
1516
from raylib import rl, ffi
16-
1717
from inspect import ismethod, getmembers, isbuiltin
1818
import inflection, sys, json
1919

20-
f = open("raylib.json", "r")
21-
js = json.load(f)
20+
known_functions = {}
21+
known_structs = {}
22+
for filename in (Path("raylib.json"), Path("raymath.json"), Path("rlgl.json"), Path("raygui.json"), Path("physac.json")):
23+
f = open(filename, "r")
24+
js = json.load(f)
25+
for fn in js["functions"]:
26+
if fn["name"] not in known_functions:
27+
known_functions[fn["name"]] = fn
28+
for st in js["structs"]:
29+
if st["name"] not in known_structs:
30+
known_structs[st["name"]] = st
31+
2232

2333
def ctype_to_python_type(t):
2434
if t == '_Bool':
@@ -51,16 +61,17 @@ def pointer(struct):
5161
...
5262
""")
5363

54-
55-
64+
# These words can be used for c arg names, but not in python
65+
reserved_words = ("in", "list", "tuple", "set", "dict", "from", "range", "min", "max", "any", "all", "len")
5666

5767
for name, attr in getmembers(rl):
5868
uname = inflection.underscore(name).replace('3_d', '_3d').replace('2_d', '_2d')
5969
if isbuiltin(attr) or str(type(attr)) == "<class '_cffi_backend.__FFIFunctionWrapper'>":
60-
json_array = [x for x in js['functions'] if x['name'] == name]
61-
json_object = {}
62-
if len(json_array) > 0:
63-
json_object = json_array[0]
70+
json_object = known_functions.get(name, None)
71+
if json_object is None:
72+
# this is _not_ an exported function from raylib, raymath, rlgl raygui or physac
73+
# so we don't want it in the pyray API
74+
continue
6475
sig = ""
6576
for i, arg in enumerate(ffi.typeof(attr).args):
6677
param_name = arg.cname.replace("struct", "").replace("char *", "str").replace("*",
@@ -69,7 +80,9 @@ def pointer(struct):
6980
if 'params' in json_object:
7081
p = json_object['params']
7182
param_name = list(p)[i]['name']
72-
83+
# don't use a python reserved word:
84+
if param_name in reserved_words:
85+
param_name = param_name + "_" + str(i)
7386
param_type = ctype_to_python_type(arg.cname)
7487
sig += f"{param_name}: {param_type},"
7588

@@ -95,11 +108,13 @@ def pointer(struct):
95108

96109
for struct in ffi.list_types()[0]:
97110
print("processing", struct, file=sys.stderr)
98-
# json_array = [x for x in js['structs'] if x['name'] == name]
99-
# json_object = {}
100-
# if len(json_array) > 0:
101-
# json_object = json_array[0]
111+
102112
if ffi.typeof(struct).kind == "struct":
113+
json_object = known_structs.get(struct, None)
114+
if json_object is None:
115+
# this is _not_ an exported struct from raylib, raymath, rlgl raygui or physac
116+
# so we don't want it in the pyray API
117+
continue
103118
if ffi.typeof(struct).fields is None:
104119
print("weird empty struct, skipping "+struct, file=sys.stderr)
105120
continue

create_stub_static.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,22 @@
1212
#
1313
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
1414

15+
from pathlib import Path
1516
from raylib import rl, ffi
16-
1717
from inspect import ismethod, getmembers, isbuiltin
1818
import inflection, sys, json
1919

20-
f = open("raylib.json", "r")
21-
js = json.load(f)
22-
20+
known_functions = {}
21+
known_structs = {}
22+
for filename in (Path("raylib.json"), Path("raymath.json"), Path("rlgl.json"), Path("raygui.json"), Path("physac.json"), Path("glfw3.json")):
23+
f = open(filename, "r")
24+
js = json.load(f)
25+
for fn in js["functions"]:
26+
if fn["name"] not in known_functions:
27+
known_functions[fn["name"]] = fn
28+
for st in js["structs"]:
29+
if st["name"] not in known_structs:
30+
known_structs[st["name"]] = st
2331

2432

2533

@@ -59,22 +67,28 @@ class struct: ...
5967
6068
""")
6169

70+
# These words can be used for c arg names, but not in python
71+
reserved_words = ("in", "list", "tuple", "set", "dict", "from", "range", "min", "max", "any", "all", "len")
72+
6273
for name, attr in getmembers(rl):
6374
uname = name
6475
if isbuiltin(attr) or str(type(attr)) == "<class '_cffi_backend.__FFIFunctionWrapper'>":
65-
json_array = [x for x in js['functions'] if x['name'] == name]
66-
json_object = {}
67-
if len(json_array) > 0:
68-
json_object = json_array[0]
76+
json_object = known_functions.get(name, {})
6977
sig = ""
7078
for i, arg in enumerate(ffi.typeof(attr).args):
71-
param_name = arg.cname.replace("struct", "").replace("char *", "str").replace("*",
72-
"_pointer").replace(
73-
" ", "")+"_"+str(i)
79+
if ")(" in arg.cname:
80+
# fn signature in arg types
81+
param_name = str(arg.cname).split("(", 1)[0] + "_callback_" + str(i)
82+
else:
83+
param_name = arg.cname.replace("struct", "").replace("char *", "str").replace("*",
84+
"_pointer").replace(" ", "")+"_"+str(i)
7485
if 'params' in json_object:
7586
p = json_object['params']
7687
#print("param_name: ", param_name, "i", i, "params: ",p,file=sys.stderr)
7788
param_name = list(p)[i]['name']
89+
# don't use a python reserved word:
90+
if param_name in reserved_words:
91+
param_name = param_name+"_"+str(i)
7892
param_type = ctype_to_python_type(arg.cname)
7993
sig += f"{param_name}: {param_type},"
8094

make_docs.sh

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,13 @@ gcc raylib-c/parser/raylib_parser.c
2323

2424
echo "running parser"
2525

26-
./a.out -i raygui/src/raygui.h -o raygui.json -f JSON
27-
./a.out -i physac/src/physac.h -o physac.json -f JSON
26+
./a.out -i raygui/src/raygui.h -d RAYGUIAPI -o raygui.json -f JSON
27+
./a.out -i physac/src/physac.h -d PHYSACDEF -o physac.json -f JSON
2828
./a.out -i raylib-c/src/raylib.h -o raylib.json -f JSON
29+
./a.out -i raylib-c/src/rlgl.h -o rlgl.json -f JSON
30+
./a.out -i raylib-c/src/raymath.h -d RMAPI -o raymath.json -f JSON
31+
./a.out -i raylib-c/src/external/glfw/include/GLFW/glfw3.h -d GLFWAPI -o glfw3.json -f JSON
32+
sed -i "s|\/\*.*,$|,|g" glfw3.json
2933

3034
echo "building raylib_python_cffi"
3135

@@ -42,6 +46,7 @@ echo "creating pyi files"
4246
python3 create_stub_pyray.py > pyray/__init__.pyi
4347
python3 create_enums.py >> pyray/__init__.pyi
4448
cat raylib/colors.py >> pyray/__init__.pyi
49+
4550
python3 create_stub_static.py >raylib/__init__.pyi
4651
cat raylib/colors.py >> raylib/__init__.pyi
4752

0 commit comments

Comments
 (0)