mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
626 Commits
define-dnd
...
v5.3.181
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ec1ebcbf5b | ||
![]() |
4ee9ccd7a9 | ||
![]() |
1ac248bfa4 | ||
![]() |
65b78d4db7 | ||
![]() |
639d90d743 | ||
![]() |
45d0a78656 | ||
![]() |
0a0811e355 | ||
![]() |
a8f9df3dac | ||
![]() |
35db56d778 | ||
![]() |
27efe8e3dd | ||
![]() |
3584ee2aaf | ||
![]() |
19a762fb60 | ||
![]() |
8a6dd8b940 | ||
![]() |
2173b49b19 | ||
![]() |
caf2752acb | ||
![]() |
e3291b515d | ||
![]() |
c1627b5ab2 | ||
![]() |
7db5b97c45 | ||
![]() |
425a0e92ca | ||
![]() |
c2dfe579af | ||
![]() |
4ea6fb78bd | ||
![]() |
8e668db6ea | ||
![]() |
88063a4cad | ||
![]() |
b180f5032e | ||
![]() |
29e7f7d7a4 | ||
![]() |
547f1e4bce | ||
![]() |
9e176d91ec | ||
![]() |
cac59d4727 | ||
![]() |
4f98ffa9ab | ||
![]() |
7229406cfb | ||
![]() |
d39cfd16a2 | ||
![]() |
2965f374bb | ||
![]() |
2d5b2a49e7 | ||
![]() |
05df9cb599 | ||
![]() |
7b28d2525e | ||
![]() |
533e61cdbc | ||
![]() |
3a823113f1 | ||
![]() |
17bc8b584d | ||
![]() |
dbaf8a6569 | ||
![]() |
fcbc538c30 | ||
![]() |
decd96c52f | ||
![]() |
8dbf9c99ce | ||
![]() |
1318523804 | ||
![]() |
8ef5e2c1ed | ||
![]() |
d945426068 | ||
![]() |
8eb07a492f | ||
![]() |
37c9dd95ce | ||
![]() |
a6d837cbe6 | ||
![]() |
f6539626d3 | ||
![]() |
e0df9b0ff3 | ||
![]() |
0b50231027 | ||
![]() |
94c9924a88 | ||
![]() |
581cc5837a | ||
![]() |
ff77d107b2 | ||
![]() |
3a5198cb34 | ||
![]() |
c92025549d | ||
![]() |
600b307e7e | ||
![]() |
297fade0bd | ||
![]() |
84d7500eab | ||
![]() |
f99c4ab948 | ||
![]() |
5fe4f23c83 | ||
![]() |
8820bd45e4 | ||
![]() |
5e16968f37 | ||
![]() |
6b6179ff22 | ||
![]() |
94bcd87a9f | ||
![]() |
356a1974ef | ||
![]() |
345bad9876 | ||
![]() |
0b8d843a73 | ||
![]() |
9f0c987ec7 | ||
![]() |
0e79209d2b | ||
![]() |
f991c09c39 | ||
![]() |
6e24dfa9b8 | ||
![]() |
a3cd00dc94 | ||
![]() |
300c011151 | ||
![]() |
230d410469 | ||
![]() |
402e54f706 | ||
![]() |
dc29c27272 | ||
![]() |
462bb84c51 | ||
![]() |
a775e79bae | ||
![]() |
bc8c867f23 | ||
![]() |
f34bf2b7b4 | ||
![]() |
e2d482e1aa | ||
![]() |
0724ae34d9 | ||
![]() |
2fc1c2fd86 | ||
![]() |
9a42ae11ad | ||
![]() |
32773e06f6 | ||
![]() |
00508df014 | ||
![]() |
c3cf5b7002 | ||
![]() |
df7fab84b8 | ||
![]() |
95a0012c5e | ||
![]() |
4bf644f9f2 | ||
![]() |
79cad1da3a | ||
![]() |
ffc6f5786b | ||
![]() |
07df65f8c2 | ||
![]() |
61f8f0ed66 | ||
![]() |
c24e2e5ace | ||
![]() |
25c72a6d1f | ||
![]() |
6153b23e7d | ||
![]() |
1b7ccfded3 | ||
![]() |
ec57a0a80d | ||
![]() |
95a9e37aba | ||
![]() |
787274f7fa | ||
![]() |
ceb24f0edb | ||
![]() |
028bf7a70d | ||
![]() |
08471d0356 | ||
![]() |
921add6665 | ||
![]() |
dabff06891 | ||
![]() |
967033c407 | ||
![]() |
0809749ddc | ||
![]() |
8a27801355 | ||
![]() |
20cba9d7ed | ||
![]() |
3878b93c94 | ||
![]() |
645d5331cb | ||
![]() |
91db750632 | ||
![]() |
740485b54a | ||
![]() |
e960fe7c5b | ||
![]() |
0633c7b474 | ||
![]() |
704bfd40cb | ||
![]() |
310abe7a13 | ||
![]() |
b0f9bed273 | ||
![]() |
766a62ad9b | ||
![]() |
ec6f669d94 | ||
![]() |
36a2408be0 | ||
![]() |
1343210a2b | ||
![]() |
1e76fedd7b | ||
![]() |
3923641988 | ||
![]() |
a7d488626c | ||
![]() |
33f20b9bde | ||
![]() |
6c4cd6343f | ||
![]() |
f1c04df0ee | ||
![]() |
9b466ff574 | ||
![]() |
2b0969600e | ||
![]() |
7ed1eee8f9 | ||
![]() |
9b9b729b42 | ||
![]() |
530969d4b0 | ||
![]() |
11ef87b9ee | ||
![]() |
e1857e2e1e | ||
![]() |
d1385e5fc2 | ||
![]() |
9298026179 | ||
![]() |
913e367f6f | ||
![]() |
1bc27bdd8b | ||
![]() |
4d8b39df95 | ||
![]() |
e6970319b9 | ||
![]() |
cdf21ebd4c | ||
![]() |
dc014e2ab0 | ||
![]() |
25509e1c7b | ||
![]() |
516621e989 | ||
![]() |
9b2435b210 | ||
![]() |
f894e1962a | ||
![]() |
cc35f51158 | ||
![]() |
a7ef02f1c1 | ||
![]() |
2cc7506ad7 | ||
![]() |
608b460da7 | ||
![]() |
6b082731c2 | ||
![]() |
e040dd5f28 | ||
![]() |
ae64cfb3bb | ||
![]() |
02b96eb298 | ||
![]() |
6f59a3ba03 | ||
![]() |
6180016b51 | ||
![]() |
b15e72410e | ||
![]() |
d6fbb0e78b | ||
![]() |
8eb9136847 | ||
![]() |
46c02ad9b7 | ||
![]() |
9846a9b45e | ||
![]() |
3d86820581 | ||
![]() |
b636eeb859 | ||
![]() |
189bcc4ceb | ||
![]() |
3fe031063c | ||
![]() |
d10712d584 | ||
![]() |
1721fb6211 | ||
![]() |
e31ea07902 | ||
![]() |
85929b6e76 | ||
![]() |
0662607409 | ||
![]() |
52f10d73ab | ||
![]() |
d4cb4fafd3 | ||
![]() |
9f4b12ce8a | ||
![]() |
b5b7edafb1 | ||
![]() |
1335819ea7 | ||
![]() |
aa7ae758f7 | ||
![]() |
7da88662fb | ||
![]() |
dbc1385787 | ||
![]() |
8944df1831 | ||
![]() |
a0925c79c3 | ||
![]() |
73642092bb | ||
![]() |
dfe84fbe2b | ||
![]() |
cd896c399d | ||
![]() |
d8126ead34 | ||
![]() |
bdbbe1f409 | ||
![]() |
3a241d03f1 | ||
![]() |
e4cf92e949 | ||
![]() |
0dc513317c | ||
![]() |
3e85242165 | ||
![]() |
ca9fe51d99 | ||
![]() |
2e9a5ee287 | ||
![]() |
b57e944da5 | ||
![]() |
06cdeb763d | ||
![]() |
5809a02a26 | ||
![]() |
3a2878c737 | ||
![]() |
2cbfb806e2 | ||
![]() |
18211d197a | ||
![]() |
128657c876 | ||
![]() |
930d4d394f | ||
![]() |
cc460657e5 | ||
![]() |
d9f2cb51a3 | ||
![]() |
d736afe4a0 | ||
![]() |
10825c0a8c | ||
![]() |
a75a8e1bfe | ||
![]() |
9a02905fb6 | ||
![]() |
414292812f | ||
![]() |
4d9035ad07 | ||
![]() |
bcf0184fdd | ||
![]() |
817f2cf758 | ||
![]() |
3c5e10f5c3 | ||
![]() |
7d19b811e4 | ||
![]() |
17b3579e5b | ||
![]() |
afa8d4f7f6 | ||
![]() |
b262cb4c3e | ||
![]() |
1c69302c02 | ||
![]() |
5ba36916c6 | ||
![]() |
7f3e2b210a | ||
![]() |
f83df15817 | ||
![]() |
40639f5578 | ||
![]() |
f07e3bfe19 | ||
![]() |
ef9a82ee33 | ||
![]() |
e916662ad4 | ||
![]() |
d7ca46455e | ||
![]() |
d193b9375e | ||
![]() |
90b830853a | ||
![]() |
f6b4cab966 | ||
![]() |
0ebec6fa02 | ||
![]() |
ab2b46adad | ||
![]() |
29fedf2efb | ||
![]() |
c0cd196a74 | ||
![]() |
18e8020bf5 | ||
![]() |
2ac85dff02 | ||
![]() |
5919c4ae20 | ||
![]() |
de12838b3f | ||
![]() |
b55f56dbd6 | ||
![]() |
c8eed6e472 | ||
![]() |
7a360b07f6 | ||
![]() |
f86fcf4190 | ||
![]() |
e4cbdd4f45 | ||
![]() |
4b5448cf00 | ||
![]() |
72e7949faf | ||
![]() |
63f9f40e3d | ||
![]() |
dfbb3515cb | ||
![]() |
7985be10cd | ||
![]() |
6de8324943 | ||
![]() |
79a14e220d | ||
![]() |
4575935a42 | ||
![]() |
134886eedc | ||
![]() |
da308bb104 | ||
![]() |
5087526066 | ||
![]() |
b6f98ad667 | ||
![]() |
b4a6b73146 | ||
![]() |
2ccdc1aad8 | ||
![]() |
68f13297ef | ||
![]() |
6a26e2cf32 | ||
![]() |
9532a42558 | ||
![]() |
f23bc5dfd9 | ||
![]() |
4a4bf6d761 | ||
![]() |
68968b603a | ||
![]() |
eb723b2a0e | ||
![]() |
c51e6fa04e | ||
![]() |
a0ad9200cf | ||
![]() |
99804f366a | ||
![]() |
71fead702d | ||
![]() |
54c9177b03 | ||
![]() |
8157d3c9db | ||
![]() |
03e0da8619 | ||
![]() |
be84b2153f | ||
![]() |
10591a41e6 | ||
![]() |
d41cc18be2 | ||
![]() |
fb6e09d0e3 | ||
![]() |
8766f73333 | ||
![]() |
b32a9006c6 | ||
![]() |
2d613e7281 | ||
![]() |
ca220d8fe5 | ||
![]() |
9971702ec9 | ||
![]() |
e48f14b753 | ||
![]() |
ce046c0b99 | ||
![]() |
e29cb462e1 | ||
![]() |
aee05affd0 | ||
![]() |
f95d197634 | ||
![]() |
075cc5a7aa | ||
![]() |
56c2aa0dc6 | ||
![]() |
fa003374ba | ||
![]() |
ca27a946a1 | ||
![]() |
2845c403f9 | ||
![]() |
9cc2e2987e | ||
![]() |
b9d6336dc7 | ||
![]() |
c2ad00ed6c | ||
![]() |
2d1845f0b8 | ||
![]() |
b5f0758f4d | ||
![]() |
1e2ffe5d15 | ||
![]() |
c887769c0a | ||
![]() |
dc1ac1e094 | ||
![]() |
4b1ceeb642 | ||
![]() |
e5d92fbf43 | ||
![]() |
c323fea5bd | ||
![]() |
32f0fe9051 | ||
![]() |
be74d3efa6 | ||
![]() |
8969c9af8c | ||
![]() |
15cac278d6 | ||
![]() |
9e8a15547d | ||
![]() |
ed74a49aa3 | ||
![]() |
6ef5d0c326 | ||
![]() |
5f871e2643 | ||
![]() |
4f65fa0d82 | ||
![]() |
4d1d763bd9 | ||
![]() |
3286722b6a | ||
![]() |
656255a662 | ||
![]() |
ea7b7a778e | ||
![]() |
9b6de5affd | ||
![]() |
0c03659314 | ||
![]() |
6b08c0f033 | ||
![]() |
a1dcf03a5b | ||
![]() |
556d13c881 | ||
![]() |
0d6c42a9bf | ||
![]() |
690ce16ab4 | ||
![]() |
5f51a5e465 | ||
![]() |
b7521de138 | ||
![]() |
acea6fc595 | ||
![]() |
d8107fe3d5 | ||
![]() |
b40b95be99 | ||
![]() |
6644525dd0 | ||
![]() |
56e66d1c5a | ||
![]() |
90d8afb5a0 | ||
![]() |
d4db61a595 | ||
![]() |
90413b842d | ||
![]() |
43c788acbf | ||
![]() |
ee22b2e4b1 | ||
![]() |
007d56e946 | ||
![]() |
577c4adb14 | ||
![]() |
7f17720ff3 | ||
![]() |
288db1c941 | ||
![]() |
2496fc3eef | ||
![]() |
b43d5ec425 | ||
![]() |
3c43f28966 | ||
![]() |
a3f7c5782e | ||
![]() |
8dec6dfa28 | ||
![]() |
4eb49bdeb2 | ||
![]() |
813cadbd6e | ||
![]() |
58dd2c1a7b | ||
![]() |
104c27ebc8 | ||
![]() |
318099504c | ||
![]() |
8851be03a3 | ||
![]() |
a9a126ab0d | ||
![]() |
19e46fedc8 | ||
![]() |
ff987a0751 | ||
![]() |
0c0ab65b1a | ||
![]() |
52a5908d7e | ||
![]() |
49926a89a2 | ||
![]() |
b63b91f33d | ||
![]() |
67ea361416 | ||
![]() |
3b9078c6b3 | ||
![]() |
3d9e3f997e | ||
![]() |
3c34866faa | ||
![]() |
69cd2784c4 | ||
![]() |
5b7e419a41 | ||
![]() |
7773460d35 | ||
![]() |
9262266480 | ||
![]() |
84f2b4ca68 | ||
![]() |
19ae7a378c | ||
![]() |
f9ca330add | ||
![]() |
5ef990ac7d | ||
![]() |
8099820729 | ||
![]() |
df556f20e9 | ||
![]() |
2c8f2ab58d | ||
![]() |
20c3d62c90 | ||
![]() |
0a28981c74 | ||
![]() |
c8bb24475c | ||
![]() |
81bce61783 | ||
![]() |
71d1b6aa1f | ||
![]() |
c41974c24b | ||
![]() |
3bee88c6cd | ||
![]() |
4c874dfb7e | ||
![]() |
65f499f24e | ||
![]() |
3265bf7fb4 | ||
![]() |
5a437dea4e | ||
![]() |
19b576e8cc | ||
![]() |
67747e458e | ||
![]() |
260c2b9c8f | ||
![]() |
255ef1d8ef | ||
![]() |
53c633c646 | ||
![]() |
cec67a91d4 | ||
![]() |
4408dfe59d | ||
![]() |
c4274d2fc4 | ||
![]() |
b0103f31b7 | ||
![]() |
18905890d4 | ||
![]() |
6858e0fb59 | ||
![]() |
cf595a7d7d | ||
![]() |
e681d27bb8 | ||
![]() |
8941e04390 | ||
![]() |
e186681f39 | ||
![]() |
a578fa32e9 | ||
![]() |
6b40e8309c | ||
![]() |
5ff51351af | ||
![]() |
d66e4e0001 | ||
![]() |
2184eaf70b | ||
![]() |
29fc0598f6 | ||
![]() |
a7760e975a | ||
![]() |
e2397cb0a4 | ||
![]() |
24ff670886 | ||
![]() |
d24b7497c9 | ||
![]() |
0ecaa342f9 | ||
![]() |
141ac87c6e | ||
![]() |
057e6dcfed | ||
![]() |
9c69c90a66 | ||
![]() |
4df6ecc654 | ||
![]() |
c106d05098 | ||
![]() |
f3f426e949 | ||
![]() |
52d0ed1217 | ||
![]() |
511138269d | ||
![]() |
22dda6194c | ||
![]() |
aa2ef39f32 | ||
![]() |
a744b88c5c | ||
![]() |
2847601fc5 | ||
![]() |
bfbdf1cd3f | ||
![]() |
ed1694a818 | ||
![]() |
0ee121c014 | ||
![]() |
312e96a881 | ||
![]() |
c169c5037a | ||
![]() |
a82ae304a0 | ||
![]() |
adb30c5105 | ||
![]() |
aad11f2518 | ||
![]() |
737d389493 | ||
![]() |
4b071fbf17 | ||
![]() |
982a0c6e53 | ||
![]() |
91adaac722 | ||
![]() |
138a7c9abe | ||
![]() |
c7099d694e | ||
![]() |
fde1039707 | ||
![]() |
73e087936a | ||
![]() |
260fd5949e | ||
![]() |
a4939181a5 | ||
![]() |
cab56451ff | ||
![]() |
7b32bbacd6 | ||
![]() |
a15707d655 | ||
![]() |
714a9f1198 | ||
![]() |
2a91c54b0e | ||
![]() |
3272b8eda7 | ||
![]() |
cd432a22b6 | ||
![]() |
9ac483156e | ||
![]() |
d0f39027af | ||
![]() |
5d8a59533d | ||
![]() |
243a72008b | ||
![]() |
e56cdac96a | ||
![]() |
cf374737fc | ||
![]() |
3d043f5264 | ||
![]() |
032f53e4e3 | ||
![]() |
f68ae4b8d8 | ||
![]() |
fa40381fb4 | ||
![]() |
544b6243ba | ||
![]() |
0a03cbb89c | ||
![]() |
c00d75f047 | ||
![]() |
5dce0684f5 | ||
![]() |
cb44999538 | ||
![]() |
4a9de2edf3 | ||
![]() |
8c3728f8b7 | ||
![]() |
212c58f67c | ||
![]() |
f5d89c66ea | ||
![]() |
8fb139ff63 | ||
![]() |
0c0fb5da1c | ||
![]() |
65a33589c0 | ||
![]() |
7ec5a95de8 | ||
![]() |
26289eec99 | ||
![]() |
cc0a01bbdb | ||
![]() |
a0fb289aaf | ||
![]() |
94045aec91 | ||
![]() |
b70d4c54c1 | ||
![]() |
f269b820fc | ||
![]() |
f91bde1fca | ||
![]() |
73ac71dadf | ||
![]() |
52fcf52ecc | ||
![]() |
55c7c4e8bf | ||
![]() |
d6a15d4090 | ||
![]() |
21a87daf64 | ||
![]() |
c712ab3163 | ||
![]() |
6c27c3dcf8 | ||
![]() |
f8de6c2ea9 | ||
![]() |
b2e8c23944 | ||
![]() |
bfc6a69d77 | ||
![]() |
3abf81fda2 | ||
![]() |
4caef9c7e6 | ||
![]() |
f9edfdef72 | ||
![]() |
4e0e4b9184 | ||
![]() |
908926bf73 | ||
![]() |
2ba81cc7d6 | ||
![]() |
e77e1fb840 | ||
![]() |
f0f47ca2f0 | ||
![]() |
07920fda9f | ||
![]() |
48e4447212 | ||
![]() |
b69dcafcc6 | ||
![]() |
89e06b0801 | ||
![]() |
5e1a6eb084 | ||
![]() |
f89a48fb2c | ||
![]() |
ddb65012ce | ||
![]() |
bb0fe0ea37 | ||
![]() |
747cdf0243 | ||
![]() |
385ec5e9ca | ||
![]() |
bcbdc35d72 | ||
![]() |
6053369474 | ||
![]() |
ed1e0852b5 | ||
![]() |
23ce46439a | ||
![]() |
d9b35018e7 | ||
![]() |
571ab1313d | ||
![]() |
aff82c4733 | ||
![]() |
2d4fc0af07 | ||
![]() |
7cadf35642 | ||
![]() |
73e1ea5ff1 | ||
![]() |
bc87caf640 | ||
![]() |
95dfb391c4 | ||
![]() |
4b973c9655 | ||
![]() |
23f24a3939 | ||
![]() |
b3ed22806b | ||
![]() |
4afefafc76 | ||
![]() |
d2a1d8620f | ||
![]() |
fdfc028a2c | ||
![]() |
48cd42fee0 | ||
![]() |
b215eff444 | ||
![]() |
1bf66a97ae | ||
![]() |
cc6890a495 | ||
![]() |
418dd834c0 | ||
![]() |
e52faae332 | ||
![]() |
31809fdf61 | ||
![]() |
17504c1713 | ||
![]() |
e29b79fdc9 | ||
![]() |
b0009cc999 | ||
![]() |
384eb2b8ee | ||
![]() |
5fa0627218 | ||
![]() |
e66660d2df | ||
![]() |
df6320c39f | ||
![]() |
ca667c02be | ||
![]() |
62d0754b33 | ||
![]() |
4c4ca0d202 | ||
![]() |
5c68d117c6 | ||
![]() |
21b9ae47ab | ||
![]() |
e8687119c9 | ||
![]() |
9c09e26aaa | ||
![]() |
c223abad60 | ||
![]() |
769de55317 | ||
![]() |
0dfe765ae1 | ||
![]() |
b94ce2b20d | ||
![]() |
89eb61b4a6 | ||
![]() |
32ba55e726 | ||
![]() |
844ac23666 | ||
![]() |
657036384d | ||
![]() |
b13ce5b17c | ||
![]() |
8f0f5a5bc5 | ||
![]() |
d23a064ca2 | ||
![]() |
3b0dc66046 | ||
![]() |
356bde650b | ||
![]() |
6d25496f89 | ||
![]() |
dfeeb864a5 | ||
![]() |
25c36d26db | ||
![]() |
36721c63e0 | ||
![]() |
69cd89ddb8 | ||
![]() |
2db4b54986 | ||
![]() |
303a4d20ed | ||
![]() |
a09bfafd26 | ||
![]() |
822329af63 | ||
![]() |
0b90e17307 | ||
![]() |
00817b4393 | ||
![]() |
2a5bbcb8d4 | ||
![]() |
7f03579855 | ||
![]() |
c7e42d1e88 | ||
![]() |
e3fd91681c | ||
![]() |
c8392332c7 | ||
![]() |
14d7dafb79 | ||
![]() |
373d5e14b8 | ||
![]() |
8b89896082 | ||
![]() |
e7d213534e | ||
![]() |
859b1d0a1c | ||
![]() |
2b6a14c612 | ||
![]() |
07051017b9 | ||
![]() |
0d5f238c75 | ||
![]() |
936c75b4ed | ||
![]() |
8d1bdfed25 | ||
![]() |
440205531f | ||
![]() |
8f45642a25 | ||
![]() |
1e6ca8c403 | ||
![]() |
113e329d7a | ||
![]() |
48ae688873 | ||
![]() |
fe77180748 | ||
![]() |
48b88b9d92 | ||
![]() |
f57a8bc6cd | ||
![]() |
1b827eb67b | ||
![]() |
c3521db5ba | ||
![]() |
b51e47233e | ||
![]() |
1bf9d3c432 | ||
![]() |
1c47d12033 | ||
![]() |
1250060848 | ||
![]() |
4712c3d9ef | ||
![]() |
56cf1cf18f | ||
![]() |
0427766b9d | ||
![]() |
8cf20cdef2 | ||
![]() |
b3f74a3e9b | ||
![]() |
38f15503e9 | ||
![]() |
47f15f6881 | ||
![]() |
b0c8bf9625 | ||
![]() |
089c774ad6 | ||
![]() |
a2ca532749 | ||
![]() |
a6e7dd6160 | ||
![]() |
7b6f3c029d | ||
![]() |
6c31056be4 | ||
![]() |
2f8287b017 | ||
![]() |
0ef4012b03 | ||
![]() |
438d70e8ba | ||
![]() |
04214abc85 | ||
![]() |
32fa646e47 | ||
![]() |
78952816b9 | ||
![]() |
6057496ff8 | ||
![]() |
76f1832b4e | ||
![]() |
d8e1c1ee8a | ||
![]() |
3de8ec0759 | ||
![]() |
de3d5e6583 | ||
![]() |
a772c7baa9 | ||
![]() |
5730fcb611 | ||
![]() |
b601e94791 | ||
![]() |
b7bf4ea62b | ||
![]() |
46466d5c11 | ||
![]() |
1892dc09c3 | ||
![]() |
e5a710d7d5 | ||
![]() |
561e18a044 | ||
![]() |
fb9c29af52 |
@@ -15,7 +15,7 @@ jobs:
|
||||
# Build the **entire** app for macOS.
|
||||
build-macos:
|
||||
macos:
|
||||
xcode: 12.5.1
|
||||
xcode: 14.2.0
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
@@ -62,13 +62,14 @@ jobs:
|
||||
|
||||
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
|
||||
# Note: Code signing is done using CSC_LINK (see https://www.electron.build/code-signing).
|
||||
# To test signing the code in the CI, add "export CSC_FOR_PULL_REQUEST=true && " before the command.
|
||||
- run:
|
||||
name: Build GDevelop IDE
|
||||
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --mac --publish=never
|
||||
command: export CSC_FOR_PULL_REQUEST=true && export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && CI=false npm run build -- --mac --publish=never
|
||||
|
||||
- run:
|
||||
name: Clean dist folder to keep only installers/binaries.
|
||||
command: rm -rf "newIDE/electron-app/dist/mac/GDevelop 5.app" && rm -rf "newIDE/electron-app/dist/mac-arm64/GDevelop 5.app"
|
||||
command: rm -rf "newIDE/electron-app/dist/mac-universal/GDevelop 5.app"
|
||||
|
||||
# Upload artifacts (CircleCI)
|
||||
- store_artifacts:
|
||||
@@ -101,8 +102,8 @@ jobs:
|
||||
command: sudo apt-get update && sudo apt install cmake
|
||||
|
||||
- run:
|
||||
name: Install Python3 dependencies for Emscripten
|
||||
command: sudo apt install python-is-python3 python3-distutils -y
|
||||
name: Install Python3 dependencies for Emscripten
|
||||
command: sudo apt install python-is-python3 python3-distutils -y
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
@@ -178,8 +179,8 @@ jobs:
|
||||
command: sudo apt-get update && sudo apt install cmake
|
||||
|
||||
- run:
|
||||
name: Install Python3 dependencies for Emscripten
|
||||
command: sudo apt install python-is-python3 python3-distutils -y
|
||||
name: Install Python3 dependencies for Emscripten
|
||||
command: sudo apt install python-is-python3 python3-distutils -y
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
|
@@ -1,6 +0,0 @@
|
||||
# This is the Dockerfile to create a "devcontainer".
|
||||
# This is a way to quickly create a development environment,
|
||||
# that can be used with GitHub workspaces.
|
||||
|
||||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/codespaces-linux/.devcontainer/base.Dockerfile
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/universal:1-focal
|
@@ -1,16 +0,0 @@
|
||||
# Devcontainer (development environment in the cloud) for GDevelop (beta)
|
||||
|
||||
A devcontainer is the configuration to run a cloud development environment, available remotely.
|
||||
This is notably used to run a **[GitHub Codespace](https://docs.github.com/en/github/developing-online-with-codespaces/about-codespaces)**. The advantage is that you can quickly experiment and do changes without installing anything on your computer.
|
||||
|
||||
> ⚠️ This development environment is in beta, and not everything is supported. This is useful for playing a bit with GDevelop codebase or to make quick changes. **In particular, it's not possible to test your changes on GDJS** because only the web-app can be launched.
|
||||
|
||||
It's recommended that you follow the usual [README](../newIDE/README.md) to get started, with development tools installed on your computer.
|
||||
|
||||
## Start a GitHub workspace to work on GDevelop (beta)
|
||||
|
||||
- Subscribe to the [beta edition of GitHub workspace](https://docs.github.com/en/github/developing-online-with-codespaces/about-codespaces#joining-the-beta).
|
||||
- In the repository GitHub page, click **Code** and then choose **Open with Codespaces**.
|
||||
- Wait for the Codespace to load and Visual Studio Code to open.
|
||||
- When it's ready, open a terminal in Visual Studio Code.
|
||||
- Follow the usual [README in `newIDE`](../newIDE/README.md) to get started, like you would do on your own computer.
|
@@ -1,51 +1,14 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/codespaces-linux
|
||||
{
|
||||
"name": "GitHub Codespaces for GDevelop",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile"
|
||||
},
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/zsh",
|
||||
"go.toolsManagement.checkForUpdates": "off",
|
||||
"go.useLanguageServer": true,
|
||||
"go.gopath": "/go",
|
||||
"go.goroot": "/usr/local/go",
|
||||
"python.pythonPath": "/opt/python/latest/bin/python",
|
||||
"python.linting.enabled": true,
|
||||
"python.linting.pylintEnabled": true,
|
||||
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
|
||||
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
|
||||
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
|
||||
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
|
||||
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
|
||||
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
|
||||
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
|
||||
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
|
||||
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint",
|
||||
"lldb.executable": "/usr/bin/lldb",
|
||||
"files.watcherExclude": {
|
||||
"**/target/**": true
|
||||
}
|
||||
},
|
||||
"remoteUser": "codespace",
|
||||
"overrideCommand": false,
|
||||
"workspaceMount": "source=${localWorkspaceFolder},target=/home/codespace/workspace,type=bind,consistency=cached",
|
||||
"workspaceFolder": "/home/codespace/workspace",
|
||||
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined", "--privileged", "--init" ],
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"GitHub.vscode-pull-request-github",
|
||||
"esbenp.prettier-vscode",
|
||||
"ms-vscode.cpptools",
|
||||
"xaver.clang-format",
|
||||
"flowtype.flow-for-vscode"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// "oryx build" will automatically install your dependencies and attempt to build your project
|
||||
"postCreateCommand": "oryx build -p virtualenv_name=.venv || echo 'Could not auto-build. Skipping.'"
|
||||
"image": "mcr.microsoft.com/devcontainers/universal:2",
|
||||
"onCreateCommand": "cd newIDE/app && npm install && cd ../electron-app && npm install",
|
||||
"forwardPorts": [3000],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"esbenp.prettier-vscode",
|
||||
"ms-vscode.cpptools",
|
||||
"flowtype.flow-for-vscode"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
37
.github/ISSUE_TEMPLATE/--automatic-crash.yml
vendored
Normal file
37
.github/ISSUE_TEMPLATE/--automatic-crash.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: 💥 Automatic crash report
|
||||
description: Do not use this template for bug reports. This template is only for automatic crash reports.
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe what you were doing when the crash happened
|
||||
description: If applicable, add screenshots to help explain your problem.
|
||||
placeholder: |
|
||||
1. Went to '...'
|
||||
2. Clicked on '...'
|
||||
3. Scrolled down to '...'
|
||||
4. Saw error
|
||||
- type: input
|
||||
id: gdevelop_version
|
||||
attributes:
|
||||
label: GDevelop version
|
||||
description: |
|
||||
The version of GDevelop used. Leave the prefilled value.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: platform_info
|
||||
attributes:
|
||||
label: Platform info
|
||||
description: |
|
||||
The platform you are using GDevelop on. Leave the prefilled value.
|
||||
- type: textarea
|
||||
id: error_stack
|
||||
attributes:
|
||||
label: Additional error context
|
||||
description: Additonal context about the problem. Leave the prefilled value.
|
||||
- type: textarea
|
||||
id: component_stack
|
||||
attributes:
|
||||
label: Additional component context
|
||||
description: Additonal context about the problem. Leave the prefilled value.
|
28
.github/ISSUE_TEMPLATE/--bug-report.md
vendored
28
.github/ISSUE_TEMPLATE/--bug-report.md
vendored
@@ -1,28 +0,0 @@
|
||||
---
|
||||
name: "\U0001F41BBug report"
|
||||
about: Create a bug report about GDevelop or the game engine
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Describe the bug
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
Please double check that the bug is not already reported in the issues list.
|
||||
|
||||
## To Reproduce
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
* Please include a link to a game if possible!
|
||||
* If applicable, add screenshots to help explain your problem.
|
||||
|
||||
## Other details
|
||||
* Include any OS/browser version/smartphone that you're using
|
||||
* Which version of GDevelop are you using? The desktop app or the web-app?
|
||||
* Add any other context about the problem here.
|
78
.github/ISSUE_TEMPLATE/--bug-report.yml
vendored
Normal file
78
.github/ISSUE_TEMPLATE/--bug-report.yml
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
name: 🐛Bug report
|
||||
description: Create a bug report about GDevelop or the game engine
|
||||
body:
|
||||
- type: checkboxes
|
||||
id: searched_issues
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
options:
|
||||
- label: I have searched the [existing issues](https://github.com/4ian/GDevelop/issues)
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction_steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: |
|
||||
* Please include a link to a game if possible!
|
||||
* If applicable, add screenshots to help explain your problem.
|
||||
placeholder: |
|
||||
1. Go to '...'
|
||||
2. Click on '...'
|
||||
3. Scroll down to '...'
|
||||
4. See error
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: platform
|
||||
attributes:
|
||||
label: GDevelop platform
|
||||
description: Which platform of GDevelop are you using?
|
||||
multiple: true
|
||||
options:
|
||||
- Desktop
|
||||
- Web
|
||||
- Mobile
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: gdevelop_version
|
||||
attributes:
|
||||
label: GDevelop version
|
||||
description: |
|
||||
Which version of GDevelop are you using?
|
||||
Take a look here: [Editor Home - About GDevelop - "This version of GDevelop is: ~~~"]
|
||||
placeholder: 5.1.159? 5.1.160?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: platform_info
|
||||
attributes:
|
||||
label: Platform info
|
||||
value: |
|
||||
<details>
|
||||
|
||||
*OS (e.g. Windows, Linux, macOS, Android, iOS)*
|
||||
>
|
||||
|
||||
*OS Version (e.g. Windows 10, macOS 10.15)*
|
||||
>
|
||||
|
||||
*Browser(For Web) (e.g. Chrome, Firefox, Safari)*
|
||||
>
|
||||
|
||||
*Device(For Mobile) (e.g. iPhone 12, Samsung Galaxy S21)*
|
||||
>
|
||||
|
||||
</details>
|
||||
- type: textarea
|
||||
id: additional_context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here.
|
26
.github/workflows/build-storybook.yml
vendored
26
.github/workflows/build-storybook.yml
vendored
@@ -9,6 +9,10 @@ name: Build Storybook
|
||||
on:
|
||||
# Launch on all commits.
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
tags-ignore:
|
||||
- "**" # Don't run on new tags
|
||||
# Allows to run this workflow manually from the Actions tab,
|
||||
# to publish on Chromatic (not done by default).
|
||||
workflow_dispatch:
|
||||
@@ -17,31 +21,23 @@ jobs:
|
||||
build-storybook:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 50
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: "npm"
|
||||
cache-dependency-path: "newIDE/app/package-lock.json"
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
uses: aws-actions/configure-aws-credentials@v2
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.BUILD_STORYBOOK_AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.BUILD_STORYBOOK_AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: us-east-1
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 50
|
||||
|
||||
# Cache npm dependencies to speed up the workflow
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-newIDE-app-node_modules
|
||||
with:
|
||||
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
|
||||
|
||||
- name: Install newIDE dependencies
|
||||
run: npm install
|
||||
working-directory: newIDE/app
|
||||
|
20
.github/workflows/extract-translations.yml
vendored
20
.github/workflows/extract-translations.yml
vendored
@@ -4,6 +4,10 @@ name: Extract translations
|
||||
on:
|
||||
# Execute for all commits (to ensure translations extraction works)
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
tags-ignore:
|
||||
- "**" # Don't run on new tags
|
||||
# Allows to run this workflow manually from the Actions tab.
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -11,26 +15,18 @@ jobs:
|
||||
extract-translations:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# Cache npm dependencies to speed up the workflow
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-newIDE-app-node_modules
|
||||
with:
|
||||
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
|
||||
cache: "npm"
|
||||
cache-dependency-path: "newIDE/app/package-lock.json"
|
||||
|
||||
- name: Install gettext
|
||||
run: sudo apt update && sudo apt install gettext -y
|
||||
|
||||
- name: Install newIDE dependencies
|
||||
run: npm install
|
||||
run: npm ci
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Extract translations
|
||||
|
42
.github/workflows/issues.yml
vendored
42
.github/workflows/issues.yml
vendored
@@ -3,41 +3,17 @@ on:
|
||||
issues:
|
||||
types: [opened]
|
||||
jobs:
|
||||
autoclose:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Autoclose issues about adding a bug without changing the bug report template
|
||||
uses: arkon/issue-closer-action@v1.1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
type: "body"
|
||||
regex: ".*Scroll down to '\\.\\.\\.\\.'.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any steps to reproduce the bug.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop.io/), the Discord chat or [read the documentation](https://wiki.gdevelop.io/gdevelop5/start) to learn more about GDevelop. Thanks!"
|
||||
- name: Autoclose known beta 105 web-app update bug
|
||||
uses: arkon/issue-closer-action@v1.1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
type: "body"
|
||||
regex: ".*_instance.getRawFloatProperty is not a function.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."
|
||||
- name: Autoclose known beta 114 web-app update bug
|
||||
uses: arkon/issue-closer-action@v1.1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
type: "body"
|
||||
regex: ".*getAssociatedSettings is not a function.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."
|
||||
autocomment:
|
||||
runs-on: ubuntu-latest
|
||||
if: contains(github.event.issue.body, 'The node to be removed is not a child of this node')
|
||||
steps:
|
||||
- name: Autocomment indications on bug if it looks like #3453
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
with:
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hi @${{ github.actor }}!
|
||||
Thank you for taking the time to open an issue.
|
||||
- name: Autocomment indications on bug if it looks like #3453
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hi @${{ github.actor }}!
|
||||
Thank you for taking the time to open an issue.
|
||||
|
||||
The solved issue #3453 mentioned a similar error, maybe it could help fix this new issue.
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
The solved issue #3453 mentioned a similar error, maybe it could help fix this new issue.
|
||||
|
68
.github/workflows/pull-requests.yml
vendored
68
.github/workflows/pull-requests.yml
vendored
@@ -1,29 +1,53 @@
|
||||
name: GDevelop Issues automatic workflow
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
jobs:
|
||||
read-locales-metadata:
|
||||
if: contains(github.event.pull_request.title, '[Auto PR] Update translations')
|
||||
if: github.event.pull_request.title == '[Auto PR] Update translations'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
COMMENT_TITLE: "Translation ratio changes"
|
||||
steps:
|
||||
- name: Read and format locales metadata
|
||||
run: |
|
||||
LANS=($(git diff HEAD^ HEAD --unified=5 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\s+\"languageName" | sed -E "s/^ *\"languageName\": \"//g" | sed -E "s/\",//g" | sed -E "s/ /_/g"))
|
||||
ADDS=($(git diff HEAD^ HEAD --unified=0 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\+\s*\"translationRatio\"" | sed -E "s/^\+ *\"translationRatio\": //g"))
|
||||
SUBS=($(git diff HEAD^ HEAD --unified=0 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\-\s*\"translationRatio\"" | sed -E "s/^\- *\"translationRatio\": //g"))
|
||||
touch sumup.txt
|
||||
for index in ${!ADDS[@]}; do
|
||||
echo ${LANS[index]} | sed -E "s/_/ /g" >> sumup.txt
|
||||
DELTA=$(bc <<< "scale=2;(${ADDS[index]}-${SUBS[index]})*100/1")
|
||||
echo $DELTA % >> sumup.txt
|
||||
done
|
||||
- name: Store sumup in outputs
|
||||
id: sumup
|
||||
run: echo "::set-output name=sumupFileContent::$(cat sumup.txt)"
|
||||
- name: Autocomment pull request with sumup
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
with:
|
||||
issue-number: ${{ github.event.number }}
|
||||
body: ${{ steps.sumup.outputs.sumupFileContent}}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Read and format locales metadata
|
||||
env:
|
||||
BASE: ${{ github.event.pull_request.base.sha }}
|
||||
HEAD: ${{ github.event.pull_request.head.sha }}
|
||||
run: |
|
||||
LANS=($(git diff $BASE...$HEAD -- newIDE/app/src/locales/LocalesMetadata.js | grep -E "^\s+\"languageName" | sed -E "s/^ *\"languageName\": \"//g" | sed -E "s/\",//g" | sed -E "s/ /_/g"))
|
||||
ADDS=($(git diff $BASE...$HEAD -- newIDE/app/src/locales/LocalesMetadata.js | grep -E "^\+\s*\"translationRatio\"" | sed -E "s/^\+ *\"translationRatio\": //g"))
|
||||
SUBS=($(git diff $BASE...$HEAD -- newIDE/app/src/locales/LocalesMetadata.js | grep -E "^\-\s*\"translationRatio\"" | sed -E "s/^\- *\"translationRatio\": //g"))
|
||||
touch sumup.md
|
||||
echo "## $COMMENT_TITLE" >> sumup.md
|
||||
echo "" >> sumup.md
|
||||
echo "| Language | Change |" >> sumup.md
|
||||
echo "| --- | --- |" >> sumup.md
|
||||
for index in ${!ADDS[@]}; do
|
||||
DELTA=$(echo "scale=3; (${ADDS[index]} - ${SUBS[index]})*100/1" | bc)
|
||||
if (( $(echo "$DELTA == 0" | bc -l) )); then
|
||||
continue
|
||||
fi
|
||||
LANGUAGE=${LANS[index]//_/ }
|
||||
echo "| $LANGUAGE | $(printf "%1.3f" $DELTA) % |" >> sumup.md
|
||||
done
|
||||
- name: Find Comment
|
||||
uses: peter-evans/find-comment@v2
|
||||
id: fc
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.number }}
|
||||
body-includes: ${{ env.COMMENT_TITLE }}
|
||||
- name: Autocomment pull request with sumup
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.number }}
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
edit-mode: replace
|
||||
body-path: "sumup.md"
|
||||
|
18
.github/workflows/update-translations.yml
vendored
18
.github/workflows/update-translations.yml
vendored
@@ -7,6 +7,8 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags-ignore:
|
||||
- "**" # Don't run on new tags
|
||||
# Allows to run this workflow manually from the Actions tab.
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -14,20 +16,12 @@ jobs:
|
||||
update-translations:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# Cache npm dependencies to speed up the workflow
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-newIDE-app-node_modules
|
||||
with:
|
||||
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
|
||||
cache: "npm"
|
||||
cache-dependency-path: "newIDE/app/package-lock.json"
|
||||
|
||||
- name: Install gettext
|
||||
run: sudo apt update && sudo apt install gettext -y
|
||||
@@ -64,7 +58,7 @@ jobs:
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Create a Pull Request with the changes
|
||||
uses: peter-evans/create-pull-request@v3.10.1
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
commit-message: Update translations [skip ci]
|
||||
branch: chore/update-translations
|
||||
|
257
.vscode/settings.json
vendored
257
.vscode/settings.json
vendored
@@ -1,131 +1,134 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"files.associations": {
|
||||
"*.idl": "java",
|
||||
"Fastfile": "ruby",
|
||||
"iosfwd": "cpp",
|
||||
"functional": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"random": "cpp",
|
||||
"__config": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"exception": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"new": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"complex": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"memory": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"hashtable": "cpp",
|
||||
"tuple": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"__split_buffer": "cpp",
|
||||
"deque": "cpp",
|
||||
"iterator": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"queue": "cpp",
|
||||
"regex": "cpp",
|
||||
"set": "cpp",
|
||||
"stack": "cpp",
|
||||
"string": "cpp",
|
||||
"vector": "cpp",
|
||||
"iostream": "cpp",
|
||||
"__functional_03": "cpp",
|
||||
"__hash_table": "cpp",
|
||||
"__tree": "cpp",
|
||||
"bitset": "cpp",
|
||||
"__bit_reference": "cpp",
|
||||
"__mutex_base": "cpp",
|
||||
"fstream": "cpp",
|
||||
"ios": "cpp",
|
||||
"__locale": "cpp",
|
||||
"valarray": "cpp",
|
||||
"freeglut_spaceball.c": "cpp",
|
||||
"__tuple": "cpp",
|
||||
"hash_map": "cpp",
|
||||
"hash_set": "cpp",
|
||||
"system_error": "cpp",
|
||||
"__nullptr": "cpp",
|
||||
"__functional_base": "cpp",
|
||||
"__functional_base_03": "cpp",
|
||||
"chrono": "cpp",
|
||||
"ratio": "cpp",
|
||||
"atomic": "cpp",
|
||||
"locale": "cpp",
|
||||
"string_view": "cpp",
|
||||
"__string": "cpp",
|
||||
"cstring": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"mutex": "cpp",
|
||||
"__hash": "cpp",
|
||||
"__debug": "cpp",
|
||||
"__threading_support": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"numeric": "cpp",
|
||||
"__memory": "cpp",
|
||||
"__errc": "cpp",
|
||||
"__node_handle": "cpp",
|
||||
"bit": "cpp",
|
||||
"optional": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstddef": "cpp",
|
||||
"xstring": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xmemory0": "cpp",
|
||||
"memory_resource": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
"Binaries/Output": true,
|
||||
"GDJS/Runtime-dist": true,
|
||||
"docs": true,
|
||||
"newIDE/electron-app/dist": true,
|
||||
"newIDE/app/build": true,
|
||||
"newIDE/app/resources/GDJS": true,
|
||||
"newIDE/electron-app/app/www": true
|
||||
},
|
||||
// Support for Flowtype (for newIDE):
|
||||
"javascript.validate.enable": false,
|
||||
"flow.useNPMPackagedFlow": true,
|
||||
"files.associations": {
|
||||
"*.idl": "java",
|
||||
"Fastfile": "ruby",
|
||||
"iosfwd": "cpp",
|
||||
"functional": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"random": "cpp",
|
||||
"__config": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"exception": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"new": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"complex": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"memory": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"hashtable": "cpp",
|
||||
"tuple": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"__split_buffer": "cpp",
|
||||
"deque": "cpp",
|
||||
"iterator": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"queue": "cpp",
|
||||
"regex": "cpp",
|
||||
"set": "cpp",
|
||||
"stack": "cpp",
|
||||
"string": "cpp",
|
||||
"vector": "cpp",
|
||||
"iostream": "cpp",
|
||||
"__functional_03": "cpp",
|
||||
"__hash_table": "cpp",
|
||||
"__tree": "cpp",
|
||||
"bitset": "cpp",
|
||||
"__bit_reference": "cpp",
|
||||
"__mutex_base": "cpp",
|
||||
"fstream": "cpp",
|
||||
"ios": "cpp",
|
||||
"__locale": "cpp",
|
||||
"valarray": "cpp",
|
||||
"freeglut_spaceball.c": "cpp",
|
||||
"__tuple": "cpp",
|
||||
"hash_map": "cpp",
|
||||
"hash_set": "cpp",
|
||||
"system_error": "cpp",
|
||||
"__nullptr": "cpp",
|
||||
"__functional_base": "cpp",
|
||||
"__functional_base_03": "cpp",
|
||||
"chrono": "cpp",
|
||||
"ratio": "cpp",
|
||||
"atomic": "cpp",
|
||||
"locale": "cpp",
|
||||
"string_view": "cpp",
|
||||
"__string": "cpp",
|
||||
"cstring": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"mutex": "cpp",
|
||||
"__hash": "cpp",
|
||||
"__debug": "cpp",
|
||||
"__threading_support": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"numeric": "cpp",
|
||||
"__memory": "cpp",
|
||||
"__errc": "cpp",
|
||||
"__node_handle": "cpp",
|
||||
"bit": "cpp",
|
||||
"optional": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstddef": "cpp",
|
||||
"xstring": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xmemory0": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"__bits": "cpp",
|
||||
"__verbose_abort": "cpp",
|
||||
"variant": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
"Binaries/Output": true,
|
||||
"GDJS/Runtime-dist": true,
|
||||
"docs": true,
|
||||
"newIDE/electron-app/dist": true,
|
||||
"newIDE/app/build": true,
|
||||
"newIDE/app/resources/GDJS": true,
|
||||
"newIDE/electron-app/app/www": true
|
||||
},
|
||||
// Support for Flowtype (for newIDE):
|
||||
"javascript.validate.enable": false,
|
||||
"flow.useNPMPackagedFlow": true,
|
||||
|
||||
// Clang format styling (duplicated in scripts/CMakeClangUtils.txt)
|
||||
"C_Cpp.clang_format_style": "{BasedOnStyle: Google, BinPackParameters: false, BinPackArguments: false}"
|
||||
// Clang format styling (duplicated in scripts/CMakeClangUtils.txt)
|
||||
"C_Cpp.clang_format_style": "{BasedOnStyle: Google, BinPackParameters: false, BinPackArguments: false}"
|
||||
}
|
||||
|
@@ -1,3 +1,3 @@
|
||||
This is the directory where native or WebAssembly binaries of the C++ code of GDCore and GDJS are produced.
|
||||
|
||||
See GDevelop.js README for the instructions to compile after a change in the C++ source code.
|
||||
See GDevelop.js README for the instructions to compile after a change in the C++ source code.
|
||||
|
124
CMakeLists.txt
124
CMakeLists.txt
@@ -1,100 +1,100 @@
|
||||
#This is the CMake file used to build GDevelop.
|
||||
#For more information, see the Readme.md file.
|
||||
# This is the CMake file used to build GDevelop.
|
||||
# For more information, see the README.md file.
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(SET CMP0011 NEW)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
# Add utility functions
|
||||
include(scripts/CMakeClangUtils.txt) # To add clang-format and clang-tidy support to a target
|
||||
|
||||
# Macro for defining an option
|
||||
macro(gd_set_option var default type docstring)
|
||||
if(NOT DEFINED ${var})
|
||||
set(${var} ${default})
|
||||
endif()
|
||||
set(${var} ${${var}} CACHE ${type} ${docstring} FORCE)
|
||||
if(NOT DEFINED ${var})
|
||||
set(${var} ${default})
|
||||
endif()
|
||||
set(${var} ${${var}} CACHE ${type} ${docstring} FORCE)
|
||||
endmacro()
|
||||
|
||||
# Set options
|
||||
gd_set_option(BUILD_CORE TRUE BOOL "TRUE to build GDevelop Core library")
|
||||
gd_set_option(BUILD_GDJS TRUE BOOL "TRUE to build GDevelop JS Platform")
|
||||
gd_set_option(BUILD_EXTENSIONS TRUE BOOL "TRUE to build the extensions")
|
||||
gd_set_option(BUILD_TESTS TRUE BOOL "TRUE to build the tests")
|
||||
|
||||
# Disable deprecated code
|
||||
set(NO_GUI TRUE CACHE BOOL "" FORCE) #Force disable old GUI related code.
|
||||
set(NO_GUI TRUE CACHE BOOL "" FORCE) # Force disable old GUI related code.
|
||||
|
||||
#Setting up installation directory, for Linux (has to be done before "project" command).
|
||||
IF(NOT WIN32)
|
||||
if (NOT APPLE)
|
||||
gd_set_option(GD_INSTALL_PREFIX "/opt/gdevelop/" STRING "The directory where GDevelop should be installed")
|
||||
ELSE()
|
||||
gd_set_option(GD_INSTALL_PREFIX "." STRING "The directory where GDevelop should be installed")
|
||||
ENDIF()
|
||||
# Setting up installation directory, for Linux (has to be done before "project" command).
|
||||
if(NOT WIN32)
|
||||
if(NOT APPLE)
|
||||
gd_set_option(GD_INSTALL_PREFIX "/opt/gdevelop/" STRING "The directory where GDevelop should be installed")
|
||||
else()
|
||||
gd_set_option(GD_INSTALL_PREFIX "." STRING "The directory where GDevelop should be installed")
|
||||
endif()
|
||||
|
||||
#As we embed SFML, prevent it to be installed system-wide
|
||||
# As we embed SFML, prevent it to be installed system-wide
|
||||
set(CMAKE_INSTALL_PREFIX "${GD_INSTALL_PREFIX}/useless")
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
project(GDevelop)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
IF(NOT WIN32 AND NOT APPLE AND NOT BUILD_TESTS)
|
||||
SET(CMAKE_SKIP_BUILD_RPATH TRUE) #Avoid errors when packaging for linux.
|
||||
ENDIF()
|
||||
IF(APPLE)
|
||||
if(NOT WIN32 AND NOT APPLE AND NOT BUILD_TESTS)
|
||||
set(CMAKE_SKIP_BUILD_RPATH TRUE) # Avoid errors when packaging for linux.
|
||||
endif()
|
||||
if(APPLE)
|
||||
set(CMAKE_MACOSX_RPATH 1)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
|
||||
set(CMAKE_INSTALL_RPATH ".")
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-potentially-evaluated-expression")
|
||||
ENDIF()
|
||||
#Sanity checks
|
||||
IF ("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
message( "CMAKE_BUILD_TYPE is empty, assuming build type is Release" )
|
||||
add_compile_options(
|
||||
-D_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_
|
||||
-Wno-potentially-evaluated-expression)
|
||||
endif()
|
||||
# Sanity checks
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
message(STATUS "CMAKE_BUILD_TYPE is empty, assuming build type is Release")
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
IF("${CMAKE_BUILD_TYPE}" STREQUAL "Release" AND NOT WIN32 AND CMAKE_COMPILER_IS_GNUCXX)
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "-s") #Force stripping to avoid errors when packaging for linux.
|
||||
ENDIF()
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release" AND NOT WIN32 AND CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-s") # Force stripping to avoid errors when packaging for linux.
|
||||
endif()
|
||||
|
||||
#Activate C++11
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=gnu++11" COMPILER_SUPPORTS_CXX11)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=gnu++0x" COMPILER_SUPPORTS_CXX0X)
|
||||
if(COMPILER_SUPPORTS_CXX11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
|
||||
elseif(COMPILER_SUPPORTS_CXX0X)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
|
||||
else()
|
||||
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support (with GNU extensions). Please use a different C++ compiler.")
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 11) # Upgrading to C++17 would need to remove usage of bind2nd (should be easy).
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Mark some warnings as errors
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# Activate as much warnings as possible to avoid errors like
|
||||
# uninitialized variables or other hard to debug bugs.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reorder-ctor -Wno-reorder -Wno-pessimizing-move -Wno-unused-variable -Wno-unused-private-field")
|
||||
add_compile_options(
|
||||
-Wall
|
||||
-Wno-unknown-warning-option
|
||||
-Wno-reorder-ctor
|
||||
-Wno-reorder
|
||||
-Wno-pessimizing-move
|
||||
-Wno-unused-variable
|
||||
-Wno-unused-private-field
|
||||
|
||||
# Make as much warnings considered as errors as possible (only one for now).
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=return-stack-address")
|
||||
# Make as much warnings considered as errors as possible (only one for now).
|
||||
-Werror=return-stack-address
|
||||
-Werror=return-type)
|
||||
endif()
|
||||
|
||||
#Define common directories:
|
||||
# Define common directories:
|
||||
set(GD_base_dir ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
#Add all the CMakeLists:
|
||||
ADD_SUBDIRECTORY(ExtLibs)
|
||||
IF(BUILD_CORE)
|
||||
ADD_SUBDIRECTORY(Core)
|
||||
ENDIF()
|
||||
IF(BUILD_GDJS)
|
||||
ADD_SUBDIRECTORY(GDJS)
|
||||
ENDIF()
|
||||
IF(EMSCRIPTEN)
|
||||
ADD_SUBDIRECTORY(GDevelop.js)
|
||||
ENDIF()
|
||||
IF(BUILD_EXTENSIONS)
|
||||
ADD_SUBDIRECTORY(Extensions)
|
||||
ENDIF()
|
||||
# Add all the CMakeLists:
|
||||
add_subdirectory(ExtLibs)
|
||||
if(BUILD_CORE)
|
||||
add_subdirectory(Core)
|
||||
endif()
|
||||
if(BUILD_GDJS)
|
||||
add_subdirectory(GDJS)
|
||||
endif()
|
||||
if(EMSCRIPTEN)
|
||||
add_subdirectory(GDevelop.js)
|
||||
endif()
|
||||
if(BUILD_EXTENSIONS)
|
||||
add_subdirectory(Extensions)
|
||||
endif()
|
||||
|
@@ -1,83 +1,98 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(SET CMP0015 NEW)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(GDCore)
|
||||
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1) #Force use response file: useful for Ninja build system on Windows.
|
||||
SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1) # Force use response file: useful for Ninja build system on Windows.
|
||||
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
|
||||
#Define common directories:
|
||||
# Define common directories:
|
||||
set(GDCORE_include_dir ${GD_base_dir}/Core PARENT_SCOPE)
|
||||
set(GDCORE_lib_dir ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME} PARENT_SCOPE)
|
||||
|
||||
#Dependencies on external libraries:
|
||||
###
|
||||
# Dependencies on external libraries:
|
||||
#
|
||||
|
||||
#Defines
|
||||
###
|
||||
add_definitions( -DGD_IDE_ONLY )
|
||||
IF (EMSCRIPTEN)
|
||||
add_definitions( -DEMSCRIPTEN )
|
||||
ENDIF()
|
||||
IF(CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
add_definitions( -DDEBUG )
|
||||
ELSE()
|
||||
add_definitions( -DRELEASE )
|
||||
ENDIF()
|
||||
# Defines
|
||||
#
|
||||
add_definitions(-DGD_IDE_ONLY)
|
||||
if(EMSCRIPTEN)
|
||||
add_definitions(-DEMSCRIPTEN)
|
||||
endif()
|
||||
if("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
|
||||
add_definitions(-DDEBUG)
|
||||
else()
|
||||
add_definitions(-DRELEASE)
|
||||
endif()
|
||||
|
||||
IF(WIN32)
|
||||
add_definitions( -DWINDOWS )
|
||||
add_definitions( "-DGD_CORE_API=__declspec(dllexport)" )
|
||||
add_definitions( -D__GNUWIN32__ )
|
||||
ELSE()
|
||||
IF(APPLE)
|
||||
add_definitions( -DMACOS )
|
||||
ELSE()
|
||||
add_definitions( -DLINUX )
|
||||
ENDIF()
|
||||
add_definitions( -DGD_API= )
|
||||
add_definitions( -DGD_CORE_API= )
|
||||
ENDIF(WIN32)
|
||||
if(WIN32)
|
||||
add_definitions(-DWINDOWS)
|
||||
add_definitions("-DGD_CORE_API=__declspec(dllexport)")
|
||||
add_definitions(-D__GNUWIN32__)
|
||||
else()
|
||||
if(APPLE)
|
||||
add_definitions(-DMACOS)
|
||||
else()
|
||||
add_definitions(-DLINUX)
|
||||
endif()
|
||||
add_definitions(-DGD_API=)
|
||||
add_definitions(-DGD_CORE_API=)
|
||||
endif()
|
||||
|
||||
#The target
|
||||
###
|
||||
# The target
|
||||
#
|
||||
include_directories(.)
|
||||
file(GLOB_RECURSE source_files GDCore/*)
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
source_files
|
||||
GDCore/*)
|
||||
|
||||
file(GLOB_RECURSE formatted_source_files tests/* GDCore/Events/* GDCore/Extensions/* GDCore/IDE/* GDCore/Project/* GDCore/Serialization/* GDCore/Tools/*)
|
||||
list(REMOVE_ITEM formatted_source_files "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.h" "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs_dialogs_bitmaps.cpp")
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
formatted_source_files
|
||||
tests/*
|
||||
GDCore/Events/*
|
||||
GDCore/Extensions/*
|
||||
GDCore/IDE/*
|
||||
GDCore/Project/*
|
||||
GDCore/Serialization/*
|
||||
GDCore/Tools/*)
|
||||
list(
|
||||
REMOVE_ITEM
|
||||
formatted_source_files
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs_dialogs_bitmaps.cpp")
|
||||
gd_add_clang_utils(GDCore "${formatted_source_files}")
|
||||
|
||||
IF(EMSCRIPTEN)
|
||||
if(EMSCRIPTEN)
|
||||
# Emscripten treats all libraries as static libraries
|
||||
add_library(GDCore STATIC ${source_files})
|
||||
ELSE()
|
||||
else()
|
||||
add_library(GDCore SHARED ${source_files})
|
||||
ENDIF()
|
||||
IF(EMSCRIPTEN)
|
||||
endif()
|
||||
if(EMSCRIPTEN)
|
||||
set_target_properties(GDCore PROPERTIES SUFFIX ".bc")
|
||||
ELSEIF(WIN32)
|
||||
elseif(WIN32)
|
||||
set_target_properties(GDCore PROPERTIES PREFIX "")
|
||||
ELSE()
|
||||
else()
|
||||
set_target_properties(GDCore PROPERTIES PREFIX "lib")
|
||||
ENDIF()
|
||||
endif()
|
||||
set(LIBRARY_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
|
||||
set(ARCHIVE_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
|
||||
set(RUNTIME_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
|
||||
|
||||
#Tests
|
||||
###
|
||||
# Tests
|
||||
#
|
||||
if(BUILD_TESTS)
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
test_source_files
|
||||
tests/*
|
||||
)
|
||||
GLOB_RECURSE
|
||||
test_source_files
|
||||
tests/*)
|
||||
|
||||
add_executable(GDCore_tests ${test_source_files})
|
||||
set_target_properties(GDCore_tests PROPERTIES BUILD_WITH_INSTALL_RPATH FALSE) #Allow finding dependencies directly from build path on Mac OS X.
|
||||
set_target_properties(GDCore_tests PROPERTIES BUILD_WITH_INSTALL_RPATH FALSE) # Allow finding dependencies directly from build path on Mac OS X.
|
||||
target_link_libraries(GDCore_tests GDCore)
|
||||
target_link_libraries(GDCore_tests ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
@@ -38,7 +38,7 @@ void CommentEvent::SerializeTo(SerializerElement &element) const {
|
||||
.SetAttribute("textB", textB);
|
||||
|
||||
element.AddChild("comment").SetValue(com1);
|
||||
element.AddChild("comment2").SetValue(com2);
|
||||
if (!com2.empty()) element.AddChild("comment2").SetValue(com2);
|
||||
}
|
||||
|
||||
void CommentEvent::UnserializeFrom(gd::Project &project,
|
||||
@@ -53,7 +53,9 @@ void CommentEvent::UnserializeFrom(gd::Project &project,
|
||||
textB = colorElement.GetIntAttribute("textB");
|
||||
|
||||
com1 = element.GetChild("comment", 0, "Com1").GetValue().GetString();
|
||||
com2 = element.GetChild("comment2", 0, "Com2").GetValue().GetString();
|
||||
if (element.HasChild("comment2")) {
|
||||
com2 = element.GetChild("comment2", 0, "Com2").GetValue().GetString();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -45,10 +45,39 @@ ForEachChildVariableEvent::GetAllActionsVectors() const {
|
||||
return allActions;
|
||||
}
|
||||
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
ForEachChildVariableEvent::GetAllExpressionsWithMetadata() {
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("scenevar");
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&iterableVariableName, metadata));
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&valueIteratorVariableName, metadata));
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&keyIteratorVariableName, metadata));
|
||||
|
||||
return allExpressionsWithMetadata;
|
||||
}
|
||||
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
ForEachChildVariableEvent::GetAllExpressionsWithMetadata() const {
|
||||
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("scenevar");
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&iterableVariableName, metadata));
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&valueIteratorVariableName, metadata));
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&keyIteratorVariableName, metadata));
|
||||
|
||||
return allExpressionsWithMetadata;
|
||||
}
|
||||
|
||||
void ForEachChildVariableEvent::SerializeTo(SerializerElement& element) const {
|
||||
element.AddChild("iterableVariableName").SetValue(iterableVariableName);
|
||||
element.AddChild("valueIteratorVariableName").SetValue(valueIteratorVariableName);
|
||||
element.AddChild("keyIteratorVariableName").SetValue(keyIteratorVariableName);
|
||||
element.AddChild("iterableVariableName").SetValue(iterableVariableName.GetPlainString());
|
||||
element.AddChild("valueIteratorVariableName").SetValue(valueIteratorVariableName.GetPlainString());
|
||||
element.AddChild("keyIteratorVariableName").SetValue(keyIteratorVariableName.GetPlainString());
|
||||
gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
conditions, element.AddChild("conditions"));
|
||||
gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#define FOREACHCHILDVARIABLEEVENT_H
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/Expression.h"
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
class Project;
|
||||
@@ -44,7 +45,7 @@ class GD_CORE_API ForEachChildVariableEvent : public gd::BaseEvent {
|
||||
*
|
||||
* It is the structure variable that will be iterated on.
|
||||
*/
|
||||
const gd::String& GetIterableVariableName() const { return iterableVariableName; };
|
||||
const gd::String& GetIterableVariableName() const { return iterableVariableName.GetPlainString(); };
|
||||
|
||||
/**
|
||||
* \brief Set the iterable variable name attached to the event.
|
||||
@@ -56,15 +57,15 @@ class GD_CORE_API ForEachChildVariableEvent : public gd::BaseEvent {
|
||||
/**
|
||||
* \brief Get the value iterator variable attached to the event.
|
||||
*
|
||||
* It is the variable that will contain the value of the
|
||||
* It is the variable that will contain the value of the
|
||||
* iterable's child being iterated on.
|
||||
*/
|
||||
const gd::String& GetValueIteratorVariableName() const { return valueIteratorVariableName; };
|
||||
const gd::String& GetValueIteratorVariableName() const { return valueIteratorVariableName.GetPlainString(); };
|
||||
|
||||
/**
|
||||
* \brief Set the value iterator variable attached to the event.
|
||||
*
|
||||
* It is the variable that will contain the value of the
|
||||
* It is the variable that will contain the value of the
|
||||
* iterable's child being iterated on.
|
||||
*/
|
||||
void SetValueIteratorVariableName(gd::String newName) { valueIteratorVariableName = newName; };
|
||||
@@ -72,15 +73,15 @@ class GD_CORE_API ForEachChildVariableEvent : public gd::BaseEvent {
|
||||
/**
|
||||
* \brief Get the key iterator variable attached to the event.
|
||||
*
|
||||
* It is the variable that will contain the name of the
|
||||
* It is the variable that will contain the name of the
|
||||
* iterable's child being iterated on.
|
||||
*/
|
||||
const gd::String& GetKeyIteratorVariableName() const { return keyIteratorVariableName; };
|
||||
const gd::String& GetKeyIteratorVariableName() const { return keyIteratorVariableName.GetPlainString(); };
|
||||
|
||||
/**
|
||||
* \brief Set the key iterator variable attached to the event.
|
||||
*
|
||||
* It is the variable that will contain the name of the
|
||||
* It is the variable that will contain the name of the
|
||||
* iterable's child being iterated on.
|
||||
*/
|
||||
void SetKeyIteratorVariableName(gd::String newName) { keyIteratorVariableName = newName; };
|
||||
@@ -92,14 +93,19 @@ class GD_CORE_API ForEachChildVariableEvent : public gd::BaseEvent {
|
||||
virtual std::vector<gd::InstructionsList*> GetAllConditionsVectors();
|
||||
virtual std::vector<gd::InstructionsList*> GetAllActionsVectors();
|
||||
|
||||
virtual std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata() const;
|
||||
virtual std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata();
|
||||
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element);
|
||||
|
||||
private:
|
||||
gd::String valueIteratorVariableName;
|
||||
gd::String keyIteratorVariableName;
|
||||
gd::String iterableVariableName;
|
||||
gd::Expression valueIteratorVariableName;
|
||||
gd::Expression keyIteratorVariableName;
|
||||
gd::Expression iterableVariableName;
|
||||
gd::InstructionsList conditions;
|
||||
gd::InstructionsList actions;
|
||||
gd::EventsList events;
|
||||
|
@@ -15,7 +15,7 @@ using namespace std;
|
||||
namespace gd {
|
||||
|
||||
ForEachEvent::ForEachEvent()
|
||||
: BaseEvent(), objectsToPick(""), objectsToPickSelected(false) {}
|
||||
: BaseEvent(), objectsToPick("") {}
|
||||
|
||||
vector<gd::InstructionsList*> ForEachEvent::GetAllConditionsVectors() {
|
||||
vector<gd::InstructionsList*> allConditions;
|
||||
|
@@ -6,6 +6,8 @@
|
||||
|
||||
#ifndef FOREACHEVENT_H
|
||||
#define FOREACHEVENT_H
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
namespace gd {
|
||||
@@ -67,8 +69,6 @@ class GD_CORE_API ForEachEvent : public gd::BaseEvent {
|
||||
gd::InstructionsList conditions;
|
||||
gd::InstructionsList actions;
|
||||
gd::EventsList events;
|
||||
|
||||
bool objectsToPickSelected;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -13,6 +13,7 @@
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
class Project;
|
||||
class EventVisitor;
|
||||
}
|
||||
class EventsCodeGenerationContext;
|
||||
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Events/EventVisitor.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -130,30 +131,46 @@ void LinkEvent::SerializeTo(SerializerElement& element) const {
|
||||
|
||||
void LinkEvent::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
SerializerElement& includeElement = element.GetChild("include", 0, "Limites");
|
||||
|
||||
SetTarget(element.GetChild("target", 0, "Scene").GetValue().GetString());
|
||||
|
||||
if (includeElement.HasAttribute("includeAll")) {
|
||||
// Compatibility with GDevelop <= 4.0.92
|
||||
if (includeElement.GetBoolAttribute("includeAll", true)) {
|
||||
SetIncludeAllEvents();
|
||||
// Compatibility with GD <= 5
|
||||
if (element.HasChild("include", "Limites")) {
|
||||
SerializerElement& includeElement = element.GetChild("include", 0, "Limites");
|
||||
if (includeElement.HasAttribute("includeAll")) {
|
||||
// Compatibility with GDevelop <= 4.0.92
|
||||
if (includeElement.GetBoolAttribute("includeAll", true)) {
|
||||
SetIncludeAllEvents();
|
||||
} else {
|
||||
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
||||
includeElement.GetIntAttribute("end"));
|
||||
}
|
||||
} else {
|
||||
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
||||
includeElement.GetIntAttribute("end"));
|
||||
// GDevelop > 4.0.92
|
||||
IncludeConfig config = static_cast<IncludeConfig>(
|
||||
includeElement.GetIntAttribute("includeConfig", 0));
|
||||
if (config == INCLUDE_ALL)
|
||||
SetIncludeAllEvents();
|
||||
else if (config == INCLUDE_EVENTS_GROUP)
|
||||
SetIncludeEventsGroup(includeElement.GetStringAttribute("eventsGroup"));
|
||||
else if (config == INCLUDE_BY_INDEX)
|
||||
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
||||
includeElement.GetIntAttribute("end"));
|
||||
}
|
||||
} else {
|
||||
// GDevelop > 4.0.92
|
||||
IncludeConfig config = static_cast<IncludeConfig>(
|
||||
includeElement.GetIntAttribute("includeConfig", 0));
|
||||
if (config == INCLUDE_ALL)
|
||||
SetIncludeAllEvents();
|
||||
else if (config == INCLUDE_EVENTS_GROUP)
|
||||
SetIncludeEventsGroup(includeElement.GetStringAttribute("eventsGroup"));
|
||||
else if (config == INCLUDE_BY_INDEX)
|
||||
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
||||
includeElement.GetIntAttribute("end"));
|
||||
// Since GDevelop 5, links always include all events.
|
||||
SetIncludeAllEvents();
|
||||
}
|
||||
// end of compatibility code
|
||||
}
|
||||
|
||||
bool LinkEvent::AcceptVisitor(gd::EventVisitor &eventVisitor) {
|
||||
return BaseEvent::AcceptVisitor(eventVisitor) |
|
||||
eventVisitor.VisitLinkEvent(*this);
|
||||
}
|
||||
|
||||
void LinkEvent::AcceptVisitor(gd::ReadOnlyEventVisitor &eventVisitor) const {
|
||||
BaseEvent::AcceptVisitor(eventVisitor);
|
||||
eventVisitor.VisitLinkEvent(*this);
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -30,7 +30,7 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
|
||||
includeEnd(gd::String::npos),
|
||||
linkWasInvalid(false){};
|
||||
virtual ~LinkEvent();
|
||||
virtual gd::LinkEvent* Clone() const { return new LinkEvent(*this); }
|
||||
virtual gd::LinkEvent* Clone() const override { return new LinkEvent(*this); }
|
||||
|
||||
/**
|
||||
* Get the link target (i.e. the scene or external events the link refers to).
|
||||
@@ -86,7 +86,7 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
|
||||
/**
|
||||
* The link event must always be preprocessed.
|
||||
*/
|
||||
virtual bool MustBePreprocessed() { return true; }
|
||||
virtual bool MustBePreprocessed() override { return true; }
|
||||
|
||||
/**
|
||||
* \brief Get a pointer to the list of events that are targeted by the link.
|
||||
@@ -107,11 +107,14 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
|
||||
EventsList& eventList,
|
||||
std::size_t indexOfTheEventInThisList);
|
||||
|
||||
virtual bool IsExecutable() const { return true; };
|
||||
virtual bool IsExecutable() const override { return true; };
|
||||
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
virtual void SerializeTo(SerializerElement& element) const override;
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element);
|
||||
const SerializerElement& element) override;
|
||||
|
||||
bool AcceptVisitor(gd::EventVisitor& eventVisitor) override;
|
||||
void AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const override;
|
||||
|
||||
private:
|
||||
gd::String
|
||||
|
@@ -35,7 +35,7 @@ vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
RepeatEvent::GetAllExpressionsWithMetadata() {
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("expression");
|
||||
auto metadata = gd::ParameterMetadata().SetType("number");
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&repeatNumberExpression, metadata));
|
||||
|
||||
@@ -61,7 +61,7 @@ vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
RepeatEvent::GetAllExpressionsWithMetadata() const {
|
||||
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("expression");
|
||||
auto metadata = gd::ParameterMetadata().SetType("number");
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&repeatNumberExpression, metadata));
|
||||
|
||||
|
@@ -15,16 +15,44 @@
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/IDE/ProjectBrowserHelper.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
void ExposeProjectEffects(
|
||||
const gd::Project& project,
|
||||
const std::function<void(const gd::Effect& effect)>& worker) {
|
||||
void EffectsCodeGenerator::DoVisitObject(gd::Object &object) {
|
||||
auto &effects = object.GetEffects();
|
||||
for (std::size_t e = 0; e < effects.GetEffectsCount(); e++) {
|
||||
auto &effect = effects.GetEffect(e);
|
||||
AddEffectIncludeFiles(effect);
|
||||
}
|
||||
};
|
||||
|
||||
void EffectsCodeGenerator::AddEffectIncludeFiles(const gd::Effect &effect) {
|
||||
// TODO: this browse all the extensions every time we're trying to find
|
||||
// a new effect. Might be a good idea to rework MetadataProvider to be
|
||||
// faster (not sure if it is a bottleneck at all though - but could be
|
||||
// for events code generation).
|
||||
const gd::EffectMetadata &effectMetadata =
|
||||
MetadataProvider::GetEffectMetadata(platform, effect.GetEffectType());
|
||||
|
||||
for (auto &includeFile : effectMetadata.GetIncludeFiles())
|
||||
includeFiles.insert(includeFile);
|
||||
};
|
||||
|
||||
void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
|
||||
const gd::Platform &platform,
|
||||
gd::Project &project,
|
||||
std::set<gd::String> &includeFiles) {
|
||||
// TODO Add unit tests on this function.
|
||||
|
||||
// TODO Merge with UsedExtensionsFinder.
|
||||
|
||||
// See also gd::Project::ExposeResources for a method that traverse the whole
|
||||
// project (this time for resources) and
|
||||
// WholeProjectRefactorer::ExposeProjectEvents.
|
||||
|
||||
EffectsCodeGenerator effectsCodeGenerator(platform, includeFiles);
|
||||
|
||||
// Add layouts effects
|
||||
for (std::size_t s = 0; s < project.GetLayoutsCount(); s++) {
|
||||
auto& layout = project.GetLayout(s);
|
||||
@@ -33,47 +61,13 @@ void ExposeProjectEffects(
|
||||
auto& effects = layout.GetLayer(l).GetEffects();
|
||||
for (std::size_t e = 0; e < effects.GetEffectsCount(); ++e) {
|
||||
auto& effect = effects.GetEffect(e);
|
||||
worker(effect);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < layout.GetObjectsCount(); i++) {
|
||||
auto& object = layout.GetObject(i);
|
||||
auto& effects = object.GetEffects();
|
||||
for (std::size_t e = 0; e < effects.GetEffectsCount(); e++) {
|
||||
auto& effect = effects.GetEffect(e);
|
||||
worker(effect);
|
||||
effectsCodeGenerator.AddEffectIncludeFiles(effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add global object effects
|
||||
for (std::size_t s = 0; s < project.GetObjectsCount(); s++) {
|
||||
auto& effects = project.GetObject(s).GetEffects();
|
||||
for (std::size_t e = 0; e < effects.GetEffectsCount(); e++) {
|
||||
auto& effect = effects.GetEffect(e);
|
||||
worker(effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
|
||||
const gd::Platform& platform,
|
||||
const gd::Project& project,
|
||||
std::set<gd::String>& includeFiles) {
|
||||
ExposeProjectEffects(
|
||||
project, [&platform, &includeFiles](const gd::Effect& effect) {
|
||||
// TODO: this browse all the extensions every time we're trying to find
|
||||
// a new effect. Might be a good idea to rework MetadataProvider to be
|
||||
// faster (not sure if it is a bottleneck at all though - but could be
|
||||
// for events code generation).
|
||||
const gd::EffectMetadata& effectMetadata =
|
||||
MetadataProvider::GetEffectMetadata(platform,
|
||||
effect.GetEffectType());
|
||||
|
||||
for (auto& includeFile : effectMetadata.GetIncludeFiles())
|
||||
includeFiles.insert(includeFile);
|
||||
});
|
||||
// Add objects effects
|
||||
gd::ProjectBrowserHelper::ExposeProjectObjects(project, effectsCodeGenerator);
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -3,16 +3,18 @@
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_EffectsCodeGenerator_H
|
||||
#define GDCORE_EffectsCodeGenerator_H
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
|
||||
namespace gd {
|
||||
class Project;
|
||||
class Platform;
|
||||
class Effect;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -20,16 +22,26 @@ namespace gd {
|
||||
/**
|
||||
* \brief Internal class used to generate code from events
|
||||
*/
|
||||
class GD_CORE_API EffectsCodeGenerator {
|
||||
public:
|
||||
class GD_CORE_API EffectsCodeGenerator : public ArbitraryObjectsWorker {
|
||||
public:
|
||||
/**
|
||||
* \brief Add all the include files required by the project effects.
|
||||
*/
|
||||
static void GenerateEffectsIncludeFiles(const gd::Platform& platform,
|
||||
const gd::Project& project,
|
||||
gd::Project& project,
|
||||
std::set<gd::String>& includeFiles);
|
||||
|
||||
private:
|
||||
EffectsCodeGenerator(const gd::Platform &platform_,
|
||||
std::set<gd::String> &includeFiles_)
|
||||
: platform(platform_), includeFiles(includeFiles_){};
|
||||
|
||||
void AddEffectIncludeFiles(const gd::Effect& effect);
|
||||
|
||||
void DoVisitObject(gd::Object &object) override;
|
||||
|
||||
const gd::Platform &platform;
|
||||
std::set<gd::String> &includeFiles;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EffectsCodeGenerator_H
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/ObjectsContainersList.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -68,8 +69,36 @@ gd::String EventsCodeGenerator::GenerateRelationalOperatorCall(
|
||||
}
|
||||
}
|
||||
|
||||
return callStartString + "(" + argumentsStr + ") " + relationalOperator +
|
||||
" " + rhs;
|
||||
auto lhs = callStartString + "(" + argumentsStr + ")";
|
||||
return GenerateRelationalOperation(relationalOperator, lhs, rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate a relational operation
|
||||
*
|
||||
* @param relationalOperator the operator
|
||||
* @param lhs the left hand operand
|
||||
* @param rhs the right hand operand
|
||||
* @return gd::String
|
||||
*/
|
||||
gd::String EventsCodeGenerator::GenerateRelationalOperation(
|
||||
const gd::String& relationalOperator,
|
||||
const gd::String& lhs,
|
||||
const gd::String& rhs) {
|
||||
return lhs + " " + GenerateRelationalOperatorCodes(relationalOperator) + " " + rhs;
|
||||
}
|
||||
|
||||
const gd::String EventsCodeGenerator::GenerateRelationalOperatorCodes(const gd::String &operatorString) {
|
||||
if (operatorString == "=") {
|
||||
return "==";
|
||||
}
|
||||
if (operatorString != "<" && operatorString != ">" &&
|
||||
operatorString != "<=" && operatorString != ">=" && operatorString != "!=" &&
|
||||
operatorString != "startsWith" && operatorString != "endsWith" && operatorString != "contains") {
|
||||
cout << "Warning: Bad relational operator: Set to == by default." << endl;
|
||||
return "==";
|
||||
}
|
||||
return operatorString;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,14 +296,12 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
return "/* Unknown instruction - skipped. */";
|
||||
}
|
||||
|
||||
AddIncludeFiles(instrInfos.codeExtraInformation.GetIncludeFiles());
|
||||
AddIncludeFiles(instrInfos.GetIncludeFiles());
|
||||
maxConditionsListsSize =
|
||||
std::max(maxConditionsListsSize, condition.GetSubInstructions().size());
|
||||
|
||||
if (instrInfos.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
if (instrInfos.HasCustomCodeGenerator()) {
|
||||
context.EnterCustomCondition();
|
||||
conditionCode += GenerateReferenceToUpperScopeBoolean(
|
||||
"conditionTrue", returnBoolean, context);
|
||||
conditionCode += instrInfos.codeExtraInformation.customCodeGenerator(
|
||||
condition, *this, context);
|
||||
maxCustomConditionsDepth =
|
||||
@@ -291,22 +318,16 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
condition.SetParameters(parameters);
|
||||
}
|
||||
|
||||
// Verify that there are no mismatchs between object type in parameters.
|
||||
// Verify that there are no mismatches between object type in parameters.
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
|
||||
gd::String objectInParameter =
|
||||
condition.GetParameter(pNb).GetPlainString();
|
||||
|
||||
if (!GetObjectsAndGroups().HasObjectNamed(objectInParameter) &&
|
||||
!GetGlobalObjectsAndGroups().HasObjectNamed(objectInParameter) &&
|
||||
!GetObjectsAndGroups().GetObjectGroups().Has(objectInParameter) &&
|
||||
!GetGlobalObjectsAndGroups().GetObjectGroups().Has(
|
||||
objectInParameter)) {
|
||||
if (!GetObjectsContainersList().HasObjectOrGroupNamed(objectInParameter)) {
|
||||
return "/* Unknown object - skipped. */";
|
||||
} else if (!instrInfos.parameters[pNb].GetExtraInfo().empty() &&
|
||||
gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
|
||||
GetObjectsAndGroups(),
|
||||
objectInParameter) !=
|
||||
GetObjectsContainersList().GetTypeOfObject(objectInParameter) !=
|
||||
instrInfos.parameters[pNb].GetExtraInfo()) {
|
||||
return "/* Mismatched object type - skipped. */";
|
||||
}
|
||||
@@ -317,19 +338,13 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
gd::String objectName = condition.GetParameter(0).GetPlainString();
|
||||
if (!objectName.empty() && !instrInfos.parameters.empty()) {
|
||||
std::vector<gd::String> realObjects =
|
||||
ExpandObjectsName(objectName, context);
|
||||
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
// Set up the context
|
||||
gd::String objectType = gd::GetTypeOfObject(
|
||||
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), realObjects[i]);
|
||||
gd::String objectType = GetObjectsContainersList().GetTypeOfObject(realObjects[i]);
|
||||
const ObjectMetadata& objInfo =
|
||||
MetadataProvider::GetObjectMetadata(platform, objectType);
|
||||
|
||||
if (objInfo.IsUnsupportedBaseObjectCapability(
|
||||
instrInfos.GetRequiredBaseObjectCapability())) {
|
||||
conditionCode +=
|
||||
"/* Object with unsupported capability - skipped. */\n";
|
||||
} else {
|
||||
AddIncludeFiles(objInfo.includeFiles);
|
||||
context.SetCurrentObject(realObjects[i]);
|
||||
context.ObjectsListNeeded(realObjects[i]);
|
||||
@@ -346,18 +361,14 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
context);
|
||||
|
||||
context.SetNoCurrentObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (instrInfos.IsBehaviorInstruction()) {
|
||||
gd::String objectName = condition.GetParameter(0).GetPlainString();
|
||||
gd::String behaviorType =
|
||||
gd::GetTypeOfBehavior(GetGlobalObjectsAndGroups(),
|
||||
GetObjectsAndGroups(),
|
||||
condition.GetParameter(1).GetPlainString());
|
||||
gd::String behaviorType = GetObjectsContainersList().GetTypeOfBehavior(condition.GetParameter(1).GetPlainString());
|
||||
if (instrInfos.parameters.size() >= 2) {
|
||||
std::vector<gd::String> realObjects =
|
||||
ExpandObjectsName(objectName, context);
|
||||
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
// Setup context
|
||||
const BehaviorMetadata& autoInfo =
|
||||
@@ -461,9 +472,9 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
return "/* Unknown instruction - skipped. */";
|
||||
}
|
||||
|
||||
AddIncludeFiles(instrInfos.codeExtraInformation.GetIncludeFiles());
|
||||
AddIncludeFiles(instrInfos.GetIncludeFiles());
|
||||
|
||||
if (instrInfos.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
if (instrInfos.HasCustomCodeGenerator()) {
|
||||
return instrInfos.codeExtraInformation.customCodeGenerator(
|
||||
action, *this, context);
|
||||
}
|
||||
@@ -483,20 +494,14 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
action.SetParameters(parameters);
|
||||
}
|
||||
|
||||
// Verify that there are no mismatchs between object type in parameters.
|
||||
// Verify that there are no mismatches between object type in parameters.
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
|
||||
gd::String objectInParameter = action.GetParameter(pNb).GetPlainString();
|
||||
if (!GetObjectsAndGroups().HasObjectNamed(objectInParameter) &&
|
||||
!GetGlobalObjectsAndGroups().HasObjectNamed(objectInParameter) &&
|
||||
!GetObjectsAndGroups().GetObjectGroups().Has(objectInParameter) &&
|
||||
!GetGlobalObjectsAndGroups().GetObjectGroups().Has(
|
||||
objectInParameter)) {
|
||||
if (!GetObjectsContainersList().HasObjectOrGroupNamed(objectInParameter)) {
|
||||
return "/* Unknown object - skipped. */";
|
||||
} else if (!instrInfos.parameters[pNb].GetExtraInfo().empty() &&
|
||||
gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
|
||||
GetObjectsAndGroups(),
|
||||
objectInParameter) !=
|
||||
GetObjectsContainersList().GetTypeOfObject(objectInParameter) !=
|
||||
instrInfos.parameters[pNb].GetExtraInfo()) {
|
||||
return "/* Mismatched object type - skipped. */";
|
||||
}
|
||||
@@ -509,18 +514,13 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
|
||||
if (!instrInfos.parameters.empty()) {
|
||||
std::vector<gd::String> realObjects =
|
||||
ExpandObjectsName(objectName, context);
|
||||
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
// Setup context
|
||||
gd::String objectType = gd::GetTypeOfObject(
|
||||
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), realObjects[i]);
|
||||
gd::String objectType = GetObjectsContainersList().GetTypeOfObject(realObjects[i]);
|
||||
const ObjectMetadata& objInfo =
|
||||
MetadataProvider::GetObjectMetadata(platform, objectType);
|
||||
|
||||
if (objInfo.IsUnsupportedBaseObjectCapability(
|
||||
instrInfos.GetRequiredBaseObjectCapability())) {
|
||||
actionCode += "/* Object with unsupported capability - skipped. */\n";
|
||||
} else {
|
||||
AddIncludeFiles(objInfo.includeFiles);
|
||||
context.SetCurrentObject(realObjects[i]);
|
||||
context.ObjectsListNeeded(realObjects[i]);
|
||||
@@ -537,19 +537,15 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
optionalAsyncCallbackName);
|
||||
|
||||
context.SetNoCurrentObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (instrInfos.IsBehaviorInstruction()) {
|
||||
gd::String objectName = action.GetParameter(0).GetPlainString();
|
||||
gd::String behaviorType =
|
||||
gd::GetTypeOfBehavior(GetGlobalObjectsAndGroups(),
|
||||
GetObjectsAndGroups(),
|
||||
action.GetParameter(1).GetPlainString());
|
||||
gd::String behaviorType = GetObjectsContainersList().GetTypeOfBehavior(action.GetParameter(1).GetPlainString());
|
||||
|
||||
if (instrInfos.parameters.size() >= 2) {
|
||||
std::vector<gd::String> realObjects =
|
||||
ExpandObjectsName(objectName, context);
|
||||
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
// Setup context
|
||||
const BehaviorMetadata& autoInfo =
|
||||
@@ -670,18 +666,6 @@ gd::String EventsCodeGenerator::GenerateActionsListCode(
|
||||
return outputCode;
|
||||
}
|
||||
|
||||
const gd::String EventsCodeGenerator::GenerateRelationalOperatorCodes(const gd::String &operatorString) {
|
||||
if (operatorString == "=") {
|
||||
return "==";
|
||||
}
|
||||
if (operatorString != "<" && operatorString != ">" &&
|
||||
operatorString != "<=" && operatorString != ">=" && operatorString != "!=") {
|
||||
cout << "Warning: Bad relational operator: Set to == by default." << endl;
|
||||
return "==";
|
||||
}
|
||||
return operatorString;
|
||||
}
|
||||
|
||||
gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
const gd::Expression& parameter,
|
||||
const gd::ParameterMetadata& metadata,
|
||||
@@ -706,7 +690,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
argOutput =
|
||||
GenerateObject(parameter.GetPlainString(), metadata.GetType(), context);
|
||||
} else if (metadata.GetType() == "relationalOperator") {
|
||||
argOutput += GenerateRelationalOperatorCodes(parameter.GetPlainString());
|
||||
argOutput += parameter.GetPlainString();
|
||||
argOutput = "\"" + argOutput + "\"";
|
||||
} else if (metadata.GetType() == "operator") {
|
||||
argOutput += parameter.GetPlainString();
|
||||
@@ -729,6 +713,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
metadata.GetType() == "tilemapResource" ||
|
||||
metadata.GetType() == "tilesetResource" ||
|
||||
metadata.GetType() == "videoResource" ||
|
||||
metadata.GetType() == "model3DResource" ||
|
||||
// Deprecated, old parameter names:
|
||||
metadata.GetType() == "password" || metadata.GetType() == "musicfile" ||
|
||||
metadata.GetType() == "soundfile" || metadata.GetType() == "police") {
|
||||
@@ -924,41 +909,6 @@ gd::String EventsCodeGenerator::ConvertToStringExplicit(
|
||||
return "\"" + ConvertToString(plainString) + "\"";
|
||||
}
|
||||
|
||||
std::vector<gd::String> EventsCodeGenerator::ExpandObjectsName(
|
||||
const gd::String& objectName,
|
||||
const EventsCodeGenerationContext& context) const {
|
||||
// Note: this logic is duplicated in EventsContextAnalyzer::ExpandObjectsName
|
||||
std::vector<gd::String> realObjects;
|
||||
if (globalObjectsAndGroups.GetObjectGroups().Has(objectName))
|
||||
realObjects = globalObjectsAndGroups.GetObjectGroups()
|
||||
.Get(objectName)
|
||||
.GetAllObjectsNames();
|
||||
else if (objectsAndGroups.GetObjectGroups().Has(objectName))
|
||||
realObjects =
|
||||
objectsAndGroups.GetObjectGroups().Get(objectName).GetAllObjectsNames();
|
||||
else
|
||||
realObjects.push_back(objectName);
|
||||
|
||||
// If current object is present, use it and only it.
|
||||
if (find(realObjects.begin(),
|
||||
realObjects.end(),
|
||||
context.GetCurrentObject()) != realObjects.end()) {
|
||||
realObjects.clear();
|
||||
realObjects.push_back(context.GetCurrentObject());
|
||||
}
|
||||
|
||||
// Ensure that all returned objects actually exists.
|
||||
for (std::size_t i = 0; i < realObjects.size();) {
|
||||
if (!objectsAndGroups.HasObjectNamed(realObjects[i]) &&
|
||||
!globalObjectsAndGroups.HasObjectNamed(realObjects[i]))
|
||||
realObjects.erase(realObjects.begin() + i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
return realObjects;
|
||||
}
|
||||
|
||||
void EventsCodeGenerator::DeleteUselessEvents(gd::EventsList& events) {
|
||||
for (std::size_t eId = events.size() - 1; eId < events.size(); --eId) {
|
||||
if (events[eId].CanHaveSubEvents()) // Process sub events, if any
|
||||
@@ -975,6 +925,8 @@ void EventsCodeGenerator::DeleteUselessEvents(gd::EventsList& events) {
|
||||
*/
|
||||
void EventsCodeGenerator::PreprocessEventList(gd::EventsList& listEvent) {
|
||||
for (std::size_t i = 0; i < listEvent.GetEventsCount(); ++i) {
|
||||
if (listEvent[i].IsDisabled()) continue;
|
||||
|
||||
listEvent[i].Preprocess(*this, listEvent, i);
|
||||
if (i <
|
||||
listEvent.GetEventsCount()) { // Be sure that that there is still an
|
||||
@@ -1020,15 +972,15 @@ gd::String EventsCodeGenerator::GenerateFreeCondition(
|
||||
bool conditionInverted,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
// Generate call
|
||||
gd::String predicat;
|
||||
gd::String predicate;
|
||||
if (instrInfos.codeExtraInformation.type == "number" ||
|
||||
instrInfos.codeExtraInformation.type == "string") {
|
||||
predicat = GenerateRelationalOperatorCall(
|
||||
predicate = GenerateRelationalOperatorCall(
|
||||
instrInfos,
|
||||
arguments,
|
||||
instrInfos.codeExtraInformation.functionCallName);
|
||||
} else {
|
||||
predicat = instrInfos.codeExtraInformation.functionCallName + "(" +
|
||||
predicate = instrInfos.codeExtraInformation.functionCallName + "(" +
|
||||
GenerateArgumentsList(arguments, 0) + ")";
|
||||
}
|
||||
|
||||
@@ -1041,10 +993,10 @@ gd::String EventsCodeGenerator::GenerateFreeCondition(
|
||||
conditionAlreadyTakeCareOfInversion = true;
|
||||
}
|
||||
if (!conditionAlreadyTakeCareOfInversion && conditionInverted)
|
||||
predicat = GenerateNegatedPredicat(predicat);
|
||||
predicate = GenerateNegatedPredicate(predicate);
|
||||
|
||||
// Generate condition code
|
||||
return returnBoolean + " = " + predicat + ";\n";
|
||||
return returnBoolean + " = " + predicate + ";\n";
|
||||
}
|
||||
|
||||
gd::String EventsCodeGenerator::GenerateObjectCondition(
|
||||
@@ -1066,18 +1018,18 @@ gd::String EventsCodeGenerator::GenerateObjectCondition(
|
||||
instrInfos.codeExtraInformation.functionCallName;
|
||||
|
||||
// Create call
|
||||
gd::String predicat;
|
||||
gd::String predicate;
|
||||
if ((instrInfos.codeExtraInformation.type == "number" ||
|
||||
instrInfos.codeExtraInformation.type == "string")) {
|
||||
predicat = GenerateRelationalOperatorCall(
|
||||
predicate = GenerateRelationalOperatorCall(
|
||||
instrInfos, arguments, objectFunctionCallNamePart, 1);
|
||||
} else {
|
||||
predicat = objectFunctionCallNamePart + "(" +
|
||||
predicate = objectFunctionCallNamePart + "(" +
|
||||
GenerateArgumentsList(arguments, 1) + ")";
|
||||
}
|
||||
if (conditionInverted) predicat = GenerateNegatedPredicat(predicat);
|
||||
if (conditionInverted) predicate = GenerateNegatedPredicate(predicate);
|
||||
|
||||
return "For each picked object \"" + objectName + "\", check " + predicat +
|
||||
return "For each picked object \"" + objectName + "\", check " + predicate +
|
||||
".\n";
|
||||
}
|
||||
|
||||
@@ -1091,16 +1043,16 @@ gd::String EventsCodeGenerator::GenerateBehaviorCondition(
|
||||
bool conditionInverted,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
// Create call
|
||||
gd::String predicat;
|
||||
gd::String predicate;
|
||||
if ((instrInfos.codeExtraInformation.type == "number" ||
|
||||
instrInfos.codeExtraInformation.type == "string")) {
|
||||
predicat = GenerateRelationalOperatorCall(instrInfos, arguments, "", 2);
|
||||
predicate = GenerateRelationalOperatorCall(instrInfos, arguments, "", 2);
|
||||
} else {
|
||||
predicat = "(" + GenerateArgumentsList(arguments, 2) + ")";
|
||||
predicate = "(" + GenerateArgumentsList(arguments, 2) + ")";
|
||||
}
|
||||
if (conditionInverted) predicat = GenerateNegatedPredicat(predicat);
|
||||
if (conditionInverted) predicate = GenerateNegatedPredicate(predicate);
|
||||
|
||||
return "For each picked object \"" + objectName + "\", check " + predicat +
|
||||
return "For each picked object \"" + objectName + "\", check " + predicate +
|
||||
" for behavior \"" + behaviorName + "\".\n";
|
||||
}
|
||||
|
||||
@@ -1240,7 +1192,7 @@ size_t EventsCodeGenerator::GenerateSingleUsageUniqueIdFor(
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
// Base the unique id on the adress in memory so that the same instruction
|
||||
// Base the unique id on the address in memory so that the same instruction
|
||||
// in memory will get the same id across different code generations.
|
||||
size_t uniqueId = (size_t)instruction;
|
||||
|
||||
@@ -1272,12 +1224,24 @@ gd::String EventsCodeGenerator::GenerateArgumentsList(
|
||||
return argumentsStr;
|
||||
}
|
||||
|
||||
gd::String EventsCodeGenerator::GeneratePropertyGetter(const gd::PropertiesContainer& propertiesContainer,
|
||||
const gd::NamedPropertyDescriptor& property,
|
||||
const gd::String& type,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
return "getProperty" + property.GetName() + "As" + type + "()";
|
||||
}
|
||||
|
||||
gd::String EventsCodeGenerator::GenerateParameterGetter(const gd::ParameterMetadata& parameter,
|
||||
const gd::String& type,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
return "getParameter" + parameter.GetName() + "As" + type + "()";
|
||||
}
|
||||
|
||||
EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
|
||||
const gd::Layout& layout,
|
||||
const gd::Platform& platform_)
|
||||
: platform(platform_),
|
||||
globalObjectsAndGroups(project_),
|
||||
objectsAndGroups(layout),
|
||||
projectScopedContainers(gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project_, layout)),
|
||||
hasProjectAndLayout(true),
|
||||
project(&project_),
|
||||
scene(&layout),
|
||||
@@ -1289,11 +1253,9 @@ EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
|
||||
|
||||
EventsCodeGenerator::EventsCodeGenerator(
|
||||
const gd::Platform& platform_,
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups_,
|
||||
const gd::ObjectsContainer& objectsAndGroups_)
|
||||
const gd::ProjectScopedContainers& projectScopedContainers_)
|
||||
: platform(platform_),
|
||||
globalObjectsAndGroups(globalObjectsAndGroups_),
|
||||
objectsAndGroups(objectsAndGroups_),
|
||||
projectScopedContainers(projectScopedContainers_),
|
||||
hasProjectAndLayout(false),
|
||||
project(nullptr),
|
||||
scene(nullptr),
|
||||
|
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Project/ProjectScopedContainers.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class EventsList;
|
||||
@@ -19,6 +20,7 @@ class Expression;
|
||||
class Project;
|
||||
class Layout;
|
||||
class ObjectsContainer;
|
||||
class ObjectsContainersList;
|
||||
class ExternalEvents;
|
||||
class ParameterMetadata;
|
||||
class ObjectMetadata;
|
||||
@@ -56,9 +58,9 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* \brief Construct a code generator for the specified
|
||||
* objects/groups and platform
|
||||
*/
|
||||
EventsCodeGenerator(const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups_,
|
||||
const gd::ObjectsContainer& objectsAndGroups_);
|
||||
EventsCodeGenerator(
|
||||
const gd::Platform& platform,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers_);
|
||||
virtual ~EventsCodeGenerator(){};
|
||||
|
||||
/**
|
||||
@@ -326,18 +328,12 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
*/
|
||||
bool ErrorOccurred() const { return errorOccurred; };
|
||||
|
||||
/**
|
||||
* \brief Get the global objects/groups used for code generation.
|
||||
*/
|
||||
const gd::ObjectsContainer& GetGlobalObjectsAndGroups() const {
|
||||
return globalObjectsAndGroups;
|
||||
}
|
||||
const gd::ObjectsContainersList& GetObjectsContainersList() const {
|
||||
return projectScopedContainers.GetObjectsContainersList();
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get the objects/groups used for code generation.
|
||||
*/
|
||||
const gd::ObjectsContainer& GetObjectsAndGroups() const {
|
||||
return objectsAndGroups;
|
||||
const gd::ProjectScopedContainers& GetProjectScopedContainers() const {
|
||||
return projectScopedContainers;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -363,22 +359,6 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
*/
|
||||
const gd::Platform& GetPlatform() const { return platform; }
|
||||
|
||||
/**
|
||||
* \brief Convert a group name to the full list of objects contained in the
|
||||
* group.
|
||||
*
|
||||
* Get a list containing the "real" objects name when the events refers to \a
|
||||
* objectName :<br> If \a objectName is really an object, the list will only
|
||||
* contains \a objectName unchanged.<br> If \a objectName is a group, the list
|
||||
* will contains all the objects of the group.<br> If \a objectName is the
|
||||
* "current" object in the context ( i.e: The object being used for launching
|
||||
* an action... ), none of the two rules below apply, and the list will only
|
||||
* contains the context "current" object name.
|
||||
*/
|
||||
std::vector<gd::String> ExpandObjectsName(
|
||||
const gd::String& objectName,
|
||||
const EventsCodeGenerationContext& context) const;
|
||||
|
||||
/**
|
||||
* \brief Get the maximum depth of custom conditions reached during code
|
||||
* generation.
|
||||
@@ -404,6 +384,18 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
return boolName;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate the full name for accessing to a boolean variable used for
|
||||
* conditions.
|
||||
*
|
||||
* Default implementation just returns the boolean name passed as argument.
|
||||
*/
|
||||
virtual gd::String GenerateUpperScopeBooleanFullName(
|
||||
const gd::String& boolName,
|
||||
const gd::EventsCodeGenerationContext& context) {
|
||||
return boolName;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Must create a boolean. Its value must be false.
|
||||
*
|
||||
@@ -481,10 +473,15 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
*/
|
||||
size_t GenerateSingleUsageUniqueIdForEventsList();
|
||||
|
||||
virtual gd::String GenerateRelationalOperation(
|
||||
const gd::String& relationalOperator,
|
||||
const gd::String& lhs,
|
||||
const gd::String& rhs);
|
||||
|
||||
protected:
|
||||
virtual const gd::String GenerateRelationalOperatorCodes(
|
||||
const gd::String& operatorString);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* \brief Generate the code for a single parameter.
|
||||
*
|
||||
@@ -493,9 +490,9 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* - object : Object name -> string
|
||||
* - expression : Mathematical expression -> number (double)
|
||||
* - string : %Text expression -> string
|
||||
* - layer, color, file, joyaxis : Same as string
|
||||
* - layer, color, file, stringWithSelector : Same as string
|
||||
* - relationalOperator : Used to make a comparison between the function
|
||||
resturn value and value of the parameter preceding the relationOperator
|
||||
return value and value of the parameter preceding the relationOperator
|
||||
parameter -> string
|
||||
* - operator : Used to update a value using a setter and a getter -> string
|
||||
* - key, mouse, objectvar, scenevar, globalvar, password, musicfile,
|
||||
@@ -554,6 +551,12 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
return ".getChild(" + ConvertToStringExplicit(childName) + ")";
|
||||
};
|
||||
|
||||
virtual gd::String GenerateVariableValueAs(const gd::String& type) {
|
||||
return type == "number|string" ? ".getAsNumberOrString()"
|
||||
: type == "string" ? ".getAsString()"
|
||||
: ".getAsNumber()";
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate the code to get the child of a variable,
|
||||
* using generated the expression.
|
||||
@@ -582,6 +585,17 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
return "fakeObjectListOf_" + objectName;
|
||||
}
|
||||
|
||||
virtual gd::String GeneratePropertyGetter(
|
||||
const gd::PropertiesContainer& propertiesContainer,
|
||||
const gd::NamedPropertyDescriptor& property,
|
||||
const gd::String& type,
|
||||
gd::EventsCodeGenerationContext& context);
|
||||
|
||||
virtual gd::String GenerateParameterGetter(
|
||||
const gd::ParameterMetadata& parameter,
|
||||
const gd::String& type,
|
||||
gd::EventsCodeGenerationContext& context);
|
||||
|
||||
/**
|
||||
* \brief Generate the code to reference an object which is
|
||||
* in an empty/null state.
|
||||
@@ -656,28 +670,16 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Must negate a predicat.
|
||||
* \brief Must negate a predicate.
|
||||
*
|
||||
* The default implementation generates C-style code : It wraps the predicat
|
||||
* The default implementation generates C-style code : It wraps the predicate
|
||||
* inside parenthesis and add a !.
|
||||
*/
|
||||
virtual gd::String GenerateNegatedPredicat(const gd::String& predicat) const {
|
||||
return "!(" + predicat + ")";
|
||||
virtual gd::String GenerateNegatedPredicate(
|
||||
const gd::String& predicate) const {
|
||||
return "!(" + predicate + ")";
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Must create a boolean which is a reference to a boolean declared in
|
||||
* the parent scope.
|
||||
*
|
||||
* The default implementation generates C-style code.
|
||||
*/
|
||||
virtual gd::String GenerateReferenceToUpperScopeBoolean(
|
||||
const gd::String& referenceName,
|
||||
const gd::String& referencedBoolean,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
return "bool & " + referenceName + " = " + referencedBoolean + ";\n";
|
||||
}
|
||||
|
||||
virtual gd::String GenerateFreeCondition(
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
@@ -735,6 +737,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::String& callStartString,
|
||||
std::size_t startFromArgument = 0);
|
||||
|
||||
gd::String GenerateOperatorCall(const gd::InstructionMetadata& instrInfos,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::String& callStartString,
|
||||
@@ -778,15 +781,14 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
|
||||
const gd::Platform& platform; ///< The platform being used.
|
||||
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups;
|
||||
const gd::ObjectsContainer& objectsAndGroups;
|
||||
gd::ProjectScopedContainers projectScopedContainers;
|
||||
|
||||
bool hasProjectAndLayout; ///< true only if project and layout are valid
|
||||
///< references. If false, they should not be used.
|
||||
const gd::Project* project; ///< The project being used.
|
||||
const gd::Layout* scene; ///< The scene being generated.
|
||||
|
||||
bool errorOccurred; ///< Must be set to true if an error occured.
|
||||
bool errorOccurred; ///< Must be set to true if an error occurred.
|
||||
bool compilationForRuntime; ///< Is set to true if the code generation is
|
||||
///< made for runtime only.
|
||||
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
@@ -25,6 +26,9 @@
|
||||
#include "GDCore/IDE/Events/ExpressionValidator.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/VariablesContainersList.h"
|
||||
#include "GDCore/Project/ObjectsContainersList.h"
|
||||
#include "GDCore/Project/ProjectScopedContainers.h"
|
||||
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
|
||||
#include "GDCore/IDE/Events/ExpressionVariableOwnerFinder.h"
|
||||
|
||||
@@ -47,12 +51,11 @@ gd::String ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
}
|
||||
|
||||
gd::ExpressionValidator validator(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType);
|
||||
node->Visit(validator);
|
||||
if (!validator.GetErrors().empty()) {
|
||||
std::cout << "Error: \"" << validator.GetErrors()[0]->GetMessage()
|
||||
if (!validator.GetFatalErrors().empty()) {
|
||||
std::cout << "Error: \"" << validator.GetFatalErrors()[0]->GetMessage()
|
||||
<< "\" in: \"" << expression.GetPlainString() << "\" ("
|
||||
<< rootType << ")" << std::endl;
|
||||
|
||||
@@ -100,35 +103,95 @@ void ExpressionCodeGenerator::OnVisitVariableNode(VariableNode& node) {
|
||||
// This "translation" from the type to an enum could be avoided
|
||||
// if all types were moved to an enum.
|
||||
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType,
|
||||
node);
|
||||
EventsCodeGenerator::VariableScope scope =
|
||||
type == "globalvar"
|
||||
? gd::EventsCodeGenerator::PROJECT_VARIABLE
|
||||
: ((type == "scenevar")
|
||||
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
|
||||
: gd::EventsCodeGenerator::OBJECT_VARIABLE);
|
||||
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
rootObjectName,
|
||||
node);
|
||||
output += codeGenerator.GenerateGetVariable(
|
||||
node.name, scope, context, objectName);
|
||||
if (node.child) node.child->Visit(*this);
|
||||
|
||||
if (gd::ParameterMetadata::IsExpression("variable", type)) {
|
||||
// The node is a variable inside an expression waiting for a *variable* to be returned, not its value.
|
||||
EventsCodeGenerator::VariableScope scope =
|
||||
type == "globalvar"
|
||||
? gd::EventsCodeGenerator::PROJECT_VARIABLE
|
||||
: ((type == "scenevar")
|
||||
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
|
||||
: gd::EventsCodeGenerator::OBJECT_VARIABLE);
|
||||
|
||||
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetObjectsContainersList(),
|
||||
rootObjectName,
|
||||
node);
|
||||
output += codeGenerator.GenerateGetVariable(
|
||||
node.name, scope, context, objectName);
|
||||
if (node.child) node.child->Visit(*this);
|
||||
} else {
|
||||
// The node represents a variable or an object variable in an expression waiting for its *value* to be returned.
|
||||
|
||||
codeGenerator.GetProjectScopedContainers().MatchIdentifierWithName<void>(node.name, [&](){
|
||||
// Generate the code to access the object variables.
|
||||
|
||||
// Defer generation of the access to the object and variable to the child,
|
||||
// once we know the name of the variable.
|
||||
objectNameToUseForVariableAccessor = node.name;
|
||||
if (node.child) node.child->Visit(*this);
|
||||
objectNameToUseForVariableAccessor = "";
|
||||
|
||||
output += codeGenerator.GenerateVariableValueAs(type);
|
||||
}, [&]() {
|
||||
if (!codeGenerator.HasProjectAndLayout()) {
|
||||
gd::LogWarning("Tried to generate access to a variable without a project/scene - the code generator only works for global and scene variables for now.");
|
||||
output += GenerateDefaultValue(type);
|
||||
return;
|
||||
}
|
||||
|
||||
// This could be adapted in the future if more scopes are supported.
|
||||
EventsCodeGenerator::VariableScope scope = gd::EventsCodeGenerator::PROJECT_VARIABLE;
|
||||
if (codeGenerator.GetProjectScopedContainers().GetVariablesContainersList().GetBottomMostVariablesContainer()->Has(node.name)) {
|
||||
scope = gd::EventsCodeGenerator::LAYOUT_VARIABLE;
|
||||
}
|
||||
|
||||
output += codeGenerator.GenerateGetVariable(node.name, scope, context, "");
|
||||
if (node.child) node.child->Visit(*this);
|
||||
output += codeGenerator.GenerateVariableValueAs(type);
|
||||
}, [&]() {
|
||||
// Properties are not supported.
|
||||
output += GenerateDefaultValue(type);
|
||||
}, [&]() {
|
||||
// Parameters are not supported.
|
||||
output += GenerateDefaultValue(type);
|
||||
}, [&]() {
|
||||
// The identifier does not represents a variable (or a child variable), or not at least an existing
|
||||
// one, nor an object variable. It's invalid.
|
||||
output += GenerateDefaultValue(type);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionCodeGenerator::OnVisitVariableAccessorNode(
|
||||
VariableAccessorNode& node) {
|
||||
output += codeGenerator.GenerateVariableAccessor(node.name);
|
||||
if (!objectNameToUseForVariableAccessor.empty()) {
|
||||
// Use the name of the object passed by the parent, as we need both to access an object variable.
|
||||
output += codeGenerator.GenerateGetVariable(node.name,
|
||||
gd::EventsCodeGenerator::OBJECT_VARIABLE, context, objectNameToUseForVariableAccessor);
|
||||
|
||||
// We have accessed an object variable, from now we can continue accessing the child variables
|
||||
// (including using the bracket notation).
|
||||
objectNameToUseForVariableAccessor = "";
|
||||
} else {
|
||||
output += codeGenerator.GenerateVariableAccessor(node.name);
|
||||
}
|
||||
if (node.child) node.child->Visit(*this);
|
||||
}
|
||||
|
||||
void ExpressionCodeGenerator::OnVisitVariableBracketAccessorNode(
|
||||
VariableBracketAccessorNode& node) {
|
||||
ExpressionCodeGenerator generator("string", "", codeGenerator, context);
|
||||
if (!objectNameToUseForVariableAccessor.empty()) {
|
||||
// Bracket notation can't be used to directly access a variable of an object (`MyObject["MyVariable"]`).
|
||||
// This would be rejected by the ExpressionValidator.
|
||||
output += codeGenerator.GenerateBadVariable();
|
||||
return;
|
||||
}
|
||||
|
||||
ExpressionCodeGenerator generator("number|string", "", codeGenerator, context);
|
||||
node.expression->Visit(generator);
|
||||
output +=
|
||||
codeGenerator.GenerateVariableBracketAccessor(generator.GetOutput());
|
||||
@@ -137,10 +200,10 @@ void ExpressionCodeGenerator::OnVisitVariableBracketAccessorNode(
|
||||
|
||||
void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
|
||||
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType,
|
||||
node);
|
||||
|
||||
if (gd::ParameterMetadata::IsObject(type)) {
|
||||
output +=
|
||||
codeGenerator.GenerateObject(node.identifierName, type, context);
|
||||
@@ -153,8 +216,7 @@ void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
|
||||
: gd::EventsCodeGenerator::OBJECT_VARIABLE);
|
||||
|
||||
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsContainersList(),
|
||||
rootObjectName,
|
||||
node);
|
||||
output += codeGenerator.GenerateGetVariable(
|
||||
@@ -162,30 +224,60 @@ void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
|
||||
if (!node.childIdentifierName.empty()) {
|
||||
output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
|
||||
}
|
||||
} else if (node.childIdentifierName.empty()) {
|
||||
output += "/* Error during generation, unrecognized identifier type: " +
|
||||
codeGenerator.ConvertToString(type) + " with value " +
|
||||
codeGenerator.ConvertToString(node.identifierName) + " */ " +
|
||||
codeGenerator.ConvertToStringExplicit(node.identifierName);
|
||||
}
|
||||
else {
|
||||
// This is for function names that are put in IdentifierNode
|
||||
// because the type is needed to tell them appart from variables.
|
||||
output += GenerateDefaultValue(type);
|
||||
} else {
|
||||
const auto& variablesContainersList = codeGenerator.GetProjectScopedContainers().GetVariablesContainersList();
|
||||
const auto& propertiesContainersList = codeGenerator.GetProjectScopedContainers().GetPropertiesContainersList();
|
||||
const auto& parametersVectorsList = codeGenerator.GetProjectScopedContainers().GetParametersVectorsList();
|
||||
|
||||
// The node represents a variable, property, parameter or an object.
|
||||
codeGenerator.GetProjectScopedContainers().MatchIdentifierWithName<void>(node.identifierName, [&]() {
|
||||
// Generate the code to access the object variable.
|
||||
output += codeGenerator.GenerateGetVariable(
|
||||
node.childIdentifierName, gd::EventsCodeGenerator::OBJECT_VARIABLE, context, node.identifierName);
|
||||
output += codeGenerator.GenerateVariableValueAs(type);
|
||||
}, [&]() {
|
||||
if (!codeGenerator.HasProjectAndLayout()) {
|
||||
gd::LogWarning("Tried to generate access to a variable without a project/scene - the code generator only works for global and scene variables for now.");
|
||||
output += GenerateDefaultValue(type);
|
||||
return;
|
||||
}
|
||||
|
||||
// This could be adapted in the future if more scopes are supported at runtime.
|
||||
EventsCodeGenerator::VariableScope scope = gd::EventsCodeGenerator::PROJECT_VARIABLE;
|
||||
if (variablesContainersList.GetBottomMostVariablesContainer()->Has(node.identifierName)) {
|
||||
scope = gd::EventsCodeGenerator::LAYOUT_VARIABLE;
|
||||
}
|
||||
|
||||
output += codeGenerator.GenerateGetVariable(node.identifierName, scope, context, "");
|
||||
if (!node.childIdentifierName.empty()) {
|
||||
output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
|
||||
}
|
||||
output += codeGenerator.GenerateVariableValueAs(type);
|
||||
}, [&]() {
|
||||
const auto& propertiesContainerAndProperty = propertiesContainersList.Get(node.identifierName);
|
||||
|
||||
output += codeGenerator.GeneratePropertyGetter(
|
||||
propertiesContainerAndProperty.first, propertiesContainerAndProperty.second, type, context);
|
||||
}, [&]() {
|
||||
const auto& parameter = gd::ParameterMetadataTools::Get(parametersVectorsList, node.identifierName);
|
||||
output += codeGenerator.GenerateParameterGetter(parameter, type, context);
|
||||
}, [&]() {
|
||||
// The identifier does not represents a variable (or a child variable), or not at least an existing
|
||||
// one, nor an object variable. It's invalid.
|
||||
output += GenerateDefaultValue(type);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionCodeGenerator::OnVisitFunctionCallNode(FunctionCallNode& node) {
|
||||
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType,
|
||||
node);
|
||||
|
||||
const gd::ExpressionMetadata &metadata = MetadataProvider::GetFunctionCallMetadata(
|
||||
codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsContainersList(),
|
||||
node);
|
||||
|
||||
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata)) {
|
||||
@@ -216,10 +308,10 @@ gd::String ExpressionCodeGenerator::GenerateFreeFunctionCode(
|
||||
const std::vector<std::unique_ptr<ExpressionNode>>& parameters,
|
||||
const ExpressionMetadata& expressionMetadata) {
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionMetadata.codeExtraInformation.GetIncludeFiles());
|
||||
expressionMetadata.GetIncludeFiles());
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionMetadata.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
if (expressionMetadata.HasCustomCodeGenerator()) {
|
||||
return expressionMetadata.codeExtraInformation.customCodeGenerator(
|
||||
PrintParameters(parameters), codeGenerator, context);
|
||||
}
|
||||
@@ -236,16 +328,11 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
|
||||
const gd::String& objectName,
|
||||
const std::vector<std::unique_ptr<ExpressionNode>>& parameters,
|
||||
const ExpressionMetadata& expressionMetadata) {
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups =
|
||||
codeGenerator.GetGlobalObjectsAndGroups();
|
||||
const gd::ObjectsContainer& objectsAndGroups =
|
||||
codeGenerator.GetObjectsAndGroups();
|
||||
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionMetadata.codeExtraInformation.GetIncludeFiles());
|
||||
expressionMetadata.GetIncludeFiles());
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionMetadata.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
if (expressionMetadata.HasCustomCodeGenerator()) {
|
||||
return expressionMetadata.codeExtraInformation.customCodeGenerator(
|
||||
PrintParameters(parameters), codeGenerator, context);
|
||||
}
|
||||
@@ -261,20 +348,14 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
|
||||
|
||||
// Get object(s) concerned by function call
|
||||
std::vector<gd::String> realObjects =
|
||||
codeGenerator.ExpandObjectsName(objectName, context);
|
||||
codeGenerator.GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
context.ObjectsListNeeded(realObjects[i]);
|
||||
|
||||
gd::String objectType = gd::GetTypeOfObject(
|
||||
globalObjectsAndGroups, objectsAndGroups, realObjects[i]);
|
||||
gd::String objectType = codeGenerator.GetObjectsContainersList().GetTypeOfObject(realObjects[i]);
|
||||
const ObjectMetadata& objInfo = MetadataProvider::GetObjectMetadata(
|
||||
codeGenerator.GetPlatform(), objectType);
|
||||
|
||||
if (objInfo.IsUnsupportedBaseObjectCapability(
|
||||
expressionMetadata.GetRequiredBaseObjectCapability())) {
|
||||
// Do nothing, skipping objects not supporting the capability required by
|
||||
// this expression.
|
||||
} else {
|
||||
codeGenerator.AddIncludeFiles(objInfo.includeFiles);
|
||||
functionOutput = codeGenerator.GenerateObjectFunctionCall(
|
||||
realObjects[i],
|
||||
@@ -283,7 +364,6 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
|
||||
parametersCode,
|
||||
functionOutput,
|
||||
context);
|
||||
}
|
||||
}
|
||||
|
||||
return functionOutput;
|
||||
@@ -294,16 +374,11 @@ gd::String ExpressionCodeGenerator::GenerateBehaviorFunctionCode(
|
||||
const gd::String& behaviorName,
|
||||
const std::vector<std::unique_ptr<ExpressionNode>>& parameters,
|
||||
const ExpressionMetadata& expressionMetadata) {
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups =
|
||||
codeGenerator.GetGlobalObjectsAndGroups();
|
||||
const gd::ObjectsContainer& objectsAndGroups =
|
||||
codeGenerator.GetObjectsAndGroups();
|
||||
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionMetadata.codeExtraInformation.GetIncludeFiles());
|
||||
expressionMetadata.GetIncludeFiles());
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionMetadata.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
if (expressionMetadata.HasCustomCodeGenerator()) {
|
||||
return expressionMetadata.codeExtraInformation.customCodeGenerator(
|
||||
PrintParameters(parameters), codeGenerator, context);
|
||||
}
|
||||
@@ -317,12 +392,11 @@ gd::String ExpressionCodeGenerator::GenerateBehaviorFunctionCode(
|
||||
|
||||
// Get object(s) concerned by function call
|
||||
std::vector<gd::String> realObjects =
|
||||
codeGenerator.ExpandObjectsName(objectName, context);
|
||||
codeGenerator.GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
|
||||
|
||||
gd::String functionOutput = GenerateDefaultValue(type);
|
||||
|
||||
gd::String behaviorType = gd::GetTypeOfBehavior(
|
||||
globalObjectsAndGroups, objectsAndGroups, behaviorName);
|
||||
gd::String behaviorType = codeGenerator.GetObjectsContainersList().GetTypeOfBehavior(behaviorName);
|
||||
const BehaviorMetadata& autoInfo = MetadataProvider::GetBehaviorMetadata(
|
||||
codeGenerator.GetPlatform(), behaviorType);
|
||||
|
||||
@@ -358,8 +432,7 @@ gd::String ExpressionCodeGenerator::GenerateParametersCodes(
|
||||
if (!parameterMetadata.IsCodeOnly()) {
|
||||
if (nonCodeOnlyParameterIndex < parameters.size()) {
|
||||
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsContainersList(),
|
||||
rootObjectName,
|
||||
*parameters[nonCodeOnlyParameterIndex].get());
|
||||
ExpressionCodeGenerator generator(parameterMetadata.GetType(), objectName, codeGenerator, context);
|
||||
@@ -429,8 +502,7 @@ gd::String ExpressionCodeGenerator::GenerateDefaultValue(
|
||||
|
||||
void ExpressionCodeGenerator::OnVisitEmptyNode(EmptyNode& node) {
|
||||
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType,
|
||||
node);
|
||||
output += GenerateDefaultValue(type);
|
||||
@@ -439,8 +511,7 @@ void ExpressionCodeGenerator::OnVisitEmptyNode(EmptyNode& node) {
|
||||
void ExpressionCodeGenerator::OnVisitObjectFunctionNameNode(
|
||||
ObjectFunctionNameNode& node) {
|
||||
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType,
|
||||
node);
|
||||
output += GenerateDefaultValue(type);
|
||||
|
@@ -102,6 +102,7 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
|
||||
const std::vector<std::unique_ptr<ExpressionNode>>& parameters);
|
||||
|
||||
gd::String output;
|
||||
gd::String objectNameToUseForVariableAccessor;
|
||||
EventsCodeGenerator& codeGenerator;
|
||||
EventsCodeGenerationContext& context;
|
||||
const gd::String rootType;
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "GDCore/Events/Builtin/AsyncEvent.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/EventVisitor.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
@@ -140,6 +141,14 @@ void BaseEvent::Preprocess(gd::EventsCodeGenerator& codeGenerator,
|
||||
}
|
||||
}
|
||||
|
||||
bool BaseEvent::AcceptVisitor(gd::EventVisitor& eventVisitor) {
|
||||
return eventVisitor.VisitEvent(*this);
|
||||
}
|
||||
|
||||
void BaseEvent::AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const {
|
||||
eventVisitor.VisitEvent(*this);
|
||||
}
|
||||
|
||||
BaseEventSPtr GD_CORE_API CloneRememberingOriginalEvent(BaseEventSPtr event) {
|
||||
gd::BaseEventSPtr copy(event->Clone());
|
||||
// Original event is either the original event of the copied event, or the
|
||||
|
@@ -24,6 +24,8 @@ class EventsCodeGenerationContext;
|
||||
class Platform;
|
||||
class SerializerElement;
|
||||
class Instruction;
|
||||
class EventVisitor;
|
||||
class ReadOnlyEventVisitor;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -238,6 +240,9 @@ class GD_CORE_API BaseEvent {
|
||||
*/
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element){};
|
||||
|
||||
virtual bool AcceptVisitor(gd::EventVisitor& eventVisitor);
|
||||
virtual void AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const;
|
||||
///@}
|
||||
|
||||
/** \name Common properties
|
||||
@@ -276,7 +281,6 @@ class GD_CORE_API BaseEvent {
|
||||
* \brief True if the event should be folded in the events editor.
|
||||
*/
|
||||
bool IsFolded() const { return folded; }
|
||||
|
||||
///@}
|
||||
|
||||
std::weak_ptr<gd::BaseEvent>
|
||||
|
76
Core/GDCore/Events/EventVisitor.h
Normal file
76
Core/GDCore/Events/EventVisitor.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
class LinkEvent;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Visitor of any kind of event.
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API EventVisitor {
|
||||
public:
|
||||
virtual ~EventVisitor(){};
|
||||
|
||||
/**
|
||||
* Called to do some work on an event.
|
||||
*
|
||||
* \return true if the event must be deleted from the events list, false
|
||||
* otherwise.
|
||||
*/
|
||||
virtual bool VisitEvent(gd::BaseEvent& linkEvent) = 0;
|
||||
|
||||
/**
|
||||
* Called to do some work on a link event.
|
||||
*
|
||||
* Note that VisitEvent is also called with this event.
|
||||
*
|
||||
* \return true if the event must be deleted from the events list, false
|
||||
* otherwise.
|
||||
*/
|
||||
virtual bool VisitLinkEvent(gd::LinkEvent& linkEvent) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Visitor of any kind of event.
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API ReadOnlyEventVisitor {
|
||||
public:
|
||||
virtual ~ReadOnlyEventVisitor(){};
|
||||
|
||||
/**
|
||||
* Called to do some work on an event.
|
||||
*/
|
||||
virtual void VisitEvent(const gd::BaseEvent& linkEvent) = 0;
|
||||
|
||||
/**
|
||||
* Called to do some work on a link event.
|
||||
*
|
||||
* Note that VisitEvent is also called with this event.
|
||||
*/
|
||||
virtual void VisitLinkEvent(const gd::LinkEvent& linkEvent) = 0;
|
||||
|
||||
/**
|
||||
* @brief Abort the iteration on the events.
|
||||
*/
|
||||
virtual void StopAnyEventIteration() = 0;
|
||||
};
|
||||
|
||||
}
|
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "EventsList.h"
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
@@ -100,9 +101,8 @@ bool EventsList::Contains(const gd::BaseEvent& eventToSearch,
|
||||
}
|
||||
|
||||
bool EventsList::MoveEventToAnotherEventsList(const gd::BaseEvent& eventToMove,
|
||||
gd::EventsList& newEventsList,
|
||||
std::size_t newPosition) {
|
||||
|
||||
gd::EventsList& newEventsList,
|
||||
std::size_t newPosition) {
|
||||
for (std::size_t i = 0; i < GetEventsCount(); ++i) {
|
||||
if (events[i].get() == &eventToMove) {
|
||||
std::shared_ptr<BaseEvent> event = events[i];
|
||||
|
@@ -19,8 +19,10 @@
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
#include "GrammarTerminals.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace gd::GrammarTerminals;
|
||||
|
||||
namespace gd {
|
||||
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
#include "GrammarTerminals.h"
|
||||
namespace gd {
|
||||
class Expression;
|
||||
class ObjectsContainer;
|
||||
@@ -28,6 +29,8 @@ class ExpressionMetadata;
|
||||
|
||||
namespace gd {
|
||||
|
||||
using namespace gd::GrammarTerminals;
|
||||
|
||||
/** \brief Parse an expression, returning a tree of node corresponding
|
||||
* to the parsed expression.
|
||||
*
|
||||
@@ -44,14 +47,9 @@ class GD_CORE_API ExpressionParser2 {
|
||||
virtual ~ExpressionParser2(){};
|
||||
|
||||
/**
|
||||
* Parse the given expression with the specified type.
|
||||
* Parse the given expression into a tree of nodes.
|
||||
*
|
||||
* \param type Type of the expression: "string", "number",
|
||||
* type supported by gd::ParameterMetadata::IsObject, types supported by
|
||||
* gd::ParameterMetadata::IsExpression or "unknown".
|
||||
* \param expression The expression to parse
|
||||
* \param objectName Specify the object name, only for the
|
||||
* case of "objectvar" type.
|
||||
* \param expression The expression to parse.
|
||||
*
|
||||
* \return The node representing the expression as a parsed tree.
|
||||
*/
|
||||
@@ -211,7 +209,7 @@ class GD_CORE_API ExpressionParser2 {
|
||||
}
|
||||
SkipIfChar(IsClosingParenthesis);
|
||||
return factor;
|
||||
} else if (IsIdentifierAllowedChar()) {
|
||||
} else if (CheckIfChar(IsAllowedInIdentifier)) {
|
||||
return Identifier();
|
||||
}
|
||||
|
||||
@@ -264,12 +262,11 @@ class GD_CORE_API ExpressionParser2 {
|
||||
} else if (CheckIfChar(IsDot)) {
|
||||
ExpressionParserLocation dotLocation = SkipChar();
|
||||
SkipAllWhitespaces();
|
||||
return ObjectFunctionOrBehaviorFunction(
|
||||
return ObjectFunctionOrBehaviorFunctionOrVariable(
|
||||
name, nameLocation, dotLocation);
|
||||
} else if (CheckIfChar(IsOpeningSquareBracket)) {
|
||||
return Variable(name, nameLocation);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
auto identifier = gd::make_unique<IdentifierNode>(name);
|
||||
identifier->location = ExpressionParserLocation(
|
||||
nameLocation.GetStartPosition(), GetCurrentPosition());
|
||||
@@ -315,7 +312,7 @@ class GD_CORE_API ExpressionParser2 {
|
||||
auto dotLocation = SkipChar();
|
||||
SkipAllWhitespaces();
|
||||
|
||||
auto identifierAndLocation = ReadIdentifierName();
|
||||
auto identifierAndLocation = ReadIdentifierName(/*allowDeprecatedSpacesInName=*/ false);
|
||||
auto child =
|
||||
gd::make_unique<VariableAccessorNode>(identifierAndLocation.name);
|
||||
child->child = VariableAccessorOrVariableBracketAccessor();
|
||||
@@ -355,11 +352,11 @@ class GD_CORE_API ExpressionParser2 {
|
||||
}
|
||||
|
||||
std::unique_ptr<IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode>
|
||||
ObjectFunctionOrBehaviorFunction(
|
||||
ObjectFunctionOrBehaviorFunctionOrVariable(
|
||||
const gd::String &parentIdentifier,
|
||||
const ExpressionParserLocation &parentIdentifierLocation,
|
||||
const ExpressionParserLocation &parentIdentifierDotLocation) {
|
||||
auto childIdentifierAndLocation = ReadIdentifierName();
|
||||
auto childIdentifierAndLocation = ReadIdentifierName(/*allowDeprecatedSpacesInName=*/ false);
|
||||
const gd::String &childIdentifierName = childIdentifierAndLocation.name;
|
||||
const auto &childIdentifierNameLocation =
|
||||
childIdentifierAndLocation.location;
|
||||
@@ -417,12 +414,6 @@ class GD_CORE_API ExpressionParser2 {
|
||||
|
||||
auto node = gd::make_unique<IdentifierNode>(
|
||||
parentIdentifier, childIdentifierName);
|
||||
if (!CheckIfChar(IsParameterSeparator) && !CheckIfChar(IsClosingParenthesis) && !IsEndReached()) {
|
||||
node->diagnostic = RaiseSyntaxError(
|
||||
_("An opening parenthesis (for an object expression), a double colon "
|
||||
"(:: for a behavior expression), a dot or an opening bracket (for "
|
||||
"a child variable) where expected."));
|
||||
}
|
||||
node->location = ExpressionParserLocation(
|
||||
parentIdentifierLocation.GetStartPosition(), GetCurrentPosition());
|
||||
node->identifierNameLocation = parentIdentifierLocation;
|
||||
@@ -606,95 +597,6 @@ class GD_CORE_API ExpressionParser2 {
|
||||
return predicate(character);
|
||||
}
|
||||
|
||||
bool IsIdentifierAllowedChar() {
|
||||
if (currentPosition >= expression.size()) return false;
|
||||
gd::String::value_type character = expression[currentPosition];
|
||||
|
||||
// Quickly compare if the character is a number or ASCII character.
|
||||
if ((character >= '0' && character <= '9') ||
|
||||
(character >= 'A' && character <= 'Z') ||
|
||||
(character >= 'a' && character <= 'z'))
|
||||
return true;
|
||||
|
||||
// Otherwise do the full check against separators forbidden in identifiers.
|
||||
if (!IsParameterSeparator(character) && !IsDot(character) &&
|
||||
!IsQuote(character) && !IsBracket(character) &&
|
||||
!IsExpressionOperator(character) && !IsTermOperator(character)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsWhitespace(gd::String::value_type character) {
|
||||
return character == ' ' || character == '\n' || character == '\r';
|
||||
}
|
||||
|
||||
static bool IsParameterSeparator(gd::String::value_type character) {
|
||||
return character == ',';
|
||||
}
|
||||
|
||||
static bool IsDot(gd::String::value_type character) {
|
||||
return character == '.';
|
||||
}
|
||||
|
||||
static bool IsQuote(gd::String::value_type character) {
|
||||
return character == '"';
|
||||
}
|
||||
|
||||
static bool IsBracket(gd::String::value_type character) {
|
||||
return character == '(' || character == ')' || character == '[' ||
|
||||
character == ']' || character == '{' || character == '}';
|
||||
}
|
||||
|
||||
static bool IsOpeningParenthesis(gd::String::value_type character) {
|
||||
return character == '(';
|
||||
}
|
||||
|
||||
static bool IsClosingParenthesis(gd::String::value_type character) {
|
||||
return character == ')';
|
||||
}
|
||||
|
||||
static bool IsOpeningSquareBracket(gd::String::value_type character) {
|
||||
return character == '[';
|
||||
}
|
||||
|
||||
static bool IsClosingSquareBracket(gd::String::value_type character) {
|
||||
return character == ']';
|
||||
}
|
||||
|
||||
static bool IsExpressionEndingChar(gd::String::value_type character) {
|
||||
return character == ',' || IsClosingParenthesis(character) ||
|
||||
IsClosingSquareBracket(character);
|
||||
}
|
||||
|
||||
static bool IsExpressionOperator(gd::String::value_type character) {
|
||||
return character == '+' || character == '-' || character == '<' ||
|
||||
character == '>' || character == '?' || character == '^' ||
|
||||
character == '=' || character == '\\' || character == ':' ||
|
||||
character == '!';
|
||||
}
|
||||
|
||||
static bool IsUnaryOperator(gd::String::value_type character) {
|
||||
return character == '+' || character == '-';
|
||||
}
|
||||
|
||||
static bool IsTermOperator(gd::String::value_type character) {
|
||||
return character == '/' || character == '*';
|
||||
}
|
||||
|
||||
static bool IsNumberFirstChar(gd::String::value_type character) {
|
||||
return character == '.' || (character >= '0' && character <= '9');
|
||||
}
|
||||
|
||||
static bool IsNonZeroDigit(gd::String::value_type character) {
|
||||
return (character >= '1' && character <= '9');
|
||||
}
|
||||
|
||||
static bool IsZeroDigit(gd::String::value_type character) {
|
||||
return character == '0';
|
||||
}
|
||||
|
||||
bool IsNamespaceSeparator() {
|
||||
// Namespace separator is a special kind of delimiter as it is 2 characters
|
||||
// long
|
||||
@@ -711,13 +613,13 @@ class GD_CORE_API ExpressionParser2 {
|
||||
ExpressionParserLocation location;
|
||||
};
|
||||
|
||||
IdentifierAndLocation ReadIdentifierName() {
|
||||
IdentifierAndLocation ReadIdentifierName(bool allowDeprecatedSpacesInName = true) {
|
||||
gd::String name;
|
||||
size_t startPosition = currentPosition;
|
||||
while (currentPosition < expression.size() &&
|
||||
(IsIdentifierAllowedChar()
|
||||
(CheckIfChar(IsAllowedInIdentifier)
|
||||
// Allow whitespace in identifier name for compatibility
|
||||
|| expression[currentPosition] == ' ')) {
|
||||
|| (allowDeprecatedSpacesInName && expression[currentPosition] == ' '))) {
|
||||
name += expression[currentPosition];
|
||||
currentPosition++;
|
||||
}
|
||||
|
@@ -189,7 +189,7 @@ struct GD_CORE_API IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode
|
||||
*
|
||||
* The name of a function to call on an object or the behavior,
|
||||
* for example: "MyObject.Function" or "MyObject.Physics".
|
||||
*
|
||||
*
|
||||
* A variable, potentially with accessor to its child,
|
||||
* for example: MyVariable or MyVariable.MyChild
|
||||
*/
|
||||
@@ -239,13 +239,14 @@ struct GD_CORE_API VariableAccessorOrVariableBracketAccessorNode : public Expres
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief A variable with bracket accessor or at least 2 "dot" accessors.
|
||||
* \brief A variable, or object variable, with bracket accessor or at least 2 "dot" accessors.
|
||||
*
|
||||
* Example: `MyVariable["MyChildren"]` or `MyVariable.MyChildren.MyGrandChildren`.
|
||||
* Example: `MyObject["MyVariable"]` or `MyObject.MyVariable.MyChildren`.
|
||||
*
|
||||
* Example: MyVariable[MyChildren] or MyVariable.MyChildren.MyGranChildren.
|
||||
*
|
||||
* Other cases like "MyVariable" or "MyVariable.MyChildren" are IdentifierNode
|
||||
* to allow handling ambiguities.
|
||||
*
|
||||
*
|
||||
* \see gd::IdentifierNode
|
||||
* \see gd::VariableAccessorNode
|
||||
* \see gd::VariableBracketAccessorNode
|
||||
@@ -267,7 +268,7 @@ struct GD_CORE_API VariableNode : public FunctionCallOrObjectFunctionNameOrEmpty
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief A bracket accessor of a variable. Example: MyChild
|
||||
* \brief A direct accessor to a child variable. Example: MyChild
|
||||
* in MyVariable.MyChild
|
||||
*/
|
||||
struct GD_CORE_API VariableAccessorNode
|
||||
@@ -285,7 +286,7 @@ struct GD_CORE_API VariableAccessorNode
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief A bracket accessor of a variable. Example: ["MyChild"]
|
||||
* \brief A bracket accessor to a child variable. Example: ["MyChild"]
|
||||
* (in MyVariable["MyChild"]).
|
||||
*/
|
||||
struct GD_CORE_API VariableBracketAccessorNode
|
||||
@@ -303,10 +304,10 @@ struct GD_CORE_API VariableBracketAccessorNode
|
||||
/**
|
||||
* \brief The name of a function to call on an object or the behavior
|
||||
* For example: "MyObject.Physics::LinearVelocity".
|
||||
*
|
||||
*
|
||||
* Other cases like "MyObject.Function" or "MyObject.Physics" are IdentifierNode
|
||||
* to allow handling ambiguities.
|
||||
*
|
||||
*
|
||||
* \see gd::IdentifierNode
|
||||
*/
|
||||
struct GD_CORE_API ObjectFunctionNameNode
|
||||
|
118
Core/GDCore/Events/Parsers/GrammarTerminals.h
Normal file
118
Core/GDCore/Events/Parsers/GrammarTerminals.h
Normal file
@@ -0,0 +1,118 @@
|
||||
#pragma once
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* Contains functions to handle the grammar of the expressions accepted by GDevelop.
|
||||
*/
|
||||
namespace GrammarTerminals {
|
||||
|
||||
inline bool IsWhitespace(gd::String::value_type character) {
|
||||
return character == ' ' || character == '\n' || character == '\r';
|
||||
}
|
||||
|
||||
inline bool IsParameterSeparator(gd::String::value_type character) {
|
||||
return character == ',';
|
||||
}
|
||||
|
||||
inline bool IsDot(gd::String::value_type character) { return character == '.'; }
|
||||
|
||||
inline bool IsQuote(gd::String::value_type character) {
|
||||
return character == '"';
|
||||
}
|
||||
|
||||
inline bool IsBracket(gd::String::value_type character) {
|
||||
return character == '(' || character == ')' || character == '[' ||
|
||||
character == ']' || character == '{' || character == '}';
|
||||
}
|
||||
|
||||
inline bool IsOpeningParenthesis(gd::String::value_type character) {
|
||||
return character == '(';
|
||||
}
|
||||
|
||||
inline bool IsClosingParenthesis(gd::String::value_type character) {
|
||||
return character == ')';
|
||||
}
|
||||
|
||||
inline bool IsOpeningSquareBracket(gd::String::value_type character) {
|
||||
return character == '[';
|
||||
}
|
||||
|
||||
inline bool IsClosingSquareBracket(gd::String::value_type character) {
|
||||
return character == ']';
|
||||
}
|
||||
|
||||
inline bool IsExpressionEndingChar(gd::String::value_type character) {
|
||||
return character == ',' || IsClosingParenthesis(character) ||
|
||||
IsClosingSquareBracket(character);
|
||||
}
|
||||
|
||||
inline bool IsExpressionOperator(gd::String::value_type character) {
|
||||
return character == '+' || character == '-' || character == '<' ||
|
||||
character == '>' || character == '?' || character == '^' ||
|
||||
character == '=' || character == '\\' || character == ':' ||
|
||||
character == '!';
|
||||
}
|
||||
|
||||
inline bool IsUnaryOperator(gd::String::value_type character) {
|
||||
return character == '+' || character == '-';
|
||||
}
|
||||
|
||||
inline bool IsTermOperator(gd::String::value_type character) {
|
||||
return character == '/' || character == '*';
|
||||
}
|
||||
|
||||
inline bool IsNumberFirstChar(gd::String::value_type character) {
|
||||
return character == '.' || (character >= '0' && character <= '9');
|
||||
}
|
||||
|
||||
inline bool IsNonZeroDigit(gd::String::value_type character) {
|
||||
return (character >= '1' && character <= '9');
|
||||
}
|
||||
|
||||
inline bool IsZeroDigit(gd::String::value_type character) {
|
||||
return character == '0';
|
||||
}
|
||||
|
||||
inline bool IsAdditionalReservedCharacter(gd::String::value_type character) {
|
||||
// These characters are not part of the grammar - but are often used in programming language
|
||||
// and could become operators or part of the grammar one day.
|
||||
return character == '~' || character == '\'' || character == '%' ||
|
||||
character == '#' || character == '@' || character == '|' ||
|
||||
character == '&' || character == '`' || character == '$' ||
|
||||
character == ';';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given character can be used in an identifier. This is
|
||||
* any unicode character, except for:
|
||||
* `, . " () [] {} + - < > ? ^ = \ : ! / * ~ ' % # @ | & $ ;`
|
||||
* and backtick and whitespaces (space, line break, carriage return).
|
||||
*
|
||||
* This is loosely based on what is allowed in languages like JavaScript
|
||||
* (see https://mathiasbynens.be/notes/javascript-properties), without support
|
||||
* for unicode escape syntax, and allowing all unicode ranges. The only
|
||||
* disallowed characters are the one used for the grammar.
|
||||
*/
|
||||
inline bool IsAllowedInIdentifier(gd::String::value_type character) {
|
||||
// Quickly compare if the character is a number or ASCII character.
|
||||
if ((character >= '0' && character <= '9') ||
|
||||
(character >= 'A' && character <= 'Z') ||
|
||||
(character >= 'a' && character <= 'z'))
|
||||
return true;
|
||||
|
||||
// Otherwise do the full check against separators forbidden in identifiers.
|
||||
if (!IsParameterSeparator(character) && !IsDot(character) &&
|
||||
!IsQuote(character) && !IsBracket(character) &&
|
||||
!IsExpressionOperator(character) && !IsTermOperator(character) &&
|
||||
!IsWhitespace(character) && !IsAdditionalReservedCharacter(character)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace GrammarTerminals
|
||||
} // namespace gd
|
@@ -17,7 +17,7 @@ const gd::String& EventsCodeNameMangler::GetMangledObjectsListName(
|
||||
return it->second;
|
||||
}
|
||||
|
||||
gd::String partiallyMangledName = originalObjectName;
|
||||
gd::String partiallyMangledName = GetMangledNameWithForbiddenUnderscore(originalObjectName);
|
||||
static const gd::String allowedCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
@@ -43,7 +43,15 @@ const gd::String& EventsCodeNameMangler::GetExternalEventsFunctionMangledName(
|
||||
return it->second;
|
||||
}
|
||||
|
||||
gd::String partiallyMangledName = externalEventsName;
|
||||
gd::String partiallyMangledName = GetMangledNameWithForbiddenUnderscore(externalEventsName);
|
||||
|
||||
mangledExternalEventsNames[externalEventsName] = "GDExternalEvents" + partiallyMangledName;
|
||||
return mangledExternalEventsNames[externalEventsName];
|
||||
}
|
||||
|
||||
gd::String EventsCodeNameMangler::GetMangledNameWithForbiddenUnderscore(
|
||||
const gd::String &name) {
|
||||
gd::String partiallyMangledName = name;
|
||||
static const gd::String allowedCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
@@ -57,11 +65,30 @@ const gd::String& EventsCodeNameMangler::GetExternalEventsFunctionMangledName(
|
||||
partiallyMangledName.replace(i, 1, "_" + gd::String::From(unallowedChar));
|
||||
}
|
||||
}
|
||||
|
||||
mangledExternalEventsNames[externalEventsName] = "GDExternalEvents" + partiallyMangledName;
|
||||
return mangledExternalEventsNames[externalEventsName];
|
||||
return partiallyMangledName;
|
||||
}
|
||||
|
||||
gd::String EventsCodeNameMangler::GetMangledName(
|
||||
const gd::String &name) {
|
||||
gd::String partiallyMangledName = name;
|
||||
static const gd::String allowedCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||
|
||||
for (size_t i = 0; i < partiallyMangledName.size();
|
||||
++i) // Replace all unallowed letter by an underscore and the ascii
|
||||
// number of the letter
|
||||
{
|
||||
if (allowedCharacters.find_first_of(
|
||||
std::u32string(1, partiallyMangledName[i])) == gd::String::npos) {
|
||||
char32_t unallowedChar = partiallyMangledName[i];
|
||||
partiallyMangledName.replace(i, 1, "_" + gd::String::From(unallowedChar));
|
||||
}
|
||||
}
|
||||
return partiallyMangledName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const gd::String& ManObjListName(const gd::String &objectName) {
|
||||
return EventsCodeNameMangler::Get()->GetMangledObjectsListName(objectName);
|
||||
}
|
||||
|
@@ -36,6 +36,8 @@ class GD_CORE_API EventsCodeNameMangler {
|
||||
const gd::String &GetExternalEventsFunctionMangledName(
|
||||
const gd::String &externalEventsName);
|
||||
|
||||
static gd::String GetMangledName(const gd::String &name);
|
||||
|
||||
static EventsCodeNameMangler *Get();
|
||||
static void DestroySingleton();
|
||||
|
||||
@@ -44,6 +46,9 @@ class GD_CORE_API EventsCodeNameMangler {
|
||||
virtual ~EventsCodeNameMangler(){};
|
||||
static EventsCodeNameMangler *_singleton;
|
||||
|
||||
// This method is inlined to avoid to copy the returned string.
|
||||
static inline gd::String GetMangledNameWithForbiddenUnderscore(const gd::String &name);
|
||||
|
||||
std::unordered_map<gd::String, gd::String>
|
||||
mangledObjectNames; ///< Memoized results of mangling for objects
|
||||
std::unordered_map<gd::String, gd::String>
|
||||
|
@@ -33,7 +33,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
.SetHelpPath("/events/functions/return")
|
||||
.AddParameter("expression", "The number to be returned")
|
||||
.AddParameter("expression", _("The number to be returned"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -48,7 +48,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
.SetHelpPath("/events/functions/return")
|
||||
.AddParameter("string", "The text to be returned")
|
||||
.AddParameter("string", _("The text to be returned"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -62,7 +62,37 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
.SetHelpPath("/events/functions/return")
|
||||
.AddParameter("trueorfalse", "Should the condition be true or false?")
|
||||
.AddParameter("trueorfalse", _("Should the condition be true or false?"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("CopyArgumentToVariable",
|
||||
_("Copy function parameter to variable"),
|
||||
_("Copy a function parameter (also called \"argument\") to a variable. "
|
||||
"The parameter type must be a variable."),
|
||||
_("Copy the parameter _PARAM0_ into the variable _PARAM1_"),
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
.SetHelpPath("/events/functions/return")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "variable")
|
||||
.AddParameter("scenevar", _("Scene variable"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("CopyVariableToArgument",
|
||||
_("Copy variable to function parameter"),
|
||||
_("Copy a variable to function parameter (also called \"argument\"). "
|
||||
"The parameter type must be a variable."),
|
||||
_("Copy the variable _PARAM1_ into the parameter _PARAM0_"),
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
.SetHelpPath("/events/functions/return")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "variable")
|
||||
.AddParameter("scenevar", _("Scene variable"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -77,7 +107,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
.AddParameter("functionParameterName", "Parameter name")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -85,21 +115,23 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
.AddExpression(
|
||||
"GetArgumentAsNumber",
|
||||
_("Get function parameter value"),
|
||||
_("Get function parameter (also called \"argument\") value."),
|
||||
_("Get function parameter (also called \"argument\") value. You don't need this most of the time as you can simply write the parameter name in an expression."),
|
||||
"",
|
||||
"res/function16.png")
|
||||
.AddParameter("functionParameterName", "Parameter name")
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.SetHidden();
|
||||
|
||||
extension
|
||||
.AddStrExpression(
|
||||
"GetArgumentAsString",
|
||||
_("Get function parameter text"),
|
||||
_("Get function parameter (also called \"argument\") text."),
|
||||
_("Get function parameter (also called \"argument\") text. You don't need this most of the time as you can simply write the parameter name in an expression."),
|
||||
"",
|
||||
"res/function16.png")
|
||||
.AddParameter("functionParameterName", "Parameter name")
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.SetHidden();
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
@@ -110,7 +142,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function16.png")
|
||||
.AddParameter("functionParameterName", "Parameter name")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
@@ -124,7 +156,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function16.png")
|
||||
.AddParameter("functionParameterName", "Parameter name")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"string", gd::ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
@@ -43,6 +43,13 @@ class GD_CORE_API BuiltinExtensionsImplementer {
|
||||
static void ImplementsVariablesExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsWindowExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsAsyncExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsResizableExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsScalableExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsFlippableExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsAnimatableExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsEffectExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsOpacityExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsTextContainerExtension(gd::PlatformExtension& extension);
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -29,8 +29,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.SetIcon("res/actions/force24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Variables"))
|
||||
.SetIcon("res/conditions/var24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Timers"))
|
||||
.SetIcon("res/actions/timer24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Visibility"))
|
||||
.SetIcon("res/actions/visibilite24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Position"))
|
||||
.SetIcon("res/actions/position24_black.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Angle"))
|
||||
.SetIcon("res/actions/direction24_black.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Size"))
|
||||
.SetIcon("res/actions/scale24_black.png");
|
||||
|
||||
gd::ObjectMetadata& obj = extension.AddObject<gd::ObjectConfiguration>(
|
||||
"", _("Base object"), _("Base object"), "res/objeticon24.png");
|
||||
@@ -388,7 +396,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Z order"),
|
||||
_("Modify the Z-order of an object"),
|
||||
_("the z-order"),
|
||||
_("Z order"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/planicon24.png",
|
||||
"res/actions/planicon.png")
|
||||
|
||||
@@ -542,7 +550,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Z-order"),
|
||||
_("Compare the Z-order of the specified object."),
|
||||
_("the Z-order"),
|
||||
_("Z-order"),
|
||||
_("Layer"),
|
||||
"res/conditions/planicon24.png",
|
||||
"res/conditions/planicon.png")
|
||||
|
||||
@@ -609,6 +617,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("AngleOfDisplacement",
|
||||
_("Angle of movement (using forces)"),
|
||||
_("Compare the angle of movement of an object according to "
|
||||
@@ -618,7 +627,20 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Movement using forces"),
|
||||
"res/conditions/vitesse24.png",
|
||||
"res/conditions/vitesse.png")
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Angle, in degrees"))
|
||||
.AddParameter("expression", _("Tolerance, in degrees"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddCondition("IsTotalForceAngleAround",
|
||||
_("Angle of movement (using forces)"),
|
||||
_("Compare the angle of movement of an object according to "
|
||||
"the forces applied on it."),
|
||||
_("Angle of movement of _PARAM0_ is _PARAM1_ ± _PARAM2_°"),
|
||||
_("Movement using forces"),
|
||||
"res/conditions/vitesse24.png",
|
||||
"res/conditions/vitesse.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Angle, in degrees"))
|
||||
.AddParameter("expression", _("Tolerance, in degrees"))
|
||||
@@ -1101,6 +1123,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/scaleWidth_black.png")
|
||||
.AddParameter("object", _("Object"));
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Largeur",
|
||||
_("Width"),
|
||||
_("Width of the object"),
|
||||
@@ -1116,6 +1139,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/scaleHeight_black.png")
|
||||
.AddParameter("object", _("Object"));
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Hauteur",
|
||||
_("Height"),
|
||||
_("Height of the object"),
|
||||
@@ -1127,7 +1151,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
obj.AddExpression("ZOrder",
|
||||
_("Z-order"),
|
||||
_("Z-order of an object"),
|
||||
_("Visibility"),
|
||||
"",
|
||||
"res/actions/planicon.png")
|
||||
.AddParameter("object", _("Object"));
|
||||
|
||||
@@ -1201,7 +1225,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
obj.AddExpression("ObjectTimerElapsedTime",
|
||||
_("Object timer value"),
|
||||
_("Value of an object timer"),
|
||||
_("Object timers"),
|
||||
_("Timers"),
|
||||
"res/actions/time.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("identifier", _("Timer's name"), "objectTimer");
|
||||
@@ -1251,6 +1275,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("expression", _("Target X position"))
|
||||
.AddParameter("expression", _("Target Y position"));
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("EnableEffect",
|
||||
_("Enable an object effect"),
|
||||
_("Enable an effect on the object"),
|
||||
@@ -1262,12 +1287,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("yesorno", _("Enable?"))
|
||||
.MarkAsSimple()
|
||||
.SetRequiresBaseObjectCapability("effect");
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("SetEffectDoubleParameter",
|
||||
_("Effect parameter (number)"),
|
||||
_("Change the value of a parameter of an effect.") + "\n" +
|
||||
_("You can find the parameter names (and change the effect "
|
||||
_("Effect property (number)"),
|
||||
_("Change the value of a property of an effect.") + "\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Set _PARAM2_ to _PARAM3_ for effect _PARAM1_ of _PARAM0_"),
|
||||
_("Effects"),
|
||||
@@ -1275,16 +1301,17 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("objectEffectParameterName", _("Property name"))
|
||||
.AddParameter("expression", _("New value"))
|
||||
.MarkAsSimple()
|
||||
.SetRequiresBaseObjectCapability("effect");
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("SetEffectStringParameter",
|
||||
_("Effect parameter (string)"),
|
||||
_("Change the value (string) of a parameter of an effect.") +
|
||||
_("Effect property (string)"),
|
||||
_("Change the value (string) of a property of an effect.") +
|
||||
"\n" +
|
||||
_("You can find the parameter names (and change the effect "
|
||||
_("You can find the property names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Set _PARAM2_ to _PARAM3_ for effect _PARAM1_ of _PARAM0_"),
|
||||
_("Effects"),
|
||||
@@ -1292,15 +1319,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("objectEffectParameterName", _("Property name"))
|
||||
.AddParameter("string", _("New value"))
|
||||
.MarkAsSimple()
|
||||
.SetRequiresBaseObjectCapability("effect");
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("SetEffectBooleanParameter",
|
||||
_("Effect parameter (enable or disable)"),
|
||||
_("Enable or disable a parameter of an effect.") + "\n" +
|
||||
_("You can find the parameter names (and change the effect "
|
||||
_("Effect property (enable or disable)"),
|
||||
_("Enable or disable a property of an effect.") + "\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Enable _PARAM2_ for effect _PARAM1_ of _PARAM0_: _PARAM3_"),
|
||||
_("Effects"),
|
||||
@@ -1308,11 +1336,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("yesorno", _("Enable?"))
|
||||
.AddParameter("objectEffectParameterName", _("Property name"))
|
||||
.AddParameter("yesorno", _("Enable this property"))
|
||||
.MarkAsSimple()
|
||||
.SetRequiresBaseObjectCapability("effect");
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("IsEffectEnabled",
|
||||
_("Effect is enabled"),
|
||||
_("Check if the effect on an object is enabled."),
|
||||
@@ -1323,7 +1352,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.MarkAsSimple()
|
||||
.SetRequiresBaseObjectCapability("effect");
|
||||
.SetHidden();
|
||||
|
||||
obj.AddAction("SetIncludedInParentCollisionMask",
|
||||
_("Include in parent collision mask"),
|
||||
@@ -1349,7 +1378,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("objectListOrEmptyIfJustDeclared", _("Object to create"))
|
||||
.AddParameter("expression", _("X position"))
|
||||
.AddParameter("expression", _("Y position"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.MarkAsSimple();
|
||||
|
||||
@@ -1374,7 +1403,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"with this name are found in the group, no object will be created."))
|
||||
.AddParameter("expression", _("X position"))
|
||||
.AddParameter("expression", _("Y position"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -1404,7 +1433,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Objects"),
|
||||
"res/actions/ajouthasard24.png",
|
||||
"res/actions/ajouthasard.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.MarkAsSimple();
|
||||
|
||||
@@ -1463,7 +1492,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Objects"),
|
||||
"res/conditions/add24.png",
|
||||
"res/conditions/add.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -1478,7 +1507,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Objects"),
|
||||
"res/conditions/ajouthasard24.png",
|
||||
"res/conditions/ajouthasard.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.MarkAsSimple();
|
||||
|
||||
@@ -1588,14 +1617,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"Raycast",
|
||||
_("Raycast"),
|
||||
_("Sends a ray from the given source position and angle, "
|
||||
"intersecting the closest object.\nThe instersected "
|
||||
"intersecting the closest object.\nThe intersected "
|
||||
"object will become the only one taken into account.\nIf "
|
||||
"the condition is inverted, the object to be intersected "
|
||||
"will be the farthest one within the ray radius."),
|
||||
_("Cast a ray from _PARAM1_;_PARAM2_, angle: _PARAM3_ and max "
|
||||
"distance: _PARAM4_px, against _PARAM0_, and save the "
|
||||
"result in _PARAM5_, _PARAM6_"),
|
||||
"",
|
||||
_("Collision"),
|
||||
"res/conditions/raycast24.png",
|
||||
"res/conditions/raycast.png")
|
||||
.AddParameter("objectList", _("Objects to test against the ray"))
|
||||
@@ -1619,14 +1648,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"RaycastToPosition",
|
||||
_("Raycast to position"),
|
||||
_("Sends a ray from the given source position to the final point, "
|
||||
"intersecting the closest object.\nThe instersected "
|
||||
"intersecting the closest object.\nThe intersected "
|
||||
"object will become the only one taken into account.\nIf "
|
||||
"the condition is inverted, the object to be intersected "
|
||||
"will be the farthest one within the ray radius."),
|
||||
_("Cast a ray from _PARAM1_;_PARAM2_ to _PARAM3_;_PARAM4_ "
|
||||
"against _PARAM0_, and save the "
|
||||
"result in _PARAM5_, _PARAM6_"),
|
||||
"",
|
||||
_("Collision"),
|
||||
"res/conditions/raycast24.png",
|
||||
"res/conditions/raycast.png")
|
||||
.AddParameter("objectList", _("Objects to test against the ray"))
|
||||
|
@@ -40,7 +40,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -72,7 +72,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -103,7 +103,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
@@ -119,7 +119,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
@@ -136,7 +136,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
@@ -153,7 +153,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
@@ -170,7 +170,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
@@ -187,7 +187,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
@@ -204,7 +204,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -322,12 +322,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression",
|
||||
_("Value (1:Initial zoom, 2:Zoom x2, 0.5:Unzoom x2...)"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
// TODO Deprecated: hide this action in a future release.
|
||||
extension
|
||||
.AddAction(
|
||||
"FixCamera",
|
||||
@@ -339,6 +338,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.SetHidden()
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("objectPtr", _("Object"))
|
||||
.AddParameter("expression",
|
||||
@@ -354,46 +354,41 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
true)
|
||||
.SetDefaultValue("yes")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"ClampCamera",
|
||||
_("Enforce camera boundaries"),
|
||||
_("Enforce camera boundaries by moving the camera back inside specified boundaries."),
|
||||
_("Enforce camera boundaries (left: _PARAM1_, top: _PARAM2_ "
|
||||
"right: _PARAM3_, bottom: _PARAM4_, layer: _PARAM5_)"),
|
||||
"",
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddAction("ClampCamera",
|
||||
_("Enforce camera boundaries"),
|
||||
_("Enforce camera boundaries by moving the camera back inside "
|
||||
"specified boundaries."),
|
||||
_("Enforce camera boundaries (left: _PARAM1_, top: _PARAM2_ "
|
||||
"right: _PARAM3_, bottom: _PARAM4_, layer: _PARAM5_)"),
|
||||
"",
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression",
|
||||
_("Left bound X Position"))
|
||||
.AddParameter("expression",
|
||||
_("Top bound Y Position"))
|
||||
.AddParameter("expression",
|
||||
_("Right bound X Position"))
|
||||
.AddParameter("expression",
|
||||
_("Bottom bound Y Position"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("expression", _("Left bound X Position"))
|
||||
.AddParameter("expression", _("Top bound Y Position"))
|
||||
.AddParameter("expression", _("Right bound X Position"))
|
||||
.AddParameter("expression", _("Bottom bound Y Position"))
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"CentreCamera",
|
||||
_("Center the camera on an object"),
|
||||
_("Center the camera on the specified object."),
|
||||
_("Center camera on _PARAM1_ (layer: _PARAM3_)"),
|
||||
"",
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddAction("CentreCamera",
|
||||
_("Center the camera on an object"),
|
||||
_("Center the camera on the specified object."),
|
||||
_("Center camera on _PARAM1_ (layer: _PARAM3_)"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("objectPtr", _("Object"))
|
||||
.AddParameter("yesorno",
|
||||
@@ -401,7 +396,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
true)
|
||||
.SetDefaultValue("yes")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -449,58 +444,58 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
extension
|
||||
.AddAction(
|
||||
"SetLayerEffectParameter",
|
||||
_("Effect parameter (number)"),
|
||||
_("Change the value of a parameter of an effect.") + "\n" +
|
||||
_("You can find the parameter names (and change the effect "
|
||||
_("Effect property (number)"),
|
||||
_("Change the value of a property of an effect.") + "\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of layer _PARAM1_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("layerEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("layerEffectParameterName", _("Property name"))
|
||||
.AddParameter("expression", _("New value"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"SetLayerEffectStringParameter",
|
||||
_("Effect parameter (string)"),
|
||||
_("Change the value (string) of a parameter of an effect.") + "\n" +
|
||||
_("You can find the parameter names (and change the effect "
|
||||
_("Effect property (string)"),
|
||||
_("Change the value (string) of a property of an effect.") + "\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of layer _PARAM1_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("layerEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("layerEffectParameterName", _("Property name"))
|
||||
.AddParameter("string", _("New value"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"SetLayerEffectBooleanParameter",
|
||||
_("Effect parameter (enable or disable)"),
|
||||
_("Enable or disable a parameter of an effect.") + "\n" +
|
||||
_("You can find the parameter names (and change the effect "
|
||||
_("Effect property (enable or disable)"),
|
||||
_("Enable or disable a property of an effect.") + "\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Enable _PARAM3_ for effect _PARAM2_ of layer _PARAM1_: _PARAM4_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("layerEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("yesorno", _("Enable this parameter"))
|
||||
.AddParameter("layerEffectParameterName", _("Property name"))
|
||||
.AddParameter("yesorno", _("Enable this property"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -512,7 +507,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.MarkAsAdvanced();
|
||||
@@ -526,7 +521,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("yesorno", _("Enable"), "", true)
|
||||
@@ -542,7 +537,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/conditions/time24.png",
|
||||
"res/conditions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
@@ -553,14 +548,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
extension
|
||||
.AddAction(
|
||||
"ChangeLayerTimeScale",
|
||||
_("Change layer time scale"),
|
||||
_("Layer time scale"),
|
||||
_("Change the time scale applied to the objects of the layer."),
|
||||
_("Set the time scale of layer _PARAM1_ to _PARAM2_"),
|
||||
"",
|
||||
"res/actions/time24.png",
|
||||
"res/actions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression",
|
||||
_("Scale (1: Default, 2: 2x faster, 0.5: 2x slower...)"));
|
||||
@@ -575,7 +570,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/conditions/layer24.png",
|
||||
"res/conditions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions())
|
||||
@@ -592,14 +587,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/layer24.png",
|
||||
"res/actions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("New default Z order"));
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"SetLayerAmbientLightColor",
|
||||
_("Set the ambient light color"),
|
||||
_("Ambient light color"),
|
||||
_("Set the ambient light color of the lighting layer in format "
|
||||
"\"R;G;B\" string."),
|
||||
_("Set the ambient color of the lighting layer _PARAM1_ to _PARAM2_"),
|
||||
@@ -607,7 +602,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/color24.png",
|
||||
"res/actions/color.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"Lighting\"")
|
||||
.AddParameter("color", _("Color"))
|
||||
.MarkAsAdvanced();
|
||||
|
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("AnimatableCapability",
|
||||
_("Animatable capability"),
|
||||
_("Animate objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Animatable capability"))
|
||||
.SetIcon("res/actions/animation24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Animations and images"))
|
||||
.SetIcon("res/actions/animation24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"AnimatableBehavior",
|
||||
_("Animatable capability"),
|
||||
"Animation",
|
||||
_("Animate objects."),
|
||||
"",
|
||||
"res/actions/animation24.png",
|
||||
"AnimatableBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"Index",
|
||||
_("Animation (by number)"),
|
||||
_("the animation played by the object using the animation number (from "
|
||||
"the animations list)"),
|
||||
_("the number of the animation"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Animation index")))
|
||||
.MarkAsSimple();
|
||||
aut.GetAllExpressions()["Index"].SetGroup("");
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"string",
|
||||
"Name",
|
||||
_("Animation (by name)"),
|
||||
_("the animation played by the object using the name of the "
|
||||
"animation"),
|
||||
_("the animation"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.UseStandardParameters(
|
||||
"objectAnimationName", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Animation name")))
|
||||
.MarkAsSimple();
|
||||
aut.GetAllStrExpressions()["Name"].SetGroup("");
|
||||
|
||||
aut.AddScopedAction("PauseAnimation",
|
||||
_("Pause the animation"),
|
||||
_("Pause the animation of the object."),
|
||||
_("Pause the animation of _PARAM0_"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png",
|
||||
"res/actions/animation.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("PlayAnimation",
|
||||
_("Resume the animation"),
|
||||
_("Resume the animation of the object."),
|
||||
_("Resume the animation of _PARAM0_"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png",
|
||||
"res/actions/animation.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"SpeedScale",
|
||||
_("Animation speed scale"),
|
||||
_("the animation speed scale (1 = the default speed, >1 = faster and "
|
||||
"<1 = slower)"),
|
||||
_("the animation speed scale"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Speed scale")))
|
||||
.MarkAsSimple();
|
||||
aut.GetAllExpressions()["SpeedScale"].SetGroup("");
|
||||
|
||||
aut.AddScopedCondition("IsAnimationPaused",
|
||||
_("Animation paused"),
|
||||
_("Check if the animation of an object is paused."),
|
||||
_("The animation of _PARAM0_ is paused"),
|
||||
_("Animations and images"),
|
||||
"res/conditions/animation24.png",
|
||||
"res/conditions/animation.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedCondition("HasAnimationEnded",
|
||||
_("Animation finished"),
|
||||
_("Check if the animation being played by the Sprite object "
|
||||
"is finished."),
|
||||
_("The animation of _PARAM0_ is finished"),
|
||||
_("Animations and images"),
|
||||
"res/conditions/animation24.png",
|
||||
"res/conditions/animation.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"ElapsedTime",
|
||||
_("Animation elapsed time"),
|
||||
_("the elapsed time from the beginning of the animation (in seconds)"),
|
||||
_("the animation elapsed time"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Elapsed time (in seconds)")))
|
||||
.MarkAsAdvanced();
|
||||
aut.GetAllExpressions()["ElapsedTime"].SetGroup("");
|
||||
|
||||
aut.AddExpression(
|
||||
"Duration",
|
||||
_("Animation duration"),
|
||||
_("Return the current animation duration (in seconds)."),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior");
|
||||
}
|
||||
|
||||
} // namespace gd
|
116
Core/GDCore/Extensions/Builtin/Capabilities/EffectExtension.cpp
Normal file
116
Core/GDCore/Extensions/Builtin/Capabilities/EffectExtension.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("EffectCapability",
|
||||
_("Effect capability"),
|
||||
_("Apply visual effects to objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
|
||||
.SetIcon("res/actions/effect24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"EffectBehavior",
|
||||
_("Effect capability"),
|
||||
"Effect",
|
||||
_("Apply visual effects to objects."),
|
||||
"",
|
||||
"res/actions/effect24.png",
|
||||
"EffectBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddScopedAction("EnableEffect",
|
||||
_("Enable an object effect"),
|
||||
_("Enable an effect on the object"),
|
||||
_("Enable effect _PARAM2_ on _PARAM0_: _PARAM3_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("yesorno", _("Enable?"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("SetEffectDoubleParameter",
|
||||
_("Effect property (number)"),
|
||||
_("Change the value of a property of an effect.") + "\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of _PARAM0_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Property name"))
|
||||
.AddParameter("expression", _("New value"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("SetEffectStringParameter",
|
||||
_("Effect property (string)"),
|
||||
_("Change the value (string) of a property of an effect.") +
|
||||
"\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of _PARAM0_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Property name"))
|
||||
.AddParameter("string", _("New value"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("SetEffectBooleanParameter",
|
||||
_("Effect property (enable or disable)"),
|
||||
_("Enable or disable a property of an effect.") + "\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Enable _PARAM3_ for effect _PARAM2_ of _PARAM0_: _PARAM4_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Property name"))
|
||||
.AddParameter("yesorno", _("Enable this property"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedCondition("IsEffectEnabled",
|
||||
_("Effect is enabled"),
|
||||
_("Check if the effect on an object is enabled."),
|
||||
_("Effect _PARAM2_ of _PARAM0_ is enabled"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.MarkAsSimple();
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFlippableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("FlippableCapability",
|
||||
_("Flippable capability"),
|
||||
_("Flip objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
|
||||
.SetIcon("res/actions/effect24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"FlippableBehavior",
|
||||
_("Flippable capability"),
|
||||
"Flippable",
|
||||
_("Flip objects."),
|
||||
"",
|
||||
"res/actions/flipX24.png",
|
||||
"FlippableBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddScopedAction("FlipX",
|
||||
_("Flip the object horizontally"),
|
||||
_("Flip the object horizontally"),
|
||||
_("Flip horizontally _PARAM0_: _PARAM2_"),
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
"res/actions/flipX.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "FlippableBehavior")
|
||||
.AddParameter("yesorno", _("Activate flipping"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("FlipY",
|
||||
_("Flip the object vertically"),
|
||||
_("Flip the object vertically"),
|
||||
_("Flip vertically _PARAM0_: _PARAM2_"),
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
"res/actions/flipY.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "FlippableBehavior")
|
||||
.AddParameter("yesorno", _("Activate flipping"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedCondition("FlippedX",
|
||||
_("Horizontally flipped"),
|
||||
_("Check if the object is horizontally flipped"),
|
||||
_("_PARAM0_ is horizontally flipped"),
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
"res/actions/flipX.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "FlippableBehavior");
|
||||
|
||||
aut.AddScopedCondition("FlippedY",
|
||||
_("Vertically flipped"),
|
||||
_("Check if the object is vertically flipped"),
|
||||
_("_PARAM0_ is vertically flipped"),
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
"res/actions/flipY.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "FlippableBehavior");
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("OpacityCapability",
|
||||
_("Opacity capability"),
|
||||
_("Change the object opacity."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Opacity capability"))
|
||||
.SetIcon("res/actions/opacity24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Visibility"))
|
||||
.SetIcon("res/actions/opacity24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"OpacityBehavior",
|
||||
_("Opacity capability"),
|
||||
"Opacity",
|
||||
_("Change the object opacity."),
|
||||
"",
|
||||
"res/actions/opacity24.png",
|
||||
"OpacityBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"Value",
|
||||
_("Opacity"),
|
||||
_("the opacity of an object, between 0 (fully transparent) to 255 "
|
||||
"(opaque)"),
|
||||
_("the opacity"),
|
||||
_("Visibility"),
|
||||
"res/actions/opacity24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "OpacityBehavior")
|
||||
.UseStandardParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Opacity (0-255)")))
|
||||
.SetFunctionName("setOpacity")
|
||||
.SetGetter("getOpacity");
|
||||
aut.GetAllExpressions()["Value"].SetGroup("");
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsResizableExtension(
|
||||
gd::PlatformExtension &extension) {
|
||||
extension
|
||||
.SetExtensionInformation("ResizableCapability",
|
||||
_("Resizable capability"),
|
||||
_("Change the object dimensions."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Size")).SetIcon(
|
||||
"res/actions/scale24_black.png");
|
||||
|
||||
gd::BehaviorMetadata &aut =
|
||||
extension
|
||||
.AddBehavior("ResizableBehavior",
|
||||
_("Resizable capability"),
|
||||
"Resizable",
|
||||
_("Change the object dimensions."),
|
||||
"",
|
||||
"res/actions/scale24_black.png",
|
||||
"ResizableBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddScopedAction("SetWidth",
|
||||
_("Width"),
|
||||
_("Change the width of the object."),
|
||||
_("the width"),
|
||||
_("Size"),
|
||||
"res/actions/scaleWidth24_black.png",
|
||||
"res/actions/scaleWidth_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(_("Width")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddScopedCondition("Width",
|
||||
_("Width"),
|
||||
_("Compare the width of the object."),
|
||||
_("the width"),
|
||||
_("Size"),
|
||||
"res/conditions/scaleWidth24_black.png",
|
||||
"res/conditions/scaleWidth_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(_("Width")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddScopedAction("SetHeight",
|
||||
_("Height"),
|
||||
_("Change the height of the object."),
|
||||
_("the height"),
|
||||
_("Size"),
|
||||
"res/actions/scaleHeight24_black.png",
|
||||
"res/actions/scaleHeight_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(_("Height")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddScopedCondition("Height",
|
||||
_("Height"),
|
||||
_("Compare the height of the object."),
|
||||
_("the height"),
|
||||
_("Size"),
|
||||
"res/conditions/scaleHeight24_black.png",
|
||||
"res/conditions/scaleHeight_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(_("Height")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddScopedAction(
|
||||
"SetSize",
|
||||
_("Size"),
|
||||
_("Change the size of an object."),
|
||||
_("Change the size of _PARAM0_: set to _PARAM2_ x _PARAM3_"),
|
||||
_("Size"),
|
||||
"res/actions/scale24_black.png",
|
||||
"res/actions/scale_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
|
||||
.AddParameter("expression", _("Width"))
|
||||
.AddParameter("expression", _("Height"))
|
||||
.MarkAsAdvanced();
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("ScalableCapability",
|
||||
_("Scalable capability"),
|
||||
_("Change the object scale."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Scalable capability"))
|
||||
.SetIcon("res/actions/scale24_black.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Size"))
|
||||
.SetIcon("res/actions/scale24_black.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"ScalableBehavior",
|
||||
_("Scalable capability"),
|
||||
"Scale",
|
||||
_("Change the object scale."),
|
||||
"",
|
||||
"res/actions/scale24_black.png",
|
||||
"ResizableBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"Value",
|
||||
_("Scale"),
|
||||
_("the scale of the object (default scale is 1)"),
|
||||
_("the scale"),
|
||||
_("Size"),
|
||||
"res/actions/scale24_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ScalableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
aut.GetAllExpressions()["Value"].SetGroup("");
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"X",
|
||||
_("Scale on X axis"),
|
||||
_("the scale on X axis of the object (default scale is 1)"),
|
||||
_("the scale on X axis"),
|
||||
_("Size"),
|
||||
"res/actions/scaleWidth24_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ScalableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
aut.GetAllExpressions()["X"].SetGroup("");
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"Y",
|
||||
_("Scale on Y axis"),
|
||||
_("the scale on Y axis of the object (default scale is 1)"),
|
||||
_("the scale on Y axis"),
|
||||
_("Size"),
|
||||
"res/actions/scaleHeight24_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ScalableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
aut.GetAllExpressions()["Y"].SetGroup("");
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTextContainerExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("TextContainerCapability",
|
||||
_("Text capability"),
|
||||
_("Animate objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Text capability"))
|
||||
.SetIcon("res/conditions/text24_black.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"TextContainerBehavior",
|
||||
_("Text capability"),
|
||||
"Text",
|
||||
_("Access objects text."),
|
||||
"",
|
||||
"res/conditions/text24_black.png",
|
||||
"TextContainerBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"string",
|
||||
"Value",
|
||||
_("Text"),
|
||||
_("the text"),
|
||||
_("the text"),
|
||||
"",
|
||||
"res/conditions/text24_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "TextContainerBehavior")
|
||||
.UseStandardParameters(
|
||||
"string", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Text")))
|
||||
.MarkAsSimple();
|
||||
aut.GetAllStrExpressions()["Value"].SetGroup("");
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -35,6 +35,8 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
.AddInstructionOrExpressionGroupMetadata(_("Events and control flow"))
|
||||
.SetIcon("res/conditions/toujours24_black.png");
|
||||
|
||||
// This condition is deprecated as this does not bring anything new
|
||||
// and can be confusing or misleading for beginners.
|
||||
extension
|
||||
.AddCondition("Always",
|
||||
_("Always"),
|
||||
@@ -46,7 +48,8 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
"res/conditions/toujours_black.png")
|
||||
.SetHelpPath("/all-features/advanced-conditions")
|
||||
.AddCodeOnlyParameter("conditionInverted", "")
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Compatibility with GD <= 5.0.127
|
||||
extension
|
||||
@@ -114,8 +117,9 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
|
||||
// Compatibility with GD <= 5.0.127
|
||||
extension
|
||||
.AddDuplicatedCondition(
|
||||
"Egal", "BuiltinCommonInstructions::CompareNumbers", {.unscoped = true})
|
||||
.AddDuplicatedCondition("Egal",
|
||||
"BuiltinCommonInstructions::CompareNumbers",
|
||||
{.unscoped = true})
|
||||
.SetHidden();
|
||||
// end of compatibility code
|
||||
|
||||
@@ -135,8 +139,9 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
|
||||
// Compatibility with GD <= 5.0.127
|
||||
extension
|
||||
.AddDuplicatedCondition(
|
||||
"StrEqual", "BuiltinCommonInstructions::CompareStrings", {.unscoped = true})
|
||||
.AddDuplicatedCondition("StrEqual",
|
||||
"BuiltinCommonInstructions::CompareStrings",
|
||||
{.unscoped = true})
|
||||
.SetHidden();
|
||||
// end of compatibility code
|
||||
|
||||
|
@@ -38,6 +38,8 @@ BuiltinExtensionsImplementer::ImplementsExternalLayoutsExtension(
|
||||
.SetDefaultValue("0")
|
||||
.AddParameter("expression", _("Y position of the origin"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.AddParameter("expression", _("Z position of the origin"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
}
|
||||
|
||||
|
@@ -69,12 +69,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
extension
|
||||
.AddAction(
|
||||
"EcrireFichierExp",
|
||||
_("Write a value"),
|
||||
_("Write the result of the expression in the stored data, in the "
|
||||
_("Save a value"),
|
||||
_("Save the result of the expression in the stored data, in the "
|
||||
"specified element.\nSpecify the structure leading to the "
|
||||
"element using / (example : Root/Level/Current)\nSpaces are "
|
||||
"forbidden in element names."),
|
||||
_("Write _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
|
||||
_("Save _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
|
||||
"",
|
||||
"res/actions/fichier24.png",
|
||||
"res/actions/fichier.png")
|
||||
@@ -85,12 +85,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
extension
|
||||
.AddAction(
|
||||
"EcrireFichierTxt",
|
||||
_("Write a text"),
|
||||
_("Write the text in the specified storage, in the specified "
|
||||
_("Save a text"),
|
||||
_("Save the text in the specified storage, in the specified "
|
||||
"element.\nSpecify "
|
||||
"the structure leading to the element using / (example : "
|
||||
"Root/Level/Current)\nSpaces are forbidden in element names."),
|
||||
_("Write _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
|
||||
_("Save _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
|
||||
"",
|
||||
"res/actions/fichier24.png",
|
||||
"res/actions/fichier.png")
|
||||
@@ -101,13 +101,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
extension
|
||||
.AddAction(
|
||||
"LireFichierExp",
|
||||
_("Read a value"),
|
||||
_("Read the value saved in the specified element and store it in a "
|
||||
_("Load a value"),
|
||||
_("Load the value saved in the specified element and store it in a "
|
||||
"scene "
|
||||
"variable.\nSpecify the structure leading to the element using / "
|
||||
"(example : Root/Level/Current)\nSpaces are forbidden in element "
|
||||
"names."),
|
||||
_("Read _PARAM1_ from storage _PARAM0_ and store value in _PARAM3_"),
|
||||
_("Load _PARAM1_ from storage _PARAM0_ and store value in _PARAM3_"),
|
||||
"",
|
||||
"res/actions/fichier24.png",
|
||||
"res/actions/fichier.png")
|
||||
@@ -119,13 +119,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
extension
|
||||
.AddAction(
|
||||
"LireFichierTxt",
|
||||
_("Read a text"),
|
||||
_("Read the text saved in the specified element and store it in a "
|
||||
_("Load a text"),
|
||||
_("Load the text saved in the specified element and store it in a "
|
||||
"scene "
|
||||
"variable.\nSpecify the structure leading to the element using / "
|
||||
"(example : Root/Level/Current)\nSpaces are forbidden in element "
|
||||
"names."),
|
||||
_("Read _PARAM1_ from storage _PARAM0_ and store as text in "
|
||||
_("Load _PARAM1_ from storage _PARAM0_ and store as text in "
|
||||
"_PARAM3_"),
|
||||
"",
|
||||
"res/actions/fichier24.png",
|
||||
|
@@ -163,7 +163,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
"res/conditions/mouse24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
@@ -185,7 +185,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
"res/conditions/mouse24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
@@ -206,7 +206,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
"res/conditions/mouse24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -223,7 +223,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
"res/conditions/mouse24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -317,7 +317,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Touch identifier"))
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
@@ -333,7 +333,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Touch identifier"))
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
@@ -48,7 +48,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
|
||||
.AddParameter("string", "Content type", "", true)
|
||||
.SetParameterLongDescription(
|
||||
"If empty, \"application/x-www-form-urlencoded\" will be used.")
|
||||
.AddParameter("scenevar", "Reponse scene variable", "", true)
|
||||
.AddParameter("scenevar", "Response scene variable", "", true)
|
||||
.SetParameterLongDescription(
|
||||
"The response of the server will be stored, as a string, in this "
|
||||
"variable. If the server returns *JSON*, you may want to use the "
|
||||
|
@@ -54,6 +54,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.MarkAsSimple();
|
||||
|
||||
extension
|
||||
.AddCondition("DoesSceneExist",
|
||||
_("Does scene exist"),
|
||||
_("Check if scene exists."),
|
||||
_("Scene _PARAM1_ exists"),
|
||||
"",
|
||||
"res/actions/texte.png",
|
||||
"res/actions/texte.png")
|
||||
.SetHelpPath("/interface/scene-editor/events")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("sceneName", _("Name of the scene to check"))
|
||||
.MarkAsSimple();
|
||||
|
||||
extension
|
||||
.AddAction("Scene",
|
||||
_("Change the scene"),
|
||||
|
@@ -110,11 +110,11 @@ void Direction::UnserializeFrom(const gd::SerializerElement& element) {
|
||||
.GetBoolAttribute("automatic", true));
|
||||
|
||||
if (spriteElement.HasChild("CustomCollisionMask"))
|
||||
sprite.SetCollisionMaskAutomatic(
|
||||
sprite.SetFullImageCollisionMask(
|
||||
!spriteElement.GetChild("CustomCollisionMask")
|
||||
.GetBoolAttribute("custom", false));
|
||||
else
|
||||
sprite.SetCollisionMaskAutomatic(
|
||||
sprite.SetFullImageCollisionMask(
|
||||
!spriteElement.GetBoolAttribute("hasCustomCollisionMask", false));
|
||||
|
||||
std::vector<Polygon2d> mask;
|
||||
@@ -173,7 +173,7 @@ void SaveSpritesDirection(const vector<Sprite>& sprites,
|
||||
.SetAttribute("automatic", sprites[i].IsDefaultCenterPoint());
|
||||
|
||||
spriteElement.SetAttribute("hasCustomCollisionMask",
|
||||
!sprites[i].IsCollisionMaskAutomatic());
|
||||
!sprites[i].IsFullImageCollisionMask());
|
||||
|
||||
gd::SerializerElement& collisionMaskElement =
|
||||
spriteElement.AddChild("customCollisionMask");
|
||||
|
@@ -4,7 +4,9 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -14,11 +16,10 @@ namespace gd {
|
||||
Point Sprite::badPoint("");
|
||||
|
||||
Sprite::Sprite()
|
||||
: automaticCollisionMask(true),
|
||||
: fullImageCollisionMask(false),
|
||||
origine("origine"),
|
||||
centre("centre"),
|
||||
automaticCentre(true) {
|
||||
}
|
||||
automaticCentre(true) {}
|
||||
|
||||
Sprite::~Sprite(){};
|
||||
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#ifndef SPRITE_H
|
||||
#define SPRITE_H
|
||||
#include <memory>
|
||||
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Point.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -43,7 +44,7 @@ class GD_CORE_API Sprite {
|
||||
|
||||
/**
|
||||
* \brief Get the collision mask (custom or automatically generated owing to
|
||||
* IsCollisionMaskAutomatic())
|
||||
* IsFullImageCollisionMask())
|
||||
*
|
||||
* \warning If the image has not been loaded ( using LoadImage ) and the
|
||||
* collision mask is set as automatic, the returned mask won't be correct.
|
||||
@@ -66,7 +67,7 @@ class GD_CORE_API Sprite {
|
||||
|
||||
/**
|
||||
* \brief Set the custom collision mask.
|
||||
* Call then `SetCollisionMaskAutomatic(false)` to use it.
|
||||
* Call then `SetFullImageCollisionMask(false)` to use it.
|
||||
*/
|
||||
void SetCustomCollisionMask(const std::vector<Polygon2d>& collisionMask);
|
||||
|
||||
@@ -74,15 +75,15 @@ class GD_CORE_API Sprite {
|
||||
* \brief Return true if the collision mask is a bounding box, false if a
|
||||
* custom collision mask is used.
|
||||
*/
|
||||
inline bool IsCollisionMaskAutomatic() const {
|
||||
return automaticCollisionMask;
|
||||
inline bool IsFullImageCollisionMask() const {
|
||||
return fullImageCollisionMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Un/set use of the custom collision mask.
|
||||
*/
|
||||
inline void SetCollisionMaskAutomatic(bool enabled) {
|
||||
automaticCollisionMask = enabled;
|
||||
inline void SetFullImageCollisionMask(bool enabled) {
|
||||
fullImageCollisionMask = enabled;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -161,9 +162,9 @@ class GD_CORE_API Sprite {
|
||||
private:
|
||||
gd::String image; ///< Name of the image to be loaded in Image Manager.
|
||||
|
||||
bool automaticCollisionMask; ///< True to use the custom collision mask.
|
||||
///< Otherwise, a basic bounding box is returned
|
||||
///< by GetCollisionMask()
|
||||
bool fullImageCollisionMask; ///< True to use a bounding box wrapping the
|
||||
///< whole image as collision mask. If false,
|
||||
///< custom collision mask is used.
|
||||
std::vector<Polygon2d> customCollisionMask; ///< Custom collision mask
|
||||
|
||||
std::vector<Point> points; ///< List of the points used by the sprite
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* LicenFse.
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
@@ -30,10 +30,17 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddObject<SpriteObject>("Sprite",
|
||||
_("Sprite"),
|
||||
_("Animated object which can be used for "
|
||||
"most elements of a game"),
|
||||
"most elements of a game."),
|
||||
"CppPlatform/Extensions/spriteicon.png")
|
||||
.SetCategoryFullName(_("General"));
|
||||
.SetCategoryFullName(_("General"))
|
||||
.AddDefaultBehavior("EffectCapability::EffectBehavior")
|
||||
.AddDefaultBehavior("ResizableCapability::ResizableBehavior")
|
||||
.AddDefaultBehavior("ScalableCapability::ScalableBehavior")
|
||||
.AddDefaultBehavior("FlippableCapability::FlippableBehavior")
|
||||
.AddDefaultBehavior("OpacityCapability::OpacityBehavior")
|
||||
.AddDefaultBehavior("AnimatableCapability::AnimatableBehavior");
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("Opacity",
|
||||
_("Sprite opacity"),
|
||||
_("Change the opacity of a Sprite. 0 is fully transparent, 255 "
|
||||
@@ -48,8 +55,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Opacity (0-255)")))
|
||||
.MarkAsSimple();
|
||||
.MarkAsSimple()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("ChangeAnimation",
|
||||
_("Change the animation"),
|
||||
_("Change the animation of the object, using the animation "
|
||||
@@ -62,8 +71,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardOperatorParameters("number",
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("SetAnimationName",
|
||||
_("Change the animation (by name)"),
|
||||
_("Change the animation of the object, using the name of the "
|
||||
@@ -75,6 +86,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("objectAnimationName", _("Animation name"))
|
||||
.SetHidden()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddAction(
|
||||
@@ -107,6 +119,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("PauseAnimation",
|
||||
_("Pause the animation"),
|
||||
_("Pause the animation of the object"),
|
||||
@@ -116,8 +129,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"res/actions/animation.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("PlayAnimation",
|
||||
_("Play the animation"),
|
||||
_("Play the animation of the object"),
|
||||
@@ -127,8 +142,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"res/actions/animation.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction(
|
||||
"ChangeAnimationSpeedScale",
|
||||
_("Animation speed scale"),
|
||||
@@ -143,8 +160,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(_("Speed scale")))
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("TourneVersPos",
|
||||
"Rotate an object toward a position",
|
||||
"Rotate an object towards a position.",
|
||||
@@ -159,8 +178,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("expression", _("Angular speed (degrees per second)"))
|
||||
.SetDefaultValue("0")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.SetHidden(); // Deprecated
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("ChangeScale",
|
||||
_("Scale"),
|
||||
_("Modify the scale of the specified object."),
|
||||
@@ -174,8 +194,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("ChangeScaleWidth",
|
||||
_("Scale on X axis"),
|
||||
_("Modify the scale of the width of an object."),
|
||||
@@ -189,8 +211,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("ChangeScaleHeight",
|
||||
_("Scale on Y axis"),
|
||||
_("Modify the scale of the height of an object."),
|
||||
@@ -204,8 +228,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("ChangeWidth",
|
||||
_("Width"),
|
||||
_("Change the width of a Sprite object."),
|
||||
@@ -217,8 +243,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardOperatorParameters("number",
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("Width",
|
||||
_("Width"),
|
||||
_("Compare the width of a Sprite object."),
|
||||
@@ -230,8 +258,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("ChangeHeight",
|
||||
_("Height"),
|
||||
_("Change the height of a Sprite object."),
|
||||
@@ -243,8 +273,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardOperatorParameters("number",
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("Height",
|
||||
_("Height"),
|
||||
_("Compare the height of a Sprite object."),
|
||||
@@ -256,8 +288,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("SetSize",
|
||||
_("Size"),
|
||||
_("Change the size of an object."),
|
||||
@@ -269,8 +303,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Width"))
|
||||
.AddParameter("expression", _("Height"))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition(
|
||||
"Animation",
|
||||
_("Current animation"),
|
||||
@@ -283,11 +319,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.SetHidden()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("AnimationName",
|
||||
_("Current animation name"),
|
||||
_("Check the animation by played by the object."),
|
||||
_("Check the animation played by the object."),
|
||||
_("The animation of _PARAM0_ is _PARAM1_"),
|
||||
_("Animations and images"),
|
||||
"res/conditions/animation24.png",
|
||||
@@ -295,6 +333,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("objectAnimationName", _("Animation name"))
|
||||
.SetHidden()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddCondition(
|
||||
@@ -328,6 +367,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("AnimStopped",
|
||||
_("Animation paused"),
|
||||
_("Check if the animation of an object is paused."),
|
||||
@@ -337,8 +377,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"res/conditions/animation.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("AnimationEnded",
|
||||
_("Animation finished"),
|
||||
_("Check if the animation being played by the Sprite object "
|
||||
@@ -352,6 +394,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.MarkAsSimple()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("AnimationEnded2",
|
||||
_("Animation finished"),
|
||||
_("Check if the animation being played by the Sprite object "
|
||||
@@ -362,8 +405,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"res/conditions/animation.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("ScaleWidth",
|
||||
_("Scale on X axis"),
|
||||
_("Compare the scale of the width of an object."),
|
||||
@@ -371,7 +416,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Size"),
|
||||
"res/conditions/scaleWidth24_black.png",
|
||||
"res/conditions/scaleWidth_black.png")
|
||||
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
@@ -379,6 +424,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("ScaleHeight",
|
||||
_("Scale on Y axis"),
|
||||
_("Compare the scale of the height of an object."),
|
||||
@@ -386,7 +432,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Size"),
|
||||
"res/conditions/scaleHeight24_black.png",
|
||||
"res/conditions/scaleHeight_black.png")
|
||||
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
@@ -394,6 +440,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("Opacity",
|
||||
_("Opacity"),
|
||||
_("Compare the opacity of a Sprite, between 0 (fully "
|
||||
@@ -408,7 +455,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Opacity to compare to (0-255)")))
|
||||
.MarkAsSimple();
|
||||
.MarkAsSimple()
|
||||
.SetHidden();
|
||||
|
||||
obj.AddCondition(
|
||||
"BlendMode",
|
||||
@@ -456,9 +504,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
"res/actions/flipX.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("yesorno", _("Activate flipping"))
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
obj.AddAction("FlipY",
|
||||
@@ -468,9 +516,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
"res/actions/flipY.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("yesorno", _("Activate flipping"))
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
obj.AddCondition("FlippedX",
|
||||
@@ -480,8 +528,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
"res/actions/flipX.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden();
|
||||
|
||||
obj.AddCondition("FlippedY",
|
||||
_("Vertically flipped"),
|
||||
@@ -490,9 +538,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
"res/actions/flipY.png")
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden();
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("TourneVers",
|
||||
"Rotate an object toward another",
|
||||
"Rotate an object towards another.",
|
||||
@@ -504,7 +553,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("objectPtr", "Rotate toward this object")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.SetHidden(); // Deprecated
|
||||
.SetHidden();
|
||||
|
||||
obj.AddExpression("X",
|
||||
_("X position of a point"),
|
||||
@@ -542,6 +591,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("objectPointName", _("Name of the point"));
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Direc",
|
||||
_("Direction"),
|
||||
_("Direction of the object"),
|
||||
@@ -550,6 +600,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Direction",
|
||||
_("Direction"),
|
||||
_("Direction of the object"),
|
||||
@@ -559,6 +610,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
// interface.
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Anim",
|
||||
_("Animation"),
|
||||
_("Animation of the object"),
|
||||
@@ -567,18 +619,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Animation",
|
||||
_("Animation"),
|
||||
_("Animation of the object"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation.png")
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddStrExpression("AnimationName",
|
||||
_("Animation name"),
|
||||
_("Name of the animation of the object"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation.png")
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
obj.AddExpression("Sprite",
|
||||
@@ -595,11 +651,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"res/actions/sprite.png")
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("AnimationSpeedScale",
|
||||
_("Animation speed scale"),
|
||||
_("Animation speed scale"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation.png")
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
obj.AddExpression("ScaleX",
|
||||
@@ -607,6 +665,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Scale of the width of an object"),
|
||||
_("Size"),
|
||||
"res/actions/scaleWidth_black.png")
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
obj.AddExpression("ScaleY",
|
||||
@@ -614,14 +673,17 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Scale of the height of an object"),
|
||||
_("Size"),
|
||||
"res/actions/scaleHeight_black.png")
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Opacity",
|
||||
_("Opacity"),
|
||||
_("Opacity"),
|
||||
_("Opacity"),
|
||||
"res/actions/opacity.png")
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden();
|
||||
|
||||
extension
|
||||
.AddCondition("Collision",
|
||||
|
@@ -25,13 +25,16 @@ namespace gd {
|
||||
|
||||
Animation SpriteObject::badAnimation;
|
||||
|
||||
SpriteObject::SpriteObject() : updateIfNotVisible(false) {}
|
||||
SpriteObject::SpriteObject()
|
||||
: updateIfNotVisible(false), adaptCollisionMaskAutomatically(true) {}
|
||||
|
||||
SpriteObject::~SpriteObject(){};
|
||||
|
||||
void SpriteObject::DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) {
|
||||
updateIfNotVisible = element.GetBoolAttribute("updateIfNotVisible", true);
|
||||
adaptCollisionMaskAutomatically =
|
||||
element.GetBoolAttribute("adaptCollisionMaskAutomatically", false);
|
||||
|
||||
RemoveAllAnimations();
|
||||
const gd::SerializerElement& animationsElement =
|
||||
@@ -80,6 +83,8 @@ void SpriteObject::DoUnserializeFrom(gd::Project& project,
|
||||
|
||||
void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
element.SetAttribute("updateIfNotVisible", updateIfNotVisible);
|
||||
element.SetAttribute("adaptCollisionMaskAutomatically",
|
||||
adaptCollisionMaskAutomatically);
|
||||
|
||||
// Animations
|
||||
gd::SerializerElement& animationsElement = element.AddChild("animations");
|
||||
|
@@ -47,8 +47,7 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
void ExposeResources(gd::ArbitraryResourceWorker& worker) override;
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
|
||||
bool UpdateProperty(const gd::String& name,
|
||||
const gd::String& value) override;
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) override;
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties(
|
||||
const gd::InitialInstance& position,
|
||||
@@ -118,14 +117,30 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
const std::vector<Animation>& GetAllAnimations() const { return animations; }
|
||||
|
||||
/**
|
||||
* \brief Set if the object animation should be played even if the object is hidden
|
||||
* or far from the camera.
|
||||
* @brief Check if the collision mask adapts automatically to the animation.
|
||||
*/
|
||||
void SetUpdateIfNotVisible(bool updateIfNotVisible_) { updateIfNotVisible = updateIfNotVisible_; }
|
||||
bool AdaptCollisionMaskAutomatically() const {
|
||||
return adaptCollisionMaskAutomatically;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if the object animation should be played even if the object is hidden
|
||||
* or far from the camera (false by default).
|
||||
* @brief Set if the collision mask adapts automatically to the animation.
|
||||
*/
|
||||
void SetAdaptCollisionMaskAutomatically(bool enable) {
|
||||
adaptCollisionMaskAutomatically = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set if the object animation should be played even if the object is
|
||||
* hidden or far from the camera.
|
||||
*/
|
||||
void SetUpdateIfNotVisible(bool updateIfNotVisible_) {
|
||||
updateIfNotVisible = updateIfNotVisible_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if the object animation should be played even if the object
|
||||
* is hidden or far from the camera (false by default).
|
||||
*/
|
||||
bool GetUpdateIfNotVisible() const { return updateIfNotVisible; }
|
||||
///@}
|
||||
@@ -137,11 +152,15 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
|
||||
mutable std::vector<Animation> animations;
|
||||
bool updateIfNotVisible; ///< If set to true, ask the game engine to play
|
||||
///< object animation even if hidden or far from the
|
||||
///< screen.
|
||||
///< object animation even if hidden or far from
|
||||
///< the screen.
|
||||
|
||||
static Animation badAnimation; //< Bad animation when an out of bound
|
||||
// animation is requested.
|
||||
static Animation badAnimation; //< Bad animation when an out of bound
|
||||
// animation is requested.
|
||||
bool adaptCollisionMaskAutomatically; ///< If set to true, the collision
|
||||
///< mask will be automatically
|
||||
///< adapted to the animation of the
|
||||
///< object.
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -126,8 +126,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
|
||||
extension
|
||||
.AddExpression(
|
||||
"StrFindLast",
|
||||
_("Search the last occurence in a text"),
|
||||
_("Search the last occurence in a string (return the position of "
|
||||
_("Search the last occurrence in a text"),
|
||||
_("Search the last occurrence in a string (return the position of "
|
||||
"the result, from the beginning of the string, or -1 if not "
|
||||
"found)"),
|
||||
"",
|
||||
@@ -169,10 +169,10 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
|
||||
extension
|
||||
.AddExpression(
|
||||
"StrFindLastFrom",
|
||||
_("Search the last occurence in a text, starting from a position"),
|
||||
_("Search in a text the last occurence, starting from a position "
|
||||
_("Search the last occurrence in a text, starting from a position"),
|
||||
_("Search in a text the last occurrence, starting from a position "
|
||||
"(return "
|
||||
" the position of the result, from the beginning of the string, or "
|
||||
"the position of the result, from the beginning of the string, or "
|
||||
"-1 if not found)"),
|
||||
"",
|
||||
"res/conditions/toujours24_black.png")
|
||||
|
@@ -87,8 +87,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
|
||||
extension
|
||||
.AddAction(
|
||||
"SetWindowSize",
|
||||
_("Change the size of the game window"),
|
||||
_("This action changes the size of the game window. Note that this "
|
||||
_("Game window size"),
|
||||
_("Changes the size of the game window. Note that this "
|
||||
"will only work on platform supporting this operation: games "
|
||||
"running in browsers or on mobile phones can not update their "
|
||||
"window size. Game resolution can still be updated."),
|
||||
|
135
Core/GDCore/Extensions/Metadata/AbstractFunctionMetadata.h
Normal file
135
Core/GDCore/Extensions/Metadata/AbstractFunctionMetadata.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "ParameterMetadata.h"
|
||||
#include "ParameterOptions.h"
|
||||
|
||||
namespace gd {
|
||||
class Project;
|
||||
class Layout;
|
||||
class EventsCodeGenerator;
|
||||
class EventsCodeGenerationContext;
|
||||
class SerializerElement;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Describe user-friendly information about an expression or an
|
||||
* instruction (action or condition), its parameters and the function name as
|
||||
* well as other information for code generation.
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API AbstractFunctionMetadata {
|
||||
public:
|
||||
AbstractFunctionMetadata(){};
|
||||
virtual ~AbstractFunctionMetadata(){};
|
||||
|
||||
/**
|
||||
* \see gd::InstructionMetadata::AddParameter
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &
|
||||
AddParameter(const gd::String &type, const gd::String &label,
|
||||
const gd::String &supplementaryInformation = "",
|
||||
bool parameterIsOptional = false) = 0;
|
||||
|
||||
/**
|
||||
* \see gd::InstructionMetadata::AddCodeOnlyParameter
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &
|
||||
AddCodeOnlyParameter(const gd::String &type,
|
||||
const gd::String &supplementaryInformation) = 0;
|
||||
|
||||
/**
|
||||
* \see gd::InstructionMetadata::SetDefaultValue
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &
|
||||
SetDefaultValue(const gd::String &defaultValue) = 0;
|
||||
|
||||
/**
|
||||
* \see gd::InstructionMetadata::SetParameterExtraInfo
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &
|
||||
SetParameterExtraInfo(const gd::String &defaultValue) = 0;
|
||||
|
||||
/**
|
||||
* \see gd::InstructionMetadata::SetParameterLongDescription
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &
|
||||
SetParameterLongDescription(const gd::String &longDescription) = 0;
|
||||
|
||||
/**
|
||||
* \see gd::InstructionMetadata::SetHidden
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &SetHidden() = 0;
|
||||
|
||||
/**
|
||||
* Set that the instruction is private - it can't be used outside of the
|
||||
* object/ behavior that it is attached too.
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &SetPrivate() = 0;
|
||||
|
||||
/**
|
||||
* Set that the instruction can be used in layouts or external events.
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &SetRelevantForLayoutEventsOnly() = 0;
|
||||
|
||||
/**
|
||||
* Set that the instruction can be used in function events.
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &SetRelevantForFunctionEventsOnly() = 0;
|
||||
|
||||
/**
|
||||
* Set that the instruction can be used in asynchronous function events.
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &
|
||||
SetRelevantForAsynchronousFunctionEventsOnly() = 0;
|
||||
|
||||
/**
|
||||
* Set that the instruction can be used in custom object events.
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &SetRelevantForCustomObjectEventsOnly() = 0;
|
||||
|
||||
/**
|
||||
* \brief Set the function that should be called when generating the source
|
||||
* code from events.
|
||||
* \param functionName the name of the function to call
|
||||
* \note Shortcut for `codeExtraInformation.SetFunctionName`.
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &
|
||||
SetFunctionName(const gd::String &functionName) = 0;
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &
|
||||
SetIncludeFile(const gd::String &includeFile) = 0;
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &
|
||||
AddIncludeFile(const gd::String &includeFile) = 0;
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
virtual const std::vector<gd::String> &GetIncludeFiles() const = 0;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -34,8 +34,7 @@ BehaviorMetadata::BehaviorMetadata(
|
||||
className(className_),
|
||||
iconFilename(icon24x24),
|
||||
instance(instance_),
|
||||
sharedDatasInstance(sharedDatasInstance_),
|
||||
isEventBased(false) {
|
||||
sharedDatasInstance(sharedDatasInstance_) {
|
||||
SetFullName(gd::String(fullname_));
|
||||
SetDescription(gd::String(description_));
|
||||
SetDefaultName(gd::String(defaultName_));
|
||||
@@ -52,29 +51,6 @@ BehaviorMetadata::BehaviorMetadata(
|
||||
if (sharedDatasInstance) sharedDatasInstance->SetTypeName(nameWithNamespace);
|
||||
}
|
||||
|
||||
BehaviorMetadata::BehaviorMetadata(
|
||||
const gd::String& extensionNamespace,
|
||||
const gd::String& nameWithNamespace,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& defaultName_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon24x24_): BehaviorMetadata(
|
||||
extensionNamespace,
|
||||
nameWithNamespace,
|
||||
fullname_,
|
||||
defaultName_,
|
||||
description_,
|
||||
group_,
|
||||
icon24x24_,
|
||||
// Class name is the name, actually unused
|
||||
defaultName_,
|
||||
// It is only used to get the name for GetName.
|
||||
gd::make_unique<gd::Behavior>("", nameWithNamespace),
|
||||
nullptr){
|
||||
isEventBased = true;
|
||||
};
|
||||
|
||||
gd::InstructionMetadata& BehaviorMetadata::AddCondition(
|
||||
const gd::String& name,
|
||||
const gd::String& fullname,
|
||||
@@ -420,10 +396,6 @@ const gd::String& BehaviorMetadata::GetName() const {
|
||||
}
|
||||
|
||||
gd::Behavior& BehaviorMetadata::Get() const {
|
||||
if (isEventBased) {
|
||||
gd::LogFatalError("Error: Event-based behaviors don't have blueprint. "
|
||||
"This method should not never be called.");
|
||||
}
|
||||
if (!instance) {
|
||||
gd::LogFatalError(
|
||||
"Trying to get a behavior from a BehaviorMetadata that has no "
|
||||
@@ -434,11 +406,20 @@ gd::Behavior& BehaviorMetadata::Get() const {
|
||||
}
|
||||
|
||||
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
|
||||
if (isEventBased) {
|
||||
gd::LogFatalError("Error: Event-based behaviors don't have blueprint. "
|
||||
"This method should not never be called.");
|
||||
}
|
||||
return sharedDatasInstance.get();
|
||||
}
|
||||
|
||||
const std::vector<gd::String>& BehaviorMetadata::GetRequiredBehaviorTypes() const {
|
||||
requiredBehaviors.clear();
|
||||
for (auto& property : Get().GetProperties()) {
|
||||
const String& propertyName = property.first;
|
||||
const gd::PropertyDescriptor& propertyDescriptor = property.second;
|
||||
|
||||
if (propertyDescriptor.GetType() == "Behavior") {
|
||||
requiredBehaviors.push_back(propertyDescriptor.GetExtraInfo()[0]);
|
||||
}
|
||||
}
|
||||
return requiredBehaviors;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -3,8 +3,10 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef BEHAVIORMETADATA_H
|
||||
#define BEHAVIORMETADATA_H
|
||||
#pragma once
|
||||
|
||||
#include "InstructionOrExpressionContainerMetadata.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
@@ -25,7 +27,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API BehaviorMetadata {
|
||||
class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMetadata {
|
||||
public:
|
||||
BehaviorMetadata(
|
||||
const gd::String& extensionNamespace,
|
||||
@@ -67,7 +69,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* Declare a new action as being part of the behavior.
|
||||
@@ -80,7 +82,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* Declare a new condition as being part of the behavior.
|
||||
@@ -91,7 +93,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* Declare a new action as being part of the behavior.
|
||||
@@ -102,7 +104,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
/**
|
||||
* Declare a new action as being part of the extension.
|
||||
*/
|
||||
@@ -110,7 +112,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* Declare a new string expression as being part of the extension.
|
||||
@@ -119,7 +121,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression and condition as being part of the
|
||||
@@ -134,7 +136,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& description,
|
||||
const gd::String& sentenceName,
|
||||
const gd::String& group,
|
||||
const gd::String& icon);
|
||||
const gd::String& icon) override;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression, condition and action as being part of the
|
||||
@@ -151,7 +153,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& description,
|
||||
const gd::String& sentenceName,
|
||||
const gd::String& group,
|
||||
const gd::String& icon);
|
||||
const gd::String& icon) override;
|
||||
|
||||
/**
|
||||
* \brief Create a new action which is the duplicate of the specified one.
|
||||
@@ -160,7 +162,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
* one.
|
||||
*/
|
||||
gd::InstructionMetadata& AddDuplicatedAction(
|
||||
const gd::String& newActionName, const gd::String& copiedActionName);
|
||||
const gd::String& newActionName, const gd::String& copiedActionName) override;
|
||||
|
||||
/**
|
||||
* \brief Create a new condition which is the duplicate of the specified one.
|
||||
@@ -170,7 +172,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
*/
|
||||
gd::InstructionMetadata& AddDuplicatedCondition(
|
||||
const gd::String& newConditionName,
|
||||
const gd::String& copiedConditionName);
|
||||
const gd::String& copiedConditionName) override;
|
||||
|
||||
/**
|
||||
* \brief Create a new expression which is the duplicate of the specified one.
|
||||
@@ -193,9 +195,9 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& newExpressionName,
|
||||
const gd::String& copiedExpressionName);
|
||||
|
||||
BehaviorMetadata& SetFullName(const gd::String& fullname_);
|
||||
BehaviorMetadata& SetFullName(const gd::String& fullname_) override;
|
||||
BehaviorMetadata& SetDefaultName(const gd::String& defaultName_);
|
||||
BehaviorMetadata& SetDescription(const gd::String& description_);
|
||||
BehaviorMetadata& SetDescription(const gd::String& description_) override;
|
||||
BehaviorMetadata& SetGroup(const gd::String& group_);
|
||||
|
||||
/**
|
||||
@@ -203,12 +205,12 @@ class GD_CORE_API BehaviorMetadata {
|
||||
* \note The requirement may vary depending on the platform: Most of the time,
|
||||
* the include file contains the declaration of the behavior.
|
||||
*/
|
||||
BehaviorMetadata& SetIncludeFile(const gd::String& includeFile);
|
||||
BehaviorMetadata& SetIncludeFile(const gd::String& includeFile) override;
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
BehaviorMetadata& AddIncludeFile(const gd::String& includeFile);
|
||||
BehaviorMetadata& AddIncludeFile(const gd::String& includeFile) override;
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing required files.
|
||||
@@ -221,7 +223,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
* Get the help path of the behavior, relative to the GDevelop documentation
|
||||
* root.
|
||||
*/
|
||||
const gd::String& GetHelpPath() const { return helpPath; }
|
||||
const gd::String& GetHelpPath() const override { return helpPath; }
|
||||
|
||||
/**
|
||||
* Set the help path of the behavior, relative to the GDevelop documentation
|
||||
@@ -230,17 +232,17 @@ class GD_CORE_API BehaviorMetadata {
|
||||
* The behavior instructions will have this help path set by
|
||||
* default, unless you call SetHelpPath on them.
|
||||
*/
|
||||
BehaviorMetadata& SetHelpPath(const gd::String& path) {
|
||||
BehaviorMetadata& SetHelpPath(const gd::String& path) override {
|
||||
helpPath = path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gd::String& GetName() const;
|
||||
const gd::String& GetFullName() const { return fullname; }
|
||||
const gd::String& GetName() const override;
|
||||
const gd::String& GetFullName() const override { return fullname; }
|
||||
const gd::String& GetDefaultName() const { return defaultName; }
|
||||
const gd::String& GetDescription() const { return description; }
|
||||
const gd::String& GetDescription() const override { return description; }
|
||||
const gd::String& GetGroup() const { return group; }
|
||||
const gd::String& GetIconFilename() const { return iconFilename; }
|
||||
const gd::String& GetIconFilename() const override { return iconFilename; }
|
||||
|
||||
/**
|
||||
* \brief Set the type of the object that this behavior can be used on.
|
||||
@@ -257,6 +259,11 @@ class GD_CORE_API BehaviorMetadata {
|
||||
*/
|
||||
const gd::String& GetObjectType() const { return objectType; }
|
||||
|
||||
/**
|
||||
* \brief Get the types of the behaviors that are required by this behavior.
|
||||
*/
|
||||
const std::vector<gd::String>& GetRequiredBehaviorTypes() const;
|
||||
|
||||
/**
|
||||
* Check if the behavior is private - it can't be used outside of its
|
||||
* extension.
|
||||
@@ -272,6 +279,21 @@ class GD_CORE_API BehaviorMetadata {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the behavior is hidden - it can be used but not attached to
|
||||
* objects by users.
|
||||
*/
|
||||
bool IsHidden() const { return isHidden; }
|
||||
|
||||
/**
|
||||
* Set that the behavior is hidden - it can be used but not attached to
|
||||
* objects by users.
|
||||
*/
|
||||
BehaviorMetadata &SetHidden() {
|
||||
isHidden = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the associated gd::Behavior, handling behavior contents.
|
||||
*
|
||||
@@ -293,22 +315,22 @@ class GD_CORE_API BehaviorMetadata {
|
||||
* \brief Return a reference to a map containing the names of the actions
|
||||
* (as keys) and the metadata associated with (as values).
|
||||
*/
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllActions() { return actionsInfos; };
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllActions() override { return actionsInfos; };
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllConditions() { return conditionsInfos; };
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllConditions() override { return conditionsInfos; };
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllExpressions() { return expressionsInfos; };
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllExpressions() override { return expressionsInfos; };
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() { return strExpressionsInfos; };
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() override { return strExpressionsInfos; };
|
||||
|
||||
std::map<gd::String, gd::InstructionMetadata> conditionsInfos;
|
||||
std::map<gd::String, gd::InstructionMetadata> actionsInfos;
|
||||
@@ -328,14 +350,13 @@ class GD_CORE_API BehaviorMetadata {
|
||||
gd::String group;
|
||||
gd::String iconFilename;
|
||||
gd::String objectType;
|
||||
mutable std::vector<gd::String> requiredBehaviors;
|
||||
bool isPrivate = false;
|
||||
bool isHidden = false;
|
||||
|
||||
// TODO: Nitpicking: convert these to std::unique_ptr to clarify ownership.
|
||||
std::shared_ptr<gd::Behavior> instance;
|
||||
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance;
|
||||
bool isEventBased;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // BEHAVIORMETADATA_H
|
||||
|
@@ -62,7 +62,7 @@ class GD_CORE_API DependencyMetadata {
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Sets the type of dependecy (what will be used to install it)
|
||||
* \brief Sets the type of dependency (what will be used to install it)
|
||||
*
|
||||
* This can either be "npm" or "cordova" for now.
|
||||
*/
|
||||
|
@@ -7,9 +7,6 @@
|
||||
|
||||
namespace gd {
|
||||
|
||||
EffectMetadata::EffectMetadata(const gd::String& type_)
|
||||
: type(type_), isMarkedAsNotWorkingForObjects(false) {}
|
||||
|
||||
EffectMetadata& EffectMetadata::SetIncludeFile(const gd::String& includeFile) {
|
||||
includeFiles.clear();
|
||||
includeFiles.push_back(includeFile);
|
||||
@@ -23,9 +20,4 @@ EffectMetadata& EffectMetadata::AddIncludeFile(const gd::String& includeFile) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
EffectMetadata& EffectMetadata::MarkAsNotWorkingForObjects() {
|
||||
isMarkedAsNotWorkingForObjects = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -3,8 +3,8 @@
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef EFFECTMETADATA_H
|
||||
#define EFFECTMETADATA_H
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -25,21 +25,25 @@ class GD_CORE_API EffectMetadata {
|
||||
/**
|
||||
* \brief Construct an effect metadata, with the given type
|
||||
*/
|
||||
EffectMetadata(const gd::String& type_);
|
||||
EffectMetadata(const gd::String &type_)
|
||||
: type(type_), isMarkedAsNotWorkingForObjects(false),
|
||||
isMarkedAsOnlyWorkingFor2D(false), isMarkedAsOnlyWorkingFor3D(false),
|
||||
isMarkedAsUnique(false) {}
|
||||
|
||||
/**
|
||||
* \brief Default constructor, only used for initializing `badEffectMetadata`.
|
||||
*/
|
||||
EffectMetadata() {}
|
||||
/**
|
||||
* \brief Default constructor, only used for initializing
|
||||
* `badEffectMetadata`.
|
||||
*/
|
||||
EffectMetadata() {}
|
||||
|
||||
virtual ~EffectMetadata(){};
|
||||
virtual ~EffectMetadata(){};
|
||||
|
||||
/**
|
||||
* \brief Set the name shown to the user.
|
||||
*/
|
||||
EffectMetadata& SetFullName(const gd::String& fullname_) {
|
||||
fullname = fullname_;
|
||||
return *this;
|
||||
/**
|
||||
* \brief Set the name shown to the user.
|
||||
*/
|
||||
EffectMetadata &SetFullName(const gd::String &fullname_) {
|
||||
fullname = fullname_;
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -69,11 +73,6 @@ class GD_CORE_API EffectMetadata {
|
||||
*/
|
||||
EffectMetadata& AddIncludeFile(const gd::String& includeFile);
|
||||
|
||||
/**
|
||||
* \brief Mark the effect as not working as an object effect.
|
||||
*/
|
||||
EffectMetadata& MarkAsNotWorkingForObjects();
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the properties of this effect.
|
||||
*/
|
||||
@@ -117,10 +116,65 @@ class GD_CORE_API EffectMetadata {
|
||||
return includeFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Mark the effect as not working as an object effect.
|
||||
*/
|
||||
EffectMetadata& MarkAsNotWorkingForObjects() {
|
||||
isMarkedAsNotWorkingForObjects = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Mark the effect as only working for the 2D renderer.
|
||||
*/
|
||||
EffectMetadata& MarkAsOnlyWorkingFor2D() {
|
||||
isMarkedAsOnlyWorkingFor2D = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Mark the effect as only working for the 3D renderer.
|
||||
*/
|
||||
EffectMetadata& MarkAsOnlyWorkingFor3D() {
|
||||
isMarkedAsOnlyWorkingFor3D = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Mark the effect as only addable once.
|
||||
*/
|
||||
EffectMetadata& MarkAsUnique() {
|
||||
isMarkedAsUnique = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if the effect is marked as not working as an object effect.
|
||||
*/
|
||||
bool IsMarkedAsNotWorkingForObjects() const { return isMarkedAsNotWorkingForObjects; };
|
||||
bool IsMarkedAsNotWorkingForObjects() const {
|
||||
return isMarkedAsNotWorkingForObjects;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Check if the effect is marked as only working for the 2D renderer.
|
||||
*/
|
||||
bool IsMarkedAsOnlyWorkingFor2D() const {
|
||||
return isMarkedAsOnlyWorkingFor2D;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Check if the effect is marked as only working for the 3D renderer.
|
||||
*/
|
||||
bool IsMarkedAsOnlyWorkingFor3D() const {
|
||||
return isMarkedAsOnlyWorkingFor3D;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Check if the effect can only be added once.
|
||||
*/
|
||||
bool IsMarkedAsUnique() const {
|
||||
return isMarkedAsUnique;
|
||||
};
|
||||
|
||||
private:
|
||||
gd::String extensionNamespace;
|
||||
@@ -130,8 +184,10 @@ class GD_CORE_API EffectMetadata {
|
||||
gd::String description;
|
||||
std::vector<gd::String> includeFiles;
|
||||
bool isMarkedAsNotWorkingForObjects;
|
||||
bool isMarkedAsOnlyWorkingFor2D;
|
||||
bool isMarkedAsOnlyWorkingFor3D;
|
||||
bool isMarkedAsUnique;
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
#endif // EFFECTMETADATA_H
|
||||
|
@@ -3,9 +3,10 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef EXPRESSIONMETADATA_H
|
||||
#define EXPRESSIONMETADATA_H
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#pragma once
|
||||
|
||||
#include "AbstractFunctionMetadata.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
@@ -17,7 +18,6 @@ class Layout;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Information about how generate code for an expression
|
||||
*/
|
||||
@@ -27,79 +27,7 @@ class ExpressionCodeGenerationInformation {
|
||||
: staticFunction(false), hasCustomCodeGenerator(false){};
|
||||
virtual ~ExpressionCodeGenerationInformation(){};
|
||||
|
||||
/**
|
||||
* \brief Set the function name which will be used when generating the code.
|
||||
* \param functionName the name of the function to call
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& SetFunctionName(
|
||||
const gd::String& functionName) {
|
||||
functionCallName = functionName;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set that the function is static
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& SetStatic() {
|
||||
staticFunction = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& SetIncludeFile(
|
||||
const gd::String& includeFile) {
|
||||
includeFiles.clear();
|
||||
includeFiles.push_back(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& AddIncludeFile(
|
||||
const gd::String& includeFile) {
|
||||
if (std::find(includeFiles.begin(), includeFiles.end(), includeFile) ==
|
||||
includeFiles.end())
|
||||
includeFiles.push_back(includeFile);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
const std::vector<gd::String>& GetIncludeFiles() const {
|
||||
return includeFiles;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Set that the function must be generated using a custom code
|
||||
* generator.
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& SetCustomCodeGenerator(
|
||||
std::function<gd::String(const std::vector<gd::Expression>& parameters,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context)>
|
||||
codeGenerator) {
|
||||
hasCustomCodeGenerator = true;
|
||||
customCodeGenerator = codeGenerator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ExpressionCodeGenerationInformation& RemoveCustomCodeGenerator() {
|
||||
hasCustomCodeGenerator = false;
|
||||
std::function<gd::String(const std::vector<gd::Expression>& parameters,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context)>
|
||||
emptyFunction;
|
||||
customCodeGenerator = emptyFunction;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HasCustomCodeGenerator() const { return hasCustomCodeGenerator; }
|
||||
|
||||
// TODO Move these attributes to ExpressionMetadata.
|
||||
bool staticFunction;
|
||||
gd::String functionCallName;
|
||||
bool hasCustomCodeGenerator;
|
||||
@@ -107,8 +35,6 @@ class ExpressionCodeGenerationInformation {
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context)>
|
||||
customCodeGenerator;
|
||||
|
||||
private:
|
||||
std::vector<gd::String> includeFiles;
|
||||
};
|
||||
|
||||
@@ -118,7 +44,7 @@ class ExpressionCodeGenerationInformation {
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API ExpressionMetadata {
|
||||
class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
public:
|
||||
/**
|
||||
* Construct a new expression metadata.
|
||||
@@ -144,7 +70,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
/**
|
||||
* \brief Set the expression as not shown in the IDE.
|
||||
*/
|
||||
ExpressionMetadata& SetHidden();
|
||||
ExpressionMetadata& SetHidden() override;
|
||||
|
||||
/**
|
||||
* \brief Set the group of the instruction in the IDE.
|
||||
@@ -179,7 +105,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
* Set that the instruction is private - it can't be used outside of the
|
||||
* object/ behavior that it is attached too.
|
||||
*/
|
||||
ExpressionMetadata& SetPrivate() {
|
||||
ExpressionMetadata& SetPrivate() override {
|
||||
isPrivate = true;
|
||||
return *this;
|
||||
}
|
||||
@@ -216,7 +142,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in layouts or external events.
|
||||
*/
|
||||
ExpressionMetadata &SetRelevantForLayoutEventsOnly() {
|
||||
ExpressionMetadata &SetRelevantForLayoutEventsOnly() override {
|
||||
relevantContext = "Layout";
|
||||
return *this;
|
||||
}
|
||||
@@ -224,7 +150,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in function events.
|
||||
*/
|
||||
ExpressionMetadata &SetRelevantForFunctionEventsOnly() {
|
||||
ExpressionMetadata &SetRelevantForFunctionEventsOnly() override {
|
||||
relevantContext = "Function";
|
||||
return *this;
|
||||
}
|
||||
@@ -232,7 +158,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in asynchronous function events.
|
||||
*/
|
||||
ExpressionMetadata &SetRelevantForAsynchronousFunctionEventsOnly() {
|
||||
ExpressionMetadata &SetRelevantForAsynchronousFunctionEventsOnly() override {
|
||||
relevantContext = "AsynchronousFunction";
|
||||
return *this;
|
||||
}
|
||||
@@ -240,7 +166,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in custom object events.
|
||||
*/
|
||||
ExpressionMetadata &SetRelevantForCustomObjectEventsOnly() {
|
||||
ExpressionMetadata &SetRelevantForCustomObjectEventsOnly() override {
|
||||
relevantContext = "Object";
|
||||
return *this;
|
||||
}
|
||||
@@ -248,17 +174,17 @@ class GD_CORE_API ExpressionMetadata {
|
||||
/**
|
||||
* \see gd::InstructionMetadata::AddParameter
|
||||
*/
|
||||
gd::ExpressionMetadata& AddParameter(
|
||||
const gd::String& type,
|
||||
const gd::String& description,
|
||||
const gd::String& supplementaryInformation = "",
|
||||
bool parameterIsOptional = false);
|
||||
gd::ExpressionMetadata &
|
||||
AddParameter(const gd::String &type, const gd::String &label,
|
||||
const gd::String &supplementaryInformation = "",
|
||||
bool parameterIsOptional = false) override;
|
||||
|
||||
/**
|
||||
* \see gd::InstructionMetadata::AddCodeOnlyParameter
|
||||
*/
|
||||
gd::ExpressionMetadata& AddCodeOnlyParameter(
|
||||
const gd::String& type, const gd::String& supplementaryInformation);
|
||||
gd::ExpressionMetadata &
|
||||
AddCodeOnlyParameter(const gd::String &type,
|
||||
const gd::String &supplementaryInformation) override;
|
||||
|
||||
/**
|
||||
* Set the default value used in editor (or if an optional parameter is empty
|
||||
@@ -266,8 +192,9 @@ class GD_CORE_API ExpressionMetadata {
|
||||
*
|
||||
* \see AddParameter
|
||||
*/
|
||||
ExpressionMetadata& SetDefaultValue(gd::String defaultValue_) {
|
||||
if (!parameters.empty()) parameters.back().SetDefaultValue(defaultValue_);
|
||||
ExpressionMetadata &SetDefaultValue(const gd::String &defaultValue) override {
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetDefaultValue(defaultValue);
|
||||
return *this;
|
||||
};
|
||||
|
||||
@@ -277,7 +204,8 @@ class GD_CORE_API ExpressionMetadata {
|
||||
*
|
||||
* \see AddParameter
|
||||
*/
|
||||
ExpressionMetadata& SetParameterLongDescription(gd::String longDescription) {
|
||||
ExpressionMetadata &
|
||||
SetParameterLongDescription(const gd::String &longDescription) override {
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetLongDescription(longDescription);
|
||||
return *this;
|
||||
@@ -290,7 +218,8 @@ class GD_CORE_API ExpressionMetadata {
|
||||
*
|
||||
* \see AddParameter
|
||||
*/
|
||||
ExpressionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) {
|
||||
ExpressionMetadata &SetParameterExtraInfo(
|
||||
const gd::String &extraInfo) override {
|
||||
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
|
||||
return *this;
|
||||
}
|
||||
@@ -312,50 +241,6 @@ class GD_CORE_API ExpressionMetadata {
|
||||
return requiredBaseObjectCapability;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Set the function that should be called when generating the source
|
||||
* code from events.
|
||||
* \param functionName the name of the function to call
|
||||
* \note Shortcut for `codeExtraInformation.SetFunctionName`.
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& SetFunctionName(
|
||||
const gd::String& functionName) {
|
||||
return codeExtraInformation.SetFunctionName(functionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the structure containing the information about code
|
||||
* generation for the expression.
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& GetCodeExtraInformation() {
|
||||
return codeExtraInformation;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
*/
|
||||
ExpressionMetadata &SetIncludeFile(const gd::String &includeFile) {
|
||||
codeExtraInformation.SetIncludeFile(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
ExpressionMetadata &AddIncludeFile(const gd::String &includeFile) {
|
||||
codeExtraInformation.AddIncludeFile(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
const std::vector<gd::String>& GetIncludeFiles() const {
|
||||
return codeExtraInformation.GetIncludeFiles();
|
||||
}
|
||||
|
||||
ExpressionCodeGenerationInformation codeExtraInformation;
|
||||
|
||||
bool IsShown() const { return shown; }
|
||||
const gd::String& GetReturnType() const { return returnType; }
|
||||
const gd::String& GetFullName() const { return fullname; }
|
||||
@@ -375,6 +260,99 @@ class GD_CORE_API ExpressionMetadata {
|
||||
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set the function name which will be used when generating the code.
|
||||
* \param functionName the name of the function to call
|
||||
*/
|
||||
ExpressionMetadata& SetFunctionName(
|
||||
const gd::String& functionName) override {
|
||||
codeExtraInformation.functionCallName = functionName;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return the name of the function which will be called in the generated code.
|
||||
*/
|
||||
const gd::String &GetFunctionName() {
|
||||
return codeExtraInformation.functionCallName;
|
||||
}
|
||||
/**
|
||||
* \brief Set that the function is static
|
||||
*/
|
||||
ExpressionMetadata& SetStatic() {
|
||||
codeExtraInformation.staticFunction = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
*/
|
||||
ExpressionMetadata& SetIncludeFile(
|
||||
const gd::String& includeFile) override {
|
||||
codeExtraInformation.includeFiles.clear();
|
||||
codeExtraInformation.includeFiles.push_back(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
ExpressionMetadata& AddIncludeFile(
|
||||
const gd::String& includeFile) override {
|
||||
if (std::find(codeExtraInformation.includeFiles.begin(), codeExtraInformation.includeFiles.end(), includeFile) ==
|
||||
codeExtraInformation.includeFiles.end())
|
||||
codeExtraInformation.includeFiles.push_back(includeFile);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
const std::vector<gd::String>& GetIncludeFiles() const override {
|
||||
return codeExtraInformation.includeFiles;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Set that the function must be generated using a custom code
|
||||
* generator.
|
||||
*/
|
||||
ExpressionMetadata& SetCustomCodeGenerator(
|
||||
std::function<gd::String(const std::vector<gd::Expression>& parameters,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context)>
|
||||
codeGenerator) {
|
||||
codeExtraInformation.hasCustomCodeGenerator = true;
|
||||
codeExtraInformation.customCodeGenerator = codeGenerator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ExpressionMetadata& RemoveCustomCodeGenerator() {
|
||||
codeExtraInformation.hasCustomCodeGenerator = false;
|
||||
std::function<gd::String(const std::vector<gd::Expression>& parameters,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context)>
|
||||
emptyFunction;
|
||||
codeExtraInformation.customCodeGenerator = emptyFunction;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HasCustomCodeGenerator() const { return codeExtraInformation.hasCustomCodeGenerator; }
|
||||
|
||||
/**
|
||||
* \brief Return the structure containing the information about code
|
||||
* generation for the expression.
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
ExpressionMetadata& GetCodeExtraInformation() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ExpressionCodeGenerationInformation codeExtraInformation;
|
||||
|
||||
private:
|
||||
gd::String returnType;
|
||||
gd::String fullname;
|
||||
@@ -391,6 +369,3 @@ class GD_CORE_API ExpressionMetadata {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
||||
#endif // EXPRESSIONMETADATA_H
|
||||
|
@@ -4,8 +4,10 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef INSTRUCTIONMETADATA_H
|
||||
#define INSTRUCTIONMETADATA_H
|
||||
#pragma once
|
||||
|
||||
#include "AbstractFunctionMetadata.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
@@ -33,7 +35,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API InstructionMetadata {
|
||||
class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
public:
|
||||
/**
|
||||
* Construct a new instruction metadata.
|
||||
@@ -96,7 +98,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
* Set that the instruction is private - it can't be used outside of the
|
||||
* object/ behavior that it is attached too.
|
||||
*/
|
||||
InstructionMetadata &SetPrivate() {
|
||||
InstructionMetadata &SetPrivate() override {
|
||||
isPrivate = true;
|
||||
return *this;
|
||||
}
|
||||
@@ -133,7 +135,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in layouts or external events.
|
||||
*/
|
||||
InstructionMetadata &SetRelevantForLayoutEventsOnly() {
|
||||
InstructionMetadata &SetRelevantForLayoutEventsOnly() override {
|
||||
relevantContext = "Layout";
|
||||
return *this;
|
||||
}
|
||||
@@ -141,7 +143,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in function events.
|
||||
*/
|
||||
InstructionMetadata &SetRelevantForFunctionEventsOnly() {
|
||||
InstructionMetadata &SetRelevantForFunctionEventsOnly() override {
|
||||
relevantContext = "Function";
|
||||
return *this;
|
||||
}
|
||||
@@ -149,7 +151,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in asynchronous function events.
|
||||
*/
|
||||
InstructionMetadata &SetRelevantForAsynchronousFunctionEventsOnly() {
|
||||
InstructionMetadata &SetRelevantForAsynchronousFunctionEventsOnly() override {
|
||||
relevantContext = "AsynchronousFunction";
|
||||
return *this;
|
||||
}
|
||||
@@ -157,7 +159,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in custom object events.
|
||||
*/
|
||||
InstructionMetadata &SetRelevantForCustomObjectEventsOnly() {
|
||||
InstructionMetadata &SetRelevantForCustomObjectEventsOnly() override {
|
||||
relevantContext = "Object";
|
||||
return *this;
|
||||
}
|
||||
@@ -192,7 +194,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
*
|
||||
* Used mainly when an instruction is deprecated.
|
||||
*/
|
||||
InstructionMetadata &SetHidden() {
|
||||
InstructionMetadata &SetHidden() override {
|
||||
hidden = true;
|
||||
return *this;
|
||||
}
|
||||
@@ -231,7 +233,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
const gd::String &type,
|
||||
const gd::String &label,
|
||||
const gd::String &supplementaryInformation = "",
|
||||
bool parameterIsOptional = false);
|
||||
bool parameterIsOptional = false) override;
|
||||
|
||||
/**
|
||||
* \brief Add a parameter not displayed in editor.
|
||||
@@ -245,7 +247,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
* \see EventsCodeGenerator::GenerateParametersCodes
|
||||
*/
|
||||
InstructionMetadata &AddCodeOnlyParameter(
|
||||
const gd::String &type, const gd::String &supplementaryInformation);
|
||||
const gd::String &type, const gd::String &supplementaryInformation) override;
|
||||
|
||||
/**
|
||||
* \brief Set the default value used in editor (or if an optional parameter is
|
||||
@@ -253,7 +255,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
*
|
||||
* \see AddParameter
|
||||
*/
|
||||
InstructionMetadata &SetDefaultValue(const gd::String &defaultValue_) {
|
||||
InstructionMetadata &SetDefaultValue(const gd::String &defaultValue_) override {
|
||||
if (!parameters.empty()) parameters.back().SetDefaultValue(defaultValue_);
|
||||
return *this;
|
||||
};
|
||||
@@ -265,7 +267,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
* \see AddParameter
|
||||
*/
|
||||
InstructionMetadata &SetParameterLongDescription(
|
||||
const gd::String &longDescription) {
|
||||
const gd::String &longDescription) override {
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetLongDescription(longDescription);
|
||||
return *this;
|
||||
@@ -278,7 +280,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
*
|
||||
* \see AddParameter
|
||||
*/
|
||||
InstructionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) {
|
||||
InstructionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) override {
|
||||
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
|
||||
return *this;
|
||||
}
|
||||
@@ -382,128 +384,13 @@ class GD_CORE_API InstructionMetadata {
|
||||
/**
|
||||
* \brief Defines information about how generate the code for an instruction
|
||||
*/
|
||||
class ExtraInformation {
|
||||
class ExtraInformation {
|
||||
public:
|
||||
enum AccessType { Reference, MutatorAndOrAccessor, Mutators };
|
||||
ExtraInformation() : accessType(Reference), hasCustomCodeGenerator(false){};
|
||||
virtual ~ExtraInformation(){};
|
||||
|
||||
/**
|
||||
* Set the name of the function which will be called in the generated code.
|
||||
* \param functionName the name of the function to call.
|
||||
*/
|
||||
ExtraInformation &SetFunctionName(const gd::String &functionName_) {
|
||||
functionCallName = functionName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the function, doing asynchronous work, which will be
|
||||
* called in the generated code. This function should return an asynchronous
|
||||
* task (i.e: `gdjs.AsyncTask` in the JavaScript runtime).
|
||||
*
|
||||
* \param functionName the name of the function doing asynchronous work to
|
||||
* call.
|
||||
*/
|
||||
ExtraInformation &SetAsyncFunctionName(const gd::String &functionName_) {
|
||||
asyncFunctionCallName = functionName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare if the instruction being declared is somewhat manipulating in a
|
||||
* standard way.
|
||||
*/
|
||||
ExtraInformation &SetManipulatedType(const gd::String &type_) {
|
||||
type = type_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If InstructionMetadata::ExtraInformation::SetManipulatedType was called
|
||||
* with "number" or "string", this function will tell the code generator the
|
||||
* name of the getter function used to retrieve the data value.
|
||||
*
|
||||
* Usage example:
|
||||
* \code
|
||||
* obj.AddAction("String",
|
||||
* _("Change the string"),
|
||||
* _("Change the string of a text"),
|
||||
* _("the string"),
|
||||
* _("Text"),
|
||||
* "CppPlatform/Extensions/text24.png",
|
||||
* "CppPlatform/Extensions/text_black.png");
|
||||
*
|
||||
* .AddParameter("object", _("Object"), "Text", false)
|
||||
* .AddParameter("operator", _("Modification operator"), "string")
|
||||
* .AddParameter("string", _("String"))
|
||||
* .SetFunctionName("SetString").SetManipulatedType("string").SetGetter("GetString");
|
||||
*
|
||||
* DECLARE_END_OBJECT_ACTION()
|
||||
* \endcode
|
||||
*/
|
||||
ExtraInformation &SetGetter(const gd::String &getter) {
|
||||
optionalAssociatedInstruction = getter;
|
||||
accessType = MutatorAndOrAccessor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ExtraInformation &SetMutators(
|
||||
const std::map<gd::String, gd::String> &mutators) {
|
||||
optionalMutators = mutators;
|
||||
accessType = Mutators;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
*/
|
||||
ExtraInformation &SetIncludeFile(const gd::String &includeFile) {
|
||||
includeFiles.clear();
|
||||
includeFiles.push_back(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
ExtraInformation &AddIncludeFile(const gd::String &includeFile) {
|
||||
if (std::find(includeFiles.begin(), includeFiles.end(), includeFile) ==
|
||||
includeFiles.end())
|
||||
includeFiles.push_back(includeFile);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
const std::vector<gd::String> &GetIncludeFiles() const {
|
||||
return includeFiles;
|
||||
};
|
||||
|
||||
ExtraInformation &SetCustomCodeGenerator(
|
||||
std::function<gd::String(Instruction &instruction,
|
||||
gd::EventsCodeGenerator &codeGenerator,
|
||||
gd::EventsCodeGenerationContext &context)>
|
||||
codeGenerator) {
|
||||
hasCustomCodeGenerator = true;
|
||||
customCodeGenerator = codeGenerator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ExtraInformation &RemoveCustomCodeGenerator() {
|
||||
hasCustomCodeGenerator = false;
|
||||
std::function<gd::String(Instruction & instruction,
|
||||
gd::EventsCodeGenerator & codeGenerator,
|
||||
gd::EventsCodeGenerationContext & context)>
|
||||
emptyFunction;
|
||||
customCodeGenerator = emptyFunction;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HasCustomCodeGenerator() const { return hasCustomCodeGenerator; }
|
||||
|
||||
// TODO Move these attributes to InstructionMetadata.
|
||||
gd::String functionCallName;
|
||||
gd::String asyncFunctionCallName;
|
||||
gd::String type;
|
||||
@@ -512,75 +399,156 @@ class GD_CORE_API InstructionMetadata {
|
||||
std::map<gd::String, gd::String> optionalMutators;
|
||||
bool hasCustomCodeGenerator;
|
||||
std::function<gd::String(Instruction &instruction,
|
||||
gd::EventsCodeGenerator &codeGenerator,
|
||||
gd::EventsCodeGenerationContext &context)>
|
||||
gd::EventsCodeGenerator &codeGenerator,
|
||||
gd::EventsCodeGenerationContext &context)>
|
||||
customCodeGenerator;
|
||||
|
||||
private:
|
||||
std::vector<gd::String> includeFiles;
|
||||
};
|
||||
ExtraInformation codeExtraInformation; ///< Information about how generate
|
||||
///< code for the instruction
|
||||
|
||||
/**
|
||||
* \brief Return the structure containing the information about code
|
||||
* generation for the instruction.
|
||||
*/
|
||||
ExtraInformation &GetCodeExtraInformation() { return codeExtraInformation; }
|
||||
|
||||
/**
|
||||
* \brief Declare if the instruction being declared is somewhat manipulating
|
||||
* in a standard way. \param type "number" or "string" \note Shortcut for
|
||||
* `codeExtraInformation.SetManipulatedType(type)`.
|
||||
*/
|
||||
ExtraInformation &SetManipulatedType(const gd::String &type_) {
|
||||
return codeExtraInformation.SetManipulatedType(type_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the function which will be called in the generated code.
|
||||
* \param functionName the name of the function to call.
|
||||
* \note Shortcut for `codeExtraInformation.SetFunctionName`.
|
||||
*/
|
||||
ExtraInformation &SetFunctionName(const gd::String &functionName) {
|
||||
return codeExtraInformation.SetFunctionName(functionName);
|
||||
InstructionMetadata &SetFunctionName(const gd::String &functionName_) override {
|
||||
codeExtraInformation.functionCallName = functionName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the function, doing asynchronous work, which will be called
|
||||
* in the generated code. This function should return an asynchronous task
|
||||
* (i.e: `gdjs.AsyncTask` in the JavaScript runtime).
|
||||
* Set the name of the function, doing asynchronous work, which will be
|
||||
* called in the generated code. This function should return an asynchronous
|
||||
* task (i.e: `gdjs.AsyncTask` in the JavaScript runtime).
|
||||
*
|
||||
* \param functionName the name of the function doing asynchronous work to
|
||||
* call. \note Shortcut for `codeExtraInformation.SetAsyncFunctionName`.
|
||||
* call.
|
||||
*/
|
||||
ExtraInformation &SetAsyncFunctionName(const gd::String &functionName) {
|
||||
return codeExtraInformation.SetAsyncFunctionName(functionName);
|
||||
InstructionMetadata &SetAsyncFunctionName(const gd::String &functionName_) {
|
||||
codeExtraInformation.asyncFunctionCallName = functionName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the function which will be called in the generated code.
|
||||
*/
|
||||
const gd::String &GetFunctionName() {
|
||||
return codeExtraInformation.functionCallName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the function, doing asynchronous work, which will be
|
||||
* called in the generated code. This function should return an asynchronous
|
||||
* task (i.e: `gdjs.AsyncTask` in the JavaScript runtime).
|
||||
*/
|
||||
const gd::String &GetAsyncFunctionName() {
|
||||
return codeExtraInformation.asyncFunctionCallName;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Declare if the instruction being declared is somewhat manipulating
|
||||
* in a standard way.
|
||||
*
|
||||
* \param type "number" or "string"
|
||||
*/
|
||||
InstructionMetadata &SetManipulatedType(const gd::String &type_) {
|
||||
codeExtraInformation.type = type_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If InstructionMetadata::ExtraInformation::SetManipulatedType was called
|
||||
* with "number" or "string", this function will tell the code generator the
|
||||
* name of the getter function used to retrieve the data value.
|
||||
*
|
||||
* Usage example:
|
||||
* \code
|
||||
* obj.AddAction("String",
|
||||
* _("Change the string"),
|
||||
* _("Change the string of a text"),
|
||||
* _("the string"),
|
||||
* _("Text"),
|
||||
* "CppPlatform/Extensions/text24.png",
|
||||
* "CppPlatform/Extensions/text_black.png");
|
||||
*
|
||||
* .AddParameter("object", _("Object"), "Text", false)
|
||||
* .AddParameter("operator", _("Modification operator"), "string")
|
||||
* .AddParameter("string", _("String"))
|
||||
* .SetFunctionName("SetString").SetManipulatedType("string").SetGetter("GetString");
|
||||
*
|
||||
* DECLARE_END_OBJECT_ACTION()
|
||||
* \endcode
|
||||
*/
|
||||
InstructionMetadata &SetGetter(const gd::String &getter) {
|
||||
codeExtraInformation.optionalAssociatedInstruction = getter;
|
||||
codeExtraInformation.accessType = codeExtraInformation.MutatorAndOrAccessor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InstructionMetadata &SetMutators(
|
||||
const std::map<gd::String, gd::String> &mutators) {
|
||||
codeExtraInformation.optionalMutators = mutators;
|
||||
codeExtraInformation.accessType = codeExtraInformation.Mutators;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
*/
|
||||
InstructionMetadata &SetIncludeFile(const gd::String &includeFile) {
|
||||
codeExtraInformation.SetIncludeFile(includeFile);
|
||||
InstructionMetadata &SetIncludeFile(const gd::String &includeFile) override {
|
||||
codeExtraInformation.includeFiles.clear();
|
||||
codeExtraInformation.includeFiles.push_back(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
InstructionMetadata &AddIncludeFile(const gd::String &includeFile) {
|
||||
codeExtraInformation.AddIncludeFile(includeFile);
|
||||
InstructionMetadata &AddIncludeFile(const gd::String &includeFile) override {
|
||||
if (std::find(codeExtraInformation.includeFiles.begin(), codeExtraInformation.includeFiles.end(), includeFile) ==
|
||||
codeExtraInformation.includeFiles.end())
|
||||
codeExtraInformation.includeFiles.push_back(includeFile);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
const std::vector<gd::String> &GetIncludeFiles() const {
|
||||
return codeExtraInformation.GetIncludeFiles();
|
||||
const std::vector<gd::String> &GetIncludeFiles() const override {
|
||||
return codeExtraInformation.includeFiles;
|
||||
};
|
||||
|
||||
InstructionMetadata &SetCustomCodeGenerator(
|
||||
std::function<gd::String(Instruction &instruction,
|
||||
gd::EventsCodeGenerator &codeGenerator,
|
||||
gd::EventsCodeGenerationContext &context)>
|
||||
codeGenerator) {
|
||||
codeExtraInformation.hasCustomCodeGenerator = true;
|
||||
codeExtraInformation.customCodeGenerator = codeGenerator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InstructionMetadata &RemoveCustomCodeGenerator() {
|
||||
codeExtraInformation.hasCustomCodeGenerator = false;
|
||||
std::function<gd::String(Instruction & instruction,
|
||||
gd::EventsCodeGenerator & codeGenerator,
|
||||
gd::EventsCodeGenerationContext & context)>
|
||||
emptyFunction;
|
||||
codeExtraInformation.customCodeGenerator = emptyFunction;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HasCustomCodeGenerator() const { return codeExtraInformation.hasCustomCodeGenerator; }
|
||||
|
||||
/**
|
||||
* \brief Return the structure containing the information about code
|
||||
* generation for the instruction.
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
InstructionMetadata &GetCodeExtraInformation() { return *this; }
|
||||
|
||||
std::vector<ParameterMetadata> parameters;
|
||||
|
||||
private:
|
||||
@@ -604,5 +572,3 @@ class GD_CORE_API InstructionMetadata {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // INSTRUCTIONMETADATA_H
|
||||
|
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class Behavior;
|
||||
class BehaviorsSharedData;
|
||||
class MultipleInstructionMetadata;
|
||||
class InstructionMetadata;
|
||||
class ExpressionMetadata;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Contains user-friendly information about instructions and expressions
|
||||
* (usually for a behavior or an object).
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API InstructionOrExpressionContainerMetadata {
|
||||
public:
|
||||
InstructionOrExpressionContainerMetadata(){};
|
||||
virtual ~InstructionOrExpressionContainerMetadata(){};
|
||||
|
||||
/**
|
||||
* Declare a new condition as being part of the behavior or object.
|
||||
* \deprecated Prefer using `AddScopedCondition`, to properly namespace
|
||||
* the condition.
|
||||
*/
|
||||
virtual gd::InstructionMetadata &
|
||||
AddCondition(const gd::String &name_, const gd::String &fullname_,
|
||||
const gd::String &description_, const gd::String &sentence_,
|
||||
const gd::String &group_, const gd::String &icon_,
|
||||
const gd::String &smallicon_) = 0;
|
||||
|
||||
/**
|
||||
* Declare a new action as being part of the behavior or object.
|
||||
* \deprecated Prefer using `AddScopedAction`, to properly namespace
|
||||
* the action.
|
||||
*/
|
||||
virtual gd::InstructionMetadata &
|
||||
AddAction(const gd::String &name_, const gd::String &fullname_,
|
||||
const gd::String &description_, const gd::String &sentence_,
|
||||
const gd::String &group_, const gd::String &icon_,
|
||||
const gd::String &smallicon_) = 0;
|
||||
|
||||
/**
|
||||
* Declare a new condition as being part of the behavior or object.
|
||||
*/
|
||||
virtual gd::InstructionMetadata &
|
||||
AddScopedCondition(const gd::String &name_, const gd::String &fullname_,
|
||||
const gd::String &description_,
|
||||
const gd::String &sentence_, const gd::String &group_,
|
||||
const gd::String &icon_, const gd::String &smallicon_) = 0;
|
||||
|
||||
/**
|
||||
* Declare a new action as being part of the behavior or object.
|
||||
*/
|
||||
virtual gd::InstructionMetadata &
|
||||
AddScopedAction(const gd::String &name_, const gd::String &fullname_,
|
||||
const gd::String &description_, const gd::String &sentence_,
|
||||
const gd::String &group_, const gd::String &icon_,
|
||||
const gd::String &smallicon_) = 0;
|
||||
/**
|
||||
* Declare a new action as being part of the extension.
|
||||
*/
|
||||
virtual gd::ExpressionMetadata &
|
||||
AddExpression(const gd::String &name_, const gd::String &fullname_,
|
||||
const gd::String &description_, const gd::String &group_,
|
||||
const gd::String &smallicon_) = 0;
|
||||
|
||||
/**
|
||||
* Declare a new string expression as being part of the extension.
|
||||
*/
|
||||
virtual gd::ExpressionMetadata &
|
||||
AddStrExpression(const gd::String &name_, const gd::String &fullname_,
|
||||
const gd::String &description_, const gd::String &group_,
|
||||
const gd::String &smallicon_) = 0;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression and condition as being part of the
|
||||
* behavior.
|
||||
* \note It's recommended to use this function to avoid declaring twice a
|
||||
* similar expression/condition.
|
||||
*/
|
||||
virtual gd::MultipleInstructionMetadata AddExpressionAndCondition(
|
||||
const gd::String &type, const gd::String &name,
|
||||
const gd::String &fullname, const gd::String &description,
|
||||
const gd::String &sentenceName, const gd::String &group,
|
||||
const gd::String &icon) = 0;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression, condition and action as being part of the
|
||||
* behavior.
|
||||
* \note The action name is prefixed by "Set" (and the namespace, as the
|
||||
* condition).
|
||||
* \note It's recommended to use this function to avoid declaring 3 times a
|
||||
* similar expression/condition/action.
|
||||
*/
|
||||
virtual gd::MultipleInstructionMetadata AddExpressionAndConditionAndAction(
|
||||
const gd::String &type, const gd::String &name,
|
||||
const gd::String &fullname, const gd::String &description,
|
||||
const gd::String &sentenceName, const gd::String &group,
|
||||
const gd::String &icon) = 0;
|
||||
|
||||
/**
|
||||
* \brief Create a new action which is the duplicate of the specified one.
|
||||
*
|
||||
* Useful for handling a deprecated action that is just a "copy" of the new
|
||||
* one.
|
||||
*/
|
||||
virtual gd::InstructionMetadata &
|
||||
AddDuplicatedAction(const gd::String &newActionName,
|
||||
const gd::String &copiedActionName) = 0;
|
||||
|
||||
/**
|
||||
* \brief Create a new condition which is the duplicate of the specified one.
|
||||
*
|
||||
* Useful for handling a deprecated condition that is just a "copy" of the new
|
||||
* one.
|
||||
*/
|
||||
virtual gd::InstructionMetadata &
|
||||
AddDuplicatedCondition(const gd::String &newConditionName,
|
||||
const gd::String &copiedConditionName) = 0;
|
||||
|
||||
virtual InstructionOrExpressionContainerMetadata &
|
||||
SetFullName(const gd::String &fullname_) = 0;
|
||||
virtual InstructionOrExpressionContainerMetadata &
|
||||
SetDescription(const gd::String &description_) = 0;
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
* \note The requirement may vary depending on the platform: Most of the time,
|
||||
* the include file contains the declaration of the behavior.
|
||||
*/
|
||||
virtual InstructionOrExpressionContainerMetadata &
|
||||
SetIncludeFile(const gd::String &includeFile) = 0;
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
virtual InstructionOrExpressionContainerMetadata &
|
||||
AddIncludeFile(const gd::String &includeFile) = 0;
|
||||
|
||||
/**
|
||||
* Get the help path of the behavior, relative to the GDevelop documentation
|
||||
* root.
|
||||
*/
|
||||
virtual const gd::String &GetHelpPath() const = 0;
|
||||
|
||||
/**
|
||||
* Set the help path of the behavior, relative to the GDevelop documentation
|
||||
* root.
|
||||
*
|
||||
* The behavior instructions will have this help path set by
|
||||
* default, unless you call SetHelpPath on them.
|
||||
*/
|
||||
virtual InstructionOrExpressionContainerMetadata &
|
||||
SetHelpPath(const gd::String &path) = 0;
|
||||
|
||||
virtual const gd::String &GetName() const = 0;
|
||||
virtual const gd::String &GetFullName() const = 0;
|
||||
virtual const gd::String &GetDescription() const = 0;
|
||||
virtual const gd::String &GetIconFilename() const = 0;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a map containing the names of the actions
|
||||
* (as keys) and the metadata associated with (as values).
|
||||
*/
|
||||
virtual std::map<gd::String, gd::InstructionMetadata> &GetAllActions() = 0;
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
virtual std::map<gd::String, gd::InstructionMetadata> &GetAllConditions() = 0;
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
virtual std::map<gd::String, gd::ExpressionMetadata> &GetAllExpressions() = 0;
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
virtual std::map<gd::String, gd::ExpressionMetadata> &
|
||||
GetAllStrExpressions() = 0;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -14,6 +14,7 @@
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Project/Layout.h" // For GetTypeOfObject and GetTypeOfBehavior
|
||||
#include "GDCore/Project/ObjectsContainersList.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2.h"
|
||||
|
||||
@@ -135,11 +136,11 @@ MetadataProvider::GetExtensionAndConditionMetadata(const gd::Platform& platform,
|
||||
|
||||
const auto& objects = extension->GetExtensionObjectsTypes();
|
||||
for (const gd::String& extObjectType : objects) {
|
||||
const auto& allObjetsConditions =
|
||||
const auto& allObjectsConditions =
|
||||
extension->GetAllConditionsForObject(extObjectType);
|
||||
if (allObjetsConditions.find(conditionType) != allObjetsConditions.end())
|
||||
if (allObjectsConditions.find(conditionType) != allObjectsConditions.end())
|
||||
return ExtensionAndMetadata<InstructionMetadata>(
|
||||
*extension, allObjetsConditions.find(conditionType)->second);
|
||||
*extension, allObjectsConditions.find(conditionType)->second);
|
||||
}
|
||||
|
||||
const auto& autos = extension->GetBehaviorsTypes();
|
||||
@@ -391,20 +392,19 @@ MetadataProvider::GetBehaviorAnyExpressionMetadata(const gd::Platform& platform,
|
||||
}
|
||||
|
||||
const gd::ExpressionMetadata& MetadataProvider::GetFunctionCallMetadata(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer &globalObjectsContainer,
|
||||
const gd::ObjectsContainer &objectsContainer,
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainersList &objectsContainersList,
|
||||
FunctionCallNode& node) {
|
||||
|
||||
if (!node.behaviorName.empty()) {
|
||||
gd::String behaviorType =
|
||||
GetTypeOfBehavior(globalObjectsContainer, objectsContainer, node.behaviorName);
|
||||
gd::String behaviorType =
|
||||
objectsContainersList.GetTypeOfBehavior(node.behaviorName);
|
||||
return MetadataProvider::GetBehaviorAnyExpressionMetadata(
|
||||
platform, behaviorType, node.functionName);
|
||||
}
|
||||
else if (!node.objectName.empty()) {
|
||||
gd::String objectType =
|
||||
GetTypeOfObject(globalObjectsContainer, objectsContainer, node.objectName);
|
||||
gd::String objectType =
|
||||
objectsContainersList.GetTypeOfObject(node.objectName);
|
||||
return MetadataProvider::GetObjectAnyExpressionMetadata(
|
||||
platform, objectType, node.functionName);
|
||||
}
|
||||
@@ -412,10 +412,9 @@ const gd::ExpressionMetadata& MetadataProvider::GetFunctionCallMetadata(
|
||||
return MetadataProvider::GetAnyExpressionMetadata(platform, node.functionName);
|
||||
}
|
||||
|
||||
const gd::ParameterMetadata* MetadataProvider::GetFunctionCallParameterMetadata(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer &globalObjectsContainer,
|
||||
const gd::ObjectsContainer &objectsContainer,
|
||||
const gd::ParameterMetadata* MetadataProvider::GetFunctionCallParameterMetadata(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainersList &objectsContainersList,
|
||||
FunctionCallNode& functionCall,
|
||||
ExpressionNode& parameter) {
|
||||
int parameterIndex = -1;
|
||||
@@ -429,17 +428,15 @@ const gd::ExpressionMetadata& MetadataProvider::GetFunctionCallMetadata(
|
||||
return nullptr;
|
||||
}
|
||||
return MetadataProvider::GetFunctionCallParameterMetadata(
|
||||
platform,
|
||||
globalObjectsContainer,
|
||||
objectsContainer,
|
||||
platform,
|
||||
objectsContainersList,
|
||||
functionCall,
|
||||
parameterIndex);
|
||||
}
|
||||
|
||||
const gd::ParameterMetadata* MetadataProvider::GetFunctionCallParameterMetadata(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer &globalObjectsContainer,
|
||||
const gd::ObjectsContainer &objectsContainer,
|
||||
const gd::ParameterMetadata* MetadataProvider::GetFunctionCallParameterMetadata(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainersList &objectsContainersList,
|
||||
FunctionCallNode& functionCall,
|
||||
int parameterIndex) {
|
||||
// Search the parameter metadata index skipping invisible ones.
|
||||
@@ -448,7 +445,7 @@ const gd::ExpressionMetadata& MetadataProvider::GetFunctionCallMetadata(
|
||||
ExpressionParser2::WrittenParametersFirstIndex(
|
||||
functionCall.objectName, functionCall.behaviorName);
|
||||
const gd::ExpressionMetadata &metadata = MetadataProvider::GetFunctionCallMetadata(
|
||||
platform, globalObjectsContainer, objectsContainer, functionCall);
|
||||
platform, objectsContainersList, functionCall);
|
||||
|
||||
if (IsBadExpressionMetadata(metadata)) {
|
||||
return nullptr;
|
||||
|
@@ -15,6 +15,7 @@ class ExpressionMetadata;
|
||||
class ExpressionMetadata;
|
||||
class Platform;
|
||||
class PlatformExtension;
|
||||
class ObjectsContainersList;
|
||||
struct FunctionCallNode;
|
||||
struct ExpressionNode;
|
||||
} // namespace gd
|
||||
@@ -237,22 +238,19 @@ class GD_CORE_API MetadataProvider {
|
||||
const gd::Platform& platform, gd::String objectType, gd::String exprType);
|
||||
|
||||
static const gd::ExpressionMetadata& GetFunctionCallMetadata(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer &globalObjectsContainer,
|
||||
const gd::ObjectsContainer &objectsContainer,
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainersList &objectsContainersList,
|
||||
FunctionCallNode& node);
|
||||
|
||||
static const gd::ParameterMetadata* GetFunctionCallParameterMetadata(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer &globalObjectsContainer,
|
||||
const gd::ObjectsContainer &objectsContainer,
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainersList &objectsContainersList,
|
||||
FunctionCallNode& functionCall,
|
||||
ExpressionNode& parameter);
|
||||
|
||||
static const gd::ParameterMetadata* GetFunctionCallParameterMetadata(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer &globalObjectsContainer,
|
||||
const gd::ObjectsContainer &objectsContainer,
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainersList &objectsContainersList,
|
||||
FunctionCallNode& functionCall,
|
||||
int parameterIndex);
|
||||
|
||||
@@ -275,6 +273,10 @@ class GD_CORE_API MetadataProvider {
|
||||
return &metadata == &badBehaviorMetadata;
|
||||
}
|
||||
|
||||
static bool IsBadObjectMetadata(const gd::ObjectMetadata& metadata) {
|
||||
return &metadata == &badObjectInfo;
|
||||
}
|
||||
|
||||
virtual ~MetadataProvider();
|
||||
|
||||
private:
|
||||
|
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "MultipleInstructionMetadata.h"
|
||||
|
||||
#include "InstructionMetadata.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
} // namespace gd
|
@@ -3,8 +3,8 @@
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef MULTIPLEINSTRUCTIONSMETADATA_H
|
||||
#define MULTIPLEINSTRUCTIONSMETADATA_H
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -21,7 +21,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API MultipleInstructionMetadata {
|
||||
class GD_CORE_API MultipleInstructionMetadata : public AbstractFunctionMetadata {
|
||||
public:
|
||||
static MultipleInstructionMetadata WithExpressionAndCondition(
|
||||
gd::ExpressionMetadata &expression, gd::InstructionMetadata &condition) {
|
||||
@@ -45,7 +45,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
const gd::String &type,
|
||||
const gd::String &label,
|
||||
const gd::String &supplementaryInformation = "",
|
||||
bool parameterIsOptional = false) {
|
||||
bool parameterIsOptional = false) override {
|
||||
if (expression)
|
||||
expression->AddParameter(
|
||||
type, label, supplementaryInformation, parameterIsOptional);
|
||||
@@ -62,7 +62,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
* \see gd::InstructionMetadata::AddCodeOnlyParameter
|
||||
*/
|
||||
MultipleInstructionMetadata &AddCodeOnlyParameter(
|
||||
const gd::String &type, const gd::String &supplementaryInformation) {
|
||||
const gd::String &type, const gd::String &supplementaryInformation) override {
|
||||
if (expression)
|
||||
expression->AddCodeOnlyParameter(type, supplementaryInformation);
|
||||
if (condition)
|
||||
@@ -74,7 +74,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
/**
|
||||
* \see gd::InstructionMetadata::SetDefaultValue
|
||||
*/
|
||||
MultipleInstructionMetadata &SetDefaultValue(const gd::String &defaultValue) {
|
||||
MultipleInstructionMetadata &SetDefaultValue(const gd::String &defaultValue) override {
|
||||
if (expression) expression->SetDefaultValue(defaultValue);
|
||||
if (condition) condition->SetDefaultValue(defaultValue);
|
||||
if (action) action->SetDefaultValue(defaultValue);
|
||||
@@ -85,7 +85,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
* \see gd::InstructionMetadata::SetParameterExtraInfo
|
||||
*/
|
||||
MultipleInstructionMetadata &SetParameterExtraInfo(
|
||||
const gd::String &defaultValue) {
|
||||
const gd::String &defaultValue) override {
|
||||
if (expression) expression->SetParameterExtraInfo(defaultValue);
|
||||
if (condition) condition->SetParameterExtraInfo(defaultValue);
|
||||
if (action) action->SetParameterExtraInfo(defaultValue);
|
||||
@@ -96,7 +96,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
* \see gd::InstructionMetadata::SetParameterLongDescription
|
||||
*/
|
||||
MultipleInstructionMetadata &SetParameterLongDescription(
|
||||
const gd::String &longDescription) {
|
||||
const gd::String &longDescription) override {
|
||||
if (expression) expression->SetParameterLongDescription(longDescription);
|
||||
if (condition) condition->SetParameterLongDescription(longDescription);
|
||||
if (action) action->SetParameterLongDescription(longDescription);
|
||||
@@ -106,7 +106,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
/**
|
||||
* \see gd::InstructionMetadata::SetHidden
|
||||
*/
|
||||
MultipleInstructionMetadata &SetHidden() {
|
||||
MultipleInstructionMetadata &SetHidden() override {
|
||||
if (expression) expression->SetHidden();
|
||||
if (condition) condition->SetHidden();
|
||||
if (action) action->SetHidden();
|
||||
@@ -136,47 +136,47 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultipleInstructionMetadata &SetFunctionName(const gd::String &functionName) {
|
||||
MultipleInstructionMetadata &SetFunctionName(const gd::String &functionName) override {
|
||||
if (expression) expression->SetFunctionName(functionName);
|
||||
if (condition) condition->SetFunctionName(functionName);
|
||||
if (action) action->GetCodeExtraInformation().SetFunctionName(functionName);
|
||||
if (action) action->SetFunctionName(functionName);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultipleInstructionMetadata &SetGetter(const gd::String &getter) {
|
||||
if (expression) expression->SetFunctionName(getter);
|
||||
if (condition) condition->SetFunctionName(getter);
|
||||
if (action) action->GetCodeExtraInformation().SetGetter(getter);
|
||||
if (action) action->SetGetter(getter);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultipleInstructionMetadata &SetIncludeFile(const gd::String &includeFile) {
|
||||
MultipleInstructionMetadata &SetIncludeFile(const gd::String &includeFile) override {
|
||||
if (expression)
|
||||
expression->GetCodeExtraInformation().SetIncludeFile(includeFile);
|
||||
expression->SetIncludeFile(includeFile);
|
||||
if (condition)
|
||||
condition->GetCodeExtraInformation().SetIncludeFile(includeFile);
|
||||
if (action) action->GetCodeExtraInformation().SetIncludeFile(includeFile);
|
||||
condition->SetIncludeFile(includeFile);
|
||||
if (action) action->SetIncludeFile(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultipleInstructionMetadata &AddIncludeFile(const gd::String &includeFile) {
|
||||
MultipleInstructionMetadata &AddIncludeFile(const gd::String &includeFile) override {
|
||||
if (expression)
|
||||
expression->GetCodeExtraInformation().AddIncludeFile(includeFile);
|
||||
if (condition)
|
||||
condition->GetCodeExtraInformation().AddIncludeFile(includeFile);
|
||||
if (action) action->GetCodeExtraInformation().AddIncludeFile(includeFile);
|
||||
condition->AddIncludeFile(includeFile);
|
||||
if (action) action->AddIncludeFile(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
const std::vector<gd::String> &GetIncludeFiles() const {
|
||||
const std::vector<gd::String> &GetIncludeFiles() const override {
|
||||
if (expression)
|
||||
return expression->GetCodeExtraInformation().GetIncludeFiles();
|
||||
if (condition)
|
||||
return condition->GetCodeExtraInformation().GetIncludeFiles();
|
||||
if (action) return action->GetCodeExtraInformation().GetIncludeFiles();
|
||||
return condition->GetIncludeFiles();
|
||||
if (action) return action->GetIncludeFiles();
|
||||
// It can't actually happen.
|
||||
throw std::logic_error("no instruction metadata");
|
||||
}
|
||||
@@ -184,7 +184,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
/**
|
||||
* \see gd::InstructionMetadata::SetPrivate
|
||||
*/
|
||||
MultipleInstructionMetadata &SetPrivate() {
|
||||
MultipleInstructionMetadata &SetPrivate() override {
|
||||
if (expression) expression->SetPrivate();
|
||||
if (condition) condition->SetPrivate();
|
||||
if (action) action->SetPrivate();
|
||||
@@ -218,6 +218,42 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that the instruction can be used in layouts or external events.
|
||||
*/
|
||||
MultipleInstructionMetadata &SetRelevantForLayoutEventsOnly() override {
|
||||
if (condition) condition->SetRelevantForLayoutEventsOnly();
|
||||
if (action) action->SetRelevantForLayoutEventsOnly();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that the instruction can be used in function events.
|
||||
*/
|
||||
MultipleInstructionMetadata &SetRelevantForFunctionEventsOnly() override {
|
||||
if (condition) condition->SetRelevantForFunctionEventsOnly();
|
||||
if (action) action->SetRelevantForFunctionEventsOnly();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that the instruction can be used in asynchronous function events.
|
||||
*/
|
||||
MultipleInstructionMetadata &SetRelevantForAsynchronousFunctionEventsOnly() override {
|
||||
if (condition) condition->SetRelevantForAsynchronousFunctionEventsOnly();
|
||||
if (action) action->SetRelevantForAsynchronousFunctionEventsOnly();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that the instruction can be used in custom object events.
|
||||
*/
|
||||
MultipleInstructionMetadata &SetRelevantForCustomObjectEventsOnly() override {
|
||||
if (condition) condition->SetRelevantForCustomObjectEventsOnly();
|
||||
if (action) action->SetRelevantForCustomObjectEventsOnly();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Don't use, only here to fulfill Emscripten bindings requirements.
|
||||
*/
|
||||
@@ -242,5 +278,3 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // MULTIPLEINSTRUCTIONSMETADATA_H
|
||||
|
@@ -3,8 +3,10 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef OBJECTMETADATA_H
|
||||
#define OBJECTMETADATA_H
|
||||
#pragma once
|
||||
|
||||
#include "InstructionOrExpressionContainerMetadata.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
@@ -32,7 +34,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API ObjectMetadata {
|
||||
class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetadata {
|
||||
public:
|
||||
/**
|
||||
* \brief Construct an object metadata, using a "blueprint" object that will
|
||||
@@ -57,7 +59,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
|
||||
/**
|
||||
* \brief Construct an object metadata, with a function that will be called
|
||||
* to instanciate a new object.
|
||||
* to instantiate a new object.
|
||||
*/
|
||||
ObjectMetadata(const gd::String& extensionNamespace_,
|
||||
const gd::String& name_,
|
||||
@@ -79,7 +81,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* \brief Declare a new action as being part of the extension.
|
||||
@@ -92,7 +94,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* Declare a new condition as being part of the object.
|
||||
@@ -103,7 +105,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* Declare a new action as being part of the object.
|
||||
@@ -114,7 +116,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression as being part of the extension.
|
||||
@@ -123,7 +125,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
/**
|
||||
* \brief Declare a new string expression as being part of the extension.
|
||||
*/
|
||||
@@ -131,7 +133,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression and condition as being part of the
|
||||
@@ -146,7 +148,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& description,
|
||||
const gd::String& sentenceName,
|
||||
const gd::String& group,
|
||||
const gd::String& icon);
|
||||
const gd::String& icon) override;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression, condition and action as being part of the
|
||||
@@ -163,7 +165,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& description,
|
||||
const gd::String& sentenceName,
|
||||
const gd::String& group,
|
||||
const gd::String& icon);
|
||||
const gd::String& icon) override;
|
||||
|
||||
/**
|
||||
* \brief Create a new action which is the duplicate of the specified one.
|
||||
@@ -172,7 +174,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
* one.
|
||||
*/
|
||||
gd::InstructionMetadata& AddDuplicatedAction(
|
||||
const gd::String& newActionName, const gd::String& copiedActionName);
|
||||
const gd::String& newActionName, const gd::String& copiedActionName) override;
|
||||
|
||||
/**
|
||||
* \brief Create a new condition which is the duplicate of the specified one.
|
||||
@@ -182,23 +184,23 @@ class GD_CORE_API ObjectMetadata {
|
||||
*/
|
||||
gd::InstructionMetadata& AddDuplicatedCondition(
|
||||
const gd::String& newConditionName,
|
||||
const gd::String& copiedConditionName);
|
||||
const gd::String& copiedConditionName) override;
|
||||
|
||||
/**
|
||||
* \brief Set the name shown to the user.
|
||||
*/
|
||||
ObjectMetadata& SetFullName(const gd::String& fullname_);
|
||||
ObjectMetadata& SetFullName(const gd::String& fullname_) override;
|
||||
|
||||
/**
|
||||
* \brief Set the description shown to the user.
|
||||
*/
|
||||
ObjectMetadata& SetDescription(const gd::String& description_);
|
||||
ObjectMetadata& SetDescription(const gd::String& description_) override;
|
||||
|
||||
/**
|
||||
* \brief Get the help path of the object, relative to the GDevelop
|
||||
* documentation root.
|
||||
*/
|
||||
const gd::String& GetHelpPath() const { return helpPath; }
|
||||
const gd::String& GetHelpPath() const override { return helpPath; }
|
||||
|
||||
/**
|
||||
* \brief Set the help path of the object, relative to the GDevelop
|
||||
@@ -207,7 +209,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
* The object instructions will have this help path set by
|
||||
* default, unless you call SetHelpPath on them.
|
||||
*/
|
||||
ObjectMetadata& SetHelpPath(const gd::String& path) {
|
||||
ObjectMetadata& SetHelpPath(const gd::String& path) override {
|
||||
helpPath = path;
|
||||
return *this;
|
||||
}
|
||||
@@ -222,38 +224,34 @@ class GD_CORE_API ObjectMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief The "capabilities" that are offered by the base object that are
|
||||
* *not* supported by this object, and should be hidden in the editor
|
||||
* inferface.
|
||||
* \brief The "capabilities" that are offered by through behaviors.
|
||||
*/
|
||||
const std::set<gd::String>& GetUnsupportedBaseObjectCapabilities() const {
|
||||
return unsupportedBaseObjectCapabilities;
|
||||
const std::set<gd::String>& GetDefaultBehaviors() const {
|
||||
return defaultBehaviorTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a "capability" that is offered by the base object that is *not*
|
||||
* supported by this object, and should be hidden in the editor inferface.
|
||||
* \brief Return true if object has a default behavior of the given type.
|
||||
*/
|
||||
ObjectMetadata& AddUnsupportedBaseObjectCapability(
|
||||
const gd::String& capability) {
|
||||
unsupportedBaseObjectCapabilities.insert(capability);
|
||||
bool HasDefaultBehavior(const gd::String& behaviorType) const {
|
||||
return defaultBehaviorTypes.find(behaviorType) != defaultBehaviorTypes.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a "capability" that is offered by through a behavior.
|
||||
*/
|
||||
ObjectMetadata& AddDefaultBehavior(
|
||||
const gd::String& behaviorType) {
|
||||
defaultBehaviorTypes.insert(behaviorType);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if a "capability" that is offered by the base object is *not*
|
||||
* supported by this object, and should be hidden in the editor inferface.
|
||||
*/
|
||||
bool IsUnsupportedBaseObjectCapability(const gd::String& capability) const {
|
||||
return unsupportedBaseObjectCapabilities.find(capability) != unsupportedBaseObjectCapabilities.end();
|
||||
}
|
||||
|
||||
const gd::String& GetName() const { return name; }
|
||||
const gd::String& GetFullName() const { return fullname; }
|
||||
const gd::String& GetName() const override { return name; }
|
||||
const gd::String& GetFullName() const override { return fullname; }
|
||||
const gd::String& GetCategoryFullName() const { return categoryFullName; }
|
||||
const gd::String& GetHelpUrl() const { return helpUrl; }
|
||||
const gd::String& GetDescription() const { return description; }
|
||||
const gd::String& GetIconFilename() const { return iconFilename; }
|
||||
const gd::String& GetDescription() const override { return description; }
|
||||
const gd::String& GetIconFilename() const override { return iconFilename; }
|
||||
|
||||
/**
|
||||
* \brief Set the URL pointing to the help page about this object
|
||||
@@ -267,33 +265,33 @@ class GD_CORE_API ObjectMetadata {
|
||||
* \note The requirement may vary depending on the platform: Most of the time,
|
||||
* the include file contains the declaration of the object.
|
||||
*/
|
||||
ObjectMetadata& SetIncludeFile(const gd::String& includeFile);
|
||||
ObjectMetadata& SetIncludeFile(const gd::String& includeFile) override;
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
ObjectMetadata& AddIncludeFile(const gd::String& includeFile);
|
||||
ObjectMetadata& AddIncludeFile(const gd::String& includeFile) override;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a map containing the names of the actions
|
||||
* (as keys) and the metadata associated with (as values).
|
||||
*/
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllActions() { return actionsInfos; };
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllActions() override { return actionsInfos; };
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllConditions() { return conditionsInfos; };
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllConditions() override { return conditionsInfos; };
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllExpressions() { return expressionsInfos; };
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllExpressions() override { return expressionsInfos; };
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() { return strExpressionsInfos; };
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() override { return strExpressionsInfos; };
|
||||
|
||||
/**
|
||||
* \brief Set the object to be hidden in the IDE.
|
||||
@@ -305,12 +303,24 @@ class GD_CORE_API ObjectMetadata {
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return true if the instruction must be hidden in the IDE.
|
||||
* \brief Return true if the object must be hidden in the IDE.
|
||||
*/
|
||||
bool IsHidden() const { return hidden; }
|
||||
|
||||
/**
|
||||
* \brief Declare a usage of the 3D renderer.
|
||||
*/
|
||||
ObjectMetadata &MarkAsRenderedIn3D() {
|
||||
isRenderedIn3D = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if the object uses the 3D renderer.
|
||||
*/
|
||||
bool IsRenderedIn3D() const { return isRenderedIn3D; }
|
||||
|
||||
std::map<gd::String, gd::InstructionMetadata> conditionsInfos;
|
||||
std::map<gd::String, gd::InstructionMetadata> actionsInfos;
|
||||
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
|
||||
@@ -329,8 +339,9 @@ class GD_CORE_API ObjectMetadata {
|
||||
gd::String description;
|
||||
gd::String iconFilename;
|
||||
gd::String categoryFullName;
|
||||
std::set<gd::String> unsupportedBaseObjectCapabilities;
|
||||
std::set<gd::String> defaultBehaviorTypes;
|
||||
bool hidden = false;
|
||||
bool isRenderedIn3D = false;
|
||||
|
||||
std::shared_ptr<gd::ObjectConfiguration>
|
||||
blueprintObject; ///< The "blueprint" object to be copied when a new
|
||||
@@ -341,4 +352,3 @@ class GD_CORE_API ObjectMetadata {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
#endif // OBJECTMETADATA_H
|
||||
|
@@ -34,6 +34,11 @@ class GD_CORE_API ParameterMetadata {
|
||||
*/
|
||||
gd::ValueTypeMetadata &GetValueTypeMetadata() { return valueTypeMetadata; }
|
||||
|
||||
/**
|
||||
* \brief Return the metadata of the parameter type.
|
||||
*/
|
||||
const gd::ValueTypeMetadata &GetValueTypeMetadata() const { return valueTypeMetadata; }
|
||||
|
||||
/**
|
||||
* \brief Set the metadata of the parameter type.
|
||||
*/
|
||||
@@ -209,10 +214,10 @@ class GD_CORE_API ParameterMetadata {
|
||||
* \brief Return the expression type from the parameter type.
|
||||
* Declinations of "number" and "string" types (like "forceMultiplier" or
|
||||
* "sceneName") are replaced by "number" and "string".
|
||||
* \deprecated Use gd::ValueTypeMetadata instead.
|
||||
* \deprecated Use gd::ValueTypeMetadata or gd::GetExpressionPrimitiveValueType instead.
|
||||
*/
|
||||
static const gd::String &GetExpressionValueType(const gd::String ¶meterType) {
|
||||
return gd::ValueTypeMetadata::GetPrimitiveValueType(parameterType);
|
||||
return gd::ValueTypeMetadata::GetExpressionPrimitiveValueType(parameterType);
|
||||
}
|
||||
|
||||
/** \name Serialization
|
||||
|
@@ -8,11 +8,16 @@
|
||||
#include "GDCore/Events/Expression.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/ObjectsContainersList.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "InstructionMetadata.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodePrinter.h"
|
||||
|
||||
namespace gd {
|
||||
const ParameterMetadata ParameterMetadataTools::badParameterMetadata;
|
||||
|
||||
void ParameterMetadataTools::ParametersToObjectsContainer(
|
||||
const gd::Project& project,
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
@@ -55,6 +60,55 @@ void ParameterMetadataTools::ParametersToObjectsContainer(
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterMetadataTools::ForEachParameterMatchingSearch(
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>&
|
||||
parametersVectorsList,
|
||||
const gd::String& search,
|
||||
std::function<void(const gd::ParameterMetadata&)> cb) {
|
||||
for (auto it = parametersVectorsList.rbegin();
|
||||
it != parametersVectorsList.rend();
|
||||
++it) {
|
||||
const std::vector<gd::ParameterMetadata>* parametersVector = *it;
|
||||
|
||||
for (const auto& parameterMetadata: *parametersVector) {
|
||||
if (parameterMetadata.GetName().FindCaseInsensitive(search) != gd::String::npos) cb(parameterMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ParameterMetadataTools::Has(
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
|
||||
const gd::String& parameterName) {
|
||||
for (auto it = parametersVectorsList.rbegin();
|
||||
it != parametersVectorsList.rend();
|
||||
++it) {
|
||||
const std::vector<gd::ParameterMetadata>* parametersVector = *it;
|
||||
|
||||
for (const auto& parameterMetadata: *parametersVector) {
|
||||
if (parameterMetadata.GetName() == parameterName) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const gd::ParameterMetadata& ParameterMetadataTools::Get(
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>&
|
||||
parametersVectorsList,
|
||||
const gd::String& parameterName) {
|
||||
for (auto it = parametersVectorsList.rbegin();
|
||||
it != parametersVectorsList.rend();
|
||||
++it) {
|
||||
const std::vector<gd::ParameterMetadata>* parametersVector = *it;
|
||||
|
||||
for (const auto& parameterMetadata: *parametersVector) {
|
||||
if (parameterMetadata.GetName() == parameterName) return parameterMetadata;
|
||||
}
|
||||
}
|
||||
|
||||
return badParameterMetadata;
|
||||
}
|
||||
|
||||
void ParameterMetadataTools::IterateOverParameters(
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
@@ -101,6 +155,54 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
const gd::Platform &platform,
|
||||
const gd::ObjectsContainersList &objectsContainersList, FunctionCallNode &node,
|
||||
std::function<void(const gd::ParameterMetadata ¶meterMetadata,
|
||||
std::unique_ptr<gd::ExpressionNode> ¶meterNode,
|
||||
size_t parameterIndex, const gd::String &lastObjectName)>
|
||||
fn) {
|
||||
gd::String lastObjectName = node.objectName;
|
||||
|
||||
const bool isObjectFunction = !node.objectName.empty();
|
||||
const gd::ExpressionMetadata &metadata =
|
||||
isObjectFunction ? MetadataProvider::GetObjectAnyExpressionMetadata(
|
||||
platform,
|
||||
objectsContainersList.GetTypeOfObject(node.objectName),
|
||||
node.functionName)
|
||||
: MetadataProvider::GetAnyExpressionMetadata(
|
||||
platform, node.functionName);
|
||||
|
||||
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata)) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t parameterIndex = 0;
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0);
|
||||
metadataIndex < metadata.parameters.size() &&
|
||||
parameterIndex < node.parameters.size();
|
||||
++metadataIndex) {
|
||||
auto ¶meterMetadata = metadata.parameters[metadataIndex];
|
||||
if (parameterMetadata.IsCodeOnly()) {
|
||||
continue;
|
||||
}
|
||||
auto ¶meterNode = node.parameters[parameterIndex];
|
||||
++parameterIndex;
|
||||
|
||||
fn(parameterMetadata, parameterNode, parameterIndex, lastObjectName);
|
||||
|
||||
// Memorize the last object name. By convention, parameters that require
|
||||
// an object (mainly, "objectvar" and "behavior") should be placed after
|
||||
// the object in the list of parameters (if possible, just after).
|
||||
// Search "lastObjectName" in the codebase for other place where this
|
||||
// convention is enforced.
|
||||
if (gd::ParameterMetadata::IsObject(parameterMetadata.GetType()))
|
||||
// Object can't be expressions so it should always be the object name.
|
||||
lastObjectName =
|
||||
gd::ExpressionParser2NodePrinter::PrintNode(*parameterNode);
|
||||
}
|
||||
}
|
||||
|
||||
size_t ParameterMetadataTools::GetObjectParameterIndexFor(
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
size_t parameterIndex) {
|
||||
|
@@ -3,16 +3,20 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef ParameterMetadataTools_H
|
||||
#define ParameterMetadataTools_H
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Platform;
|
||||
class Project;
|
||||
class ObjectsContainer;
|
||||
class ObjectsContainersList;
|
||||
class ParameterMetadata;
|
||||
class Expression;
|
||||
struct FunctionCallNode;
|
||||
struct ExpressionNode;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -23,6 +27,19 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
gd::ObjectsContainer& outputObjectsContainer);
|
||||
|
||||
static void ForEachParameterMatchingSearch(
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
|
||||
const gd::String& search,
|
||||
std::function<void(const gd::ParameterMetadata&)> cb);
|
||||
|
||||
static bool Has(
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
|
||||
const gd::String& parameterName);
|
||||
|
||||
static const gd::ParameterMetadata& Get(
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
|
||||
const gd::String& parameterName);
|
||||
|
||||
/**
|
||||
* Iterate over a list of parameters and their values.
|
||||
* Callback function is called with the parameter metadata, its value
|
||||
@@ -48,6 +65,20 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName)> fn);
|
||||
|
||||
/**
|
||||
* Iterate over the parameters of a FunctionCallNode.
|
||||
* Callback function is called with the parameter metadata, its value
|
||||
* and if applicable the name of the object it's linked to.
|
||||
*/
|
||||
static void IterateOverParametersWithIndex(
|
||||
const gd::Platform &platform,
|
||||
const gd::ObjectsContainersList &objectsContainersList, FunctionCallNode &node,
|
||||
std::function<void(const gd::ParameterMetadata ¶meterMetadata,
|
||||
std::unique_ptr<gd::ExpressionNode> ¶meterNode,
|
||||
size_t parameterIndex,
|
||||
const gd::String &lastObjectName)>
|
||||
fn);
|
||||
|
||||
/**
|
||||
* Given a parameter, return, if applicable, the index of the object parameter
|
||||
* it's linked to.
|
||||
@@ -55,8 +86,8 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
static size_t GetObjectParameterIndexFor(
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
size_t parameterIndex);
|
||||
|
||||
private:
|
||||
static const gd::ParameterMetadata badParameterMetadata;
|
||||
};
|
||||
} // namespace gd
|
||||
|
||||
#endif // ParameterMetadataTools_H
|
||||
#endif
|
||||
|
@@ -35,17 +35,40 @@ void ValueTypeMetadata::UnserializeFrom(const SerializerElement& element) {
|
||||
|
||||
const gd::String ValueTypeMetadata::numberType = "number";
|
||||
const gd::String ValueTypeMetadata::stringType = "string";
|
||||
const gd::String ValueTypeMetadata::variableType = "variable";
|
||||
const gd::String ValueTypeMetadata::booleanType = "boolean";
|
||||
|
||||
const gd::String &ValueTypeMetadata::GetPrimitiveValueType(const gd::String ¶meterType) {
|
||||
if (parameterType == "number" || gd::ValueTypeMetadata::IsTypeExpression("number", parameterType)) {
|
||||
const gd::String &ValueTypeMetadata::GetExpressionPrimitiveValueType(
|
||||
const gd::String ¶meterType) {
|
||||
if (parameterType == "number" ||
|
||||
gd::ValueTypeMetadata::IsTypeExpression("number", parameterType)) {
|
||||
return ValueTypeMetadata::numberType;
|
||||
}
|
||||
if (parameterType == "string" || gd::ValueTypeMetadata::IsTypeExpression("string", parameterType)) {
|
||||
if (parameterType == "string" ||
|
||||
gd::ValueTypeMetadata::IsTypeExpression("string", parameterType)) {
|
||||
return ValueTypeMetadata::stringType;
|
||||
}
|
||||
return parameterType;
|
||||
}
|
||||
|
||||
const gd::String &
|
||||
ValueTypeMetadata::GetPrimitiveValueType(const gd::String ¶meterType) {
|
||||
if (parameterType == "variable" ||
|
||||
gd::ValueTypeMetadata::IsTypeExpression("variable", parameterType)) {
|
||||
return ValueTypeMetadata::variableType;
|
||||
}
|
||||
if (parameterType == "boolean" || parameterType == "yesorno" ||
|
||||
parameterType == "trueorfalse") {
|
||||
return ValueTypeMetadata::booleanType;
|
||||
}
|
||||
// These 2 types are not strings from the code generator point of view,
|
||||
// but it is for event-based extensions.
|
||||
if (parameterType == "key" || parameterType == "mouse") {
|
||||
return ValueTypeMetadata::stringType;
|
||||
}
|
||||
return GetExpressionPrimitiveValueType(parameterType);
|
||||
}
|
||||
|
||||
const gd::String ValueTypeMetadata::numberValueType = "number";
|
||||
const gd::String ValueTypeMetadata::booleanValueType = "boolean";
|
||||
const gd::String ValueTypeMetadata::colorValueType = "color";
|
||||
|
@@ -121,6 +121,13 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
return gd::ValueTypeMetadata::IsTypeExpression("string", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if the type is a boolean.
|
||||
*/
|
||||
bool IsBoolean() const {
|
||||
return gd::ValueTypeMetadata::IsTypeExpression("boolean", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if the type of the parameter is a number.
|
||||
* \note If you had a new type of parameter, also add it in the IDE (
|
||||
@@ -131,6 +138,24 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
return gd::ValueTypeMetadata::IsTypeExpression("variable", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if the type is a variable but from a specific scope
|
||||
* (scene, project or object). In new code, prefer to use the more generic "variable"
|
||||
* parameter (which accepts any variable coming from an object or from containers in the scope).
|
||||
*/
|
||||
bool IsLegacyPreScopedVariable() const {
|
||||
return gd::ValueTypeMetadata::IsTypeLegacyPreScopedVariable(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if the type is a variable but from a specific scope
|
||||
* (scene, project or object). In new code, prefer to use the more generic "variable"
|
||||
* parameter (which accepts any variable coming from an object or from containers in the scope).
|
||||
*/
|
||||
static bool IsTypeLegacyPreScopedVariable(const gd::String &type) {
|
||||
return type == "scenevar" || type == "globalvar" || type == "objectvar";
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if the type is representing one object
|
||||
* (or more, i.e: an object group).
|
||||
@@ -163,7 +188,6 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
} else if (type == "string") {
|
||||
return parameterType == "string" || parameterType == "layer" ||
|
||||
parameterType == "color" || parameterType == "file" ||
|
||||
parameterType == "joyaxis" ||
|
||||
parameterType == "stringWithSelector" ||
|
||||
parameterType == "sceneName" ||
|
||||
parameterType == "layerEffectName" ||
|
||||
@@ -176,9 +200,24 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
parameterType == "externalLayoutName" ||
|
||||
parameterType == "leaderboardId" ||
|
||||
parameterType == "identifier";
|
||||
} else if (type == "boolean") {
|
||||
return parameterType == "yesorno" || parameterType == "trueorfalse";
|
||||
} else if (type == "variable") {
|
||||
return parameterType == "objectvar" || parameterType == "globalvar" ||
|
||||
return
|
||||
parameterType == "variable" || // Any variable.
|
||||
// Old, "pre-scoped" variables:
|
||||
parameterType == "objectvar" || parameterType == "globalvar" ||
|
||||
parameterType == "scenevar";
|
||||
} else if (type == "resource") {
|
||||
return parameterType == "fontResource" ||
|
||||
parameterType == "soundfile" ||
|
||||
parameterType == "musicfile" ||
|
||||
parameterType == "bitmapFontResource" ||
|
||||
parameterType == "imageResource" ||
|
||||
parameterType == "jsonResource" ||
|
||||
parameterType == "tilemapResource" ||
|
||||
parameterType == "tilesetResource" ||
|
||||
parameterType == "model3DResource";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -187,10 +226,23 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
* \brief Return the expression type from the parameter type.
|
||||
* Declinations of "number" and "string" types (like "forceMultiplier" or
|
||||
* "sceneName") are replaced by "number" and "string".
|
||||
*
|
||||
* \note It only maps string and number types.
|
||||
*/
|
||||
static const gd::String &GetExpressionPrimitiveValueType(const gd::String ¶meterType);
|
||||
|
||||
/**
|
||||
* \brief Return the primitive type from the parameter type.
|
||||
* Declinations of "number" and "string" types (like "forceMultiplier" or
|
||||
* "sceneName") are replaced by "number" and "string".
|
||||
*
|
||||
* \note It also maps variable and boolean types.
|
||||
*/
|
||||
static const gd::String &GetPrimitiveValueType(const gd::String ¶meterType);
|
||||
static const gd::String numberType;
|
||||
static const gd::String stringType;
|
||||
static const gd::String variableType;
|
||||
static const gd::String booleanType;
|
||||
|
||||
/**
|
||||
* \brief Return the ValueTypeMetadata name for a property type.
|
||||
|
@@ -273,25 +273,6 @@ gd::BehaviorMetadata& PlatformExtension::AddBehavior(
|
||||
return behaviorsInfo[nameWithNamespace];
|
||||
}
|
||||
|
||||
gd::BehaviorMetadata& PlatformExtension::AddEventsBasedBehavior(
|
||||
const gd::String& name,
|
||||
const gd::String& fullname,
|
||||
const gd::String& description,
|
||||
const gd::String& group,
|
||||
const gd::String& icon24x24) {
|
||||
gd::String nameWithNamespace = GetNameSpace() + name;
|
||||
behaviorsInfo[nameWithNamespace] = BehaviorMetadata(GetNameSpace(),
|
||||
nameWithNamespace,
|
||||
fullname,
|
||||
// Default name is the name
|
||||
name,
|
||||
description,
|
||||
group,
|
||||
icon24x24)
|
||||
.SetHelpPath(GetHelpPath());
|
||||
return behaviorsInfo[nameWithNamespace];
|
||||
}
|
||||
|
||||
gd::EffectMetadata& PlatformExtension::AddEffect(const gd::String& name) {
|
||||
gd::String nameWithNamespace = GetNameSpace() + name;
|
||||
effectsMetadata[nameWithNamespace] = EffectMetadata(nameWithNamespace);
|
||||
@@ -653,7 +634,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
GetAllActions().begin();
|
||||
it != GetAllActions().end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
GetAllActions().erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -663,7 +644,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
GetAllConditions().begin();
|
||||
it != GetAllConditions().end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
GetAllConditions().erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -673,7 +654,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
GetAllExpressions().begin();
|
||||
it != GetAllExpressions().end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
GetAllExpressions().erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -683,7 +664,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
GetAllStrExpressions().begin();
|
||||
it != GetAllStrExpressions().end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
GetAllStrExpressions().erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -699,7 +680,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.actionsInfos.begin();
|
||||
it != obj.actionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.actionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -709,7 +690,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.conditionsInfos.begin();
|
||||
it != obj.conditionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.conditionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -719,7 +700,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.expressionsInfos.begin();
|
||||
it != obj.expressionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.expressionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -729,7 +710,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.strExpressionsInfos.begin();
|
||||
it != obj.strExpressionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.strExpressionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -746,7 +727,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.actionsInfos.begin();
|
||||
it != obj.actionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.actionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -756,7 +737,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.conditionsInfos.begin();
|
||||
it != obj.conditionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.conditionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -766,7 +747,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.expressionsInfos.begin();
|
||||
it != obj.expressionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.expressionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -776,7 +757,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.strExpressionsInfos.begin();
|
||||
it != obj.strExpressionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.strExpressionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
|
@@ -421,6 +421,32 @@ class GD_CORE_API PlatformExtension {
|
||||
*/
|
||||
const gd::String& GetIconUrl() const { return iconUrl; }
|
||||
|
||||
/**
|
||||
* \brief Return keywords that help search engines find this extension.
|
||||
*/
|
||||
const std::vector<gd::String>& GetTags() const { return tags; }
|
||||
|
||||
/**
|
||||
* \brief Set keywords that help search engines find this extension.
|
||||
*/
|
||||
PlatformExtension& SetTags(const gd::String& csvTags) {
|
||||
tags.clear();
|
||||
tags = csvTags.Split(',');
|
||||
for (size_t i = 0; i < tags.size(); i++)
|
||||
{
|
||||
tags[i] = tags[i].Trim().LowerCase();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a keyword that help search engines find this extension.
|
||||
*/
|
||||
PlatformExtension& AddTag(const gd::String& tag) {
|
||||
tags.push_back(tag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if the extension is flagged as being deprecated.
|
||||
*/
|
||||
@@ -661,6 +687,7 @@ private:
|
||||
gd::String helpPath; ///< The relative path to the help for this extension in
|
||||
///< the documentation.
|
||||
gd::String iconUrl; ///< The URL to the icon to be shown for this extension.
|
||||
std::vector<gd::String> tags;
|
||||
|
||||
std::map<gd::String, gd::ObjectMetadata> objectsInfos;
|
||||
std::map<gd::String, gd::BehaviorMetadata> behaviorsInfo;
|
||||
|
@@ -42,7 +42,7 @@ class GD_CORE_API DependenciesAnalyzer {
|
||||
*
|
||||
* You can also call then
|
||||
* DependenciesAnalyzer::ExternalEventsCanBeCompiledForAScene to check if the
|
||||
* external events can be compiled separatly and called by a scene. \see
|
||||
* external events can be compiled separately and called by a scene. \see
|
||||
* DependenciesAnalyzer::ExternalEventsCanBeCompiledForAScene
|
||||
*/
|
||||
DependenciesAnalyzer(const gd::Project& project_,
|
||||
|
@@ -11,6 +11,8 @@
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Events/Expression.h"
|
||||
#include "GDCore/Extensions/Metadata/ParameterMetadata.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -23,7 +25,7 @@ void ArbitraryEventsWorker::VisitEventList(gd::EventsList& events) {
|
||||
DoVisitEventList(events);
|
||||
|
||||
for (std::size_t i = 0; i < events.size();) {
|
||||
if (VisitEvent(events[i]))
|
||||
if (events[i].AcceptVisitor(*this))
|
||||
events.RemoveEvent(i);
|
||||
else {
|
||||
if (events[i].CanHaveSubEvents())
|
||||
@@ -47,7 +49,18 @@ bool ArbitraryEventsWorker::VisitEvent(gd::BaseEvent& event) {
|
||||
for (std::size_t j = 0; j < actionsVectors.size(); ++j)
|
||||
VisitInstructionList(*actionsVectors[j], false);
|
||||
|
||||
return false;
|
||||
auto allExpressionsWithMetadata = event.GetAllExpressionsWithMetadata();
|
||||
for (auto& expressionAndMetadata : allExpressionsWithMetadata) {
|
||||
shouldDelete |= VisitEventExpression(
|
||||
*expressionAndMetadata.first, expressionAndMetadata.second);
|
||||
}
|
||||
|
||||
|
||||
return shouldDelete;
|
||||
}
|
||||
|
||||
bool ArbitraryEventsWorker::VisitLinkEvent(gd::LinkEvent& linkEvent) {
|
||||
return DoVisitLinkEvent(linkEvent);
|
||||
}
|
||||
|
||||
void ArbitraryEventsWorker::VisitInstructionList(
|
||||
@@ -71,6 +84,11 @@ bool ArbitraryEventsWorker::VisitInstruction(gd::Instruction& instruction,
|
||||
return DoVisitInstruction(instruction, isCondition);
|
||||
}
|
||||
|
||||
bool ArbitraryEventsWorker::VisitEventExpression(gd::Expression& expression,
|
||||
const gd::ParameterMetadata& metadata) {
|
||||
return DoVisitEventExpression(expression, metadata);
|
||||
}
|
||||
|
||||
ArbitraryEventsWorkerWithContext::~ArbitraryEventsWorkerWithContext() {}
|
||||
|
||||
|
||||
@@ -80,7 +98,10 @@ void ReadOnlyArbitraryEventsWorker::VisitEventList(const gd::EventsList& events)
|
||||
DoVisitEventList(events);
|
||||
|
||||
for (std::size_t i = 0; i < events.size(); ++i) {
|
||||
VisitEvent(events[i]);
|
||||
if (shouldStopIteration) {
|
||||
break;
|
||||
}
|
||||
events[i].AcceptVisitor(*this);
|
||||
|
||||
if (events[i].CanHaveSubEvents()) {
|
||||
VisitEventList(events[i].GetSubEvents());
|
||||
@@ -94,20 +115,33 @@ void ReadOnlyArbitraryEventsWorker::VisitEvent(const gd::BaseEvent& event) {
|
||||
const vector<const gd::InstructionsList*> conditionsVectors =
|
||||
event.GetAllConditionsVectors();
|
||||
for (std::size_t j = 0; j < conditionsVectors.size(); ++j) {
|
||||
if (shouldStopIteration) {
|
||||
break;
|
||||
}
|
||||
VisitInstructionList(*conditionsVectors[j], true);
|
||||
}
|
||||
|
||||
const vector<const gd::InstructionsList*> actionsVectors = event.GetAllActionsVectors();
|
||||
for (std::size_t j = 0; j < actionsVectors.size(); ++j) {
|
||||
if (shouldStopIteration) {
|
||||
break;
|
||||
}
|
||||
VisitInstructionList(*actionsVectors[j], false);
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::VisitLinkEvent(const gd::LinkEvent& linkEvent) {
|
||||
DoVisitLinkEvent(linkEvent);
|
||||
}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::VisitInstructionList(
|
||||
const gd::InstructionsList& instructions, bool areConditions) {
|
||||
DoVisitInstructionList(instructions, areConditions);
|
||||
|
||||
for (std::size_t i = 0; i < instructions.size(); ++i) {
|
||||
if (shouldStopIteration) {
|
||||
break;
|
||||
}
|
||||
VisitInstruction(instructions[i], areConditions);
|
||||
if (!instructions[i].GetSubInstructions().empty()) {
|
||||
VisitInstructionList(instructions[i].GetSubInstructions(),
|
||||
@@ -121,6 +155,16 @@ void ReadOnlyArbitraryEventsWorker::VisitInstruction(const gd::Instruction& inst
|
||||
DoVisitInstruction(instruction, isCondition);
|
||||
}
|
||||
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::VisitEventExpression(const gd::Expression& expression,
|
||||
const gd::ParameterMetadata& metadata) {
|
||||
DoVisitEventExpression(expression, metadata);
|
||||
}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::StopAnyEventIteration() {
|
||||
shouldStopIteration = true;
|
||||
}
|
||||
|
||||
ReadOnlyArbitraryEventsWorkerWithContext::~ReadOnlyArbitraryEventsWorkerWithContext() {}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -9,12 +9,17 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "GDCore/Events/InstructionsList.h"
|
||||
#include "GDCore/Events/EventVisitor.h"
|
||||
#include "GDCore/Project/ProjectScopedContainers.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
class BaseEvent;
|
||||
class LinkEvent;
|
||||
class EventsList;
|
||||
class ObjectsContainer;
|
||||
class Expression;
|
||||
class ParameterMetadata;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -28,7 +33,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ArbitraryEventsWorker {
|
||||
class GD_CORE_API ArbitraryEventsWorker : private EventVisitor {
|
||||
public:
|
||||
ArbitraryEventsWorker(){};
|
||||
virtual ~ArbitraryEventsWorker();
|
||||
@@ -40,10 +45,12 @@ class GD_CORE_API ArbitraryEventsWorker {
|
||||
|
||||
private:
|
||||
void VisitEventList(gd::EventsList& events);
|
||||
bool VisitEvent(gd::BaseEvent& event);
|
||||
bool VisitEvent(gd::BaseEvent& event) override;
|
||||
bool VisitLinkEvent(gd::LinkEvent& linkEvent) override;
|
||||
void VisitInstructionList(gd::InstructionsList& instructions,
|
||||
bool areConditions);
|
||||
bool VisitInstruction(gd::Instruction& instruction, bool isCondition);
|
||||
bool VisitEventExpression(gd::Expression& expression, const gd::ParameterMetadata& metadata);
|
||||
|
||||
/**
|
||||
* Called to do some work on an event list.
|
||||
@@ -52,11 +59,21 @@ class GD_CORE_API ArbitraryEventsWorker {
|
||||
|
||||
/**
|
||||
* Called to do some work on an event
|
||||
* \return true if the instruction must be deleted from the events list, false
|
||||
* \return true if the event must be deleted from the events list, false
|
||||
* otherwise (default).
|
||||
*/
|
||||
virtual bool DoVisitEvent(gd::BaseEvent& event) { return false; };
|
||||
|
||||
/**
|
||||
* Called to do some work on a link event.
|
||||
*
|
||||
* Note that DoVisitEvent is also called with this event.
|
||||
*
|
||||
* \return true if the event must be deleted from the events list, false
|
||||
* otherwise (default).
|
||||
*/
|
||||
virtual bool DoVisitLinkEvent(gd::LinkEvent& event) { return false; };
|
||||
|
||||
/**
|
||||
* Called to do some work on an instruction list
|
||||
*/
|
||||
@@ -72,6 +89,16 @@ class GD_CORE_API ArbitraryEventsWorker {
|
||||
bool isCondition) {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Called to do some work on an expression of an event.
|
||||
* \return true if the event must be deleted from the list, false
|
||||
* otherwise (default).
|
||||
*/
|
||||
virtual bool DoVisitEventExpression(gd::Expression& expression,
|
||||
const gd::ParameterMetadata& metadata) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -86,8 +113,7 @@ class GD_CORE_API ArbitraryEventsWorkerWithContext
|
||||
: public ArbitraryEventsWorker {
|
||||
public:
|
||||
ArbitraryEventsWorkerWithContext()
|
||||
: currentGlobalObjectsContainer(nullptr),
|
||||
currentObjectsContainer(nullptr){};
|
||||
: projectScopedContainers(nullptr){};
|
||||
virtual ~ArbitraryEventsWorkerWithContext();
|
||||
|
||||
/**
|
||||
@@ -95,30 +121,27 @@ class GD_CORE_API ArbitraryEventsWorkerWithContext
|
||||
* giving the objects container on which the events are applying to.
|
||||
*/
|
||||
void Launch(gd::EventsList& events,
|
||||
const gd::ObjectsContainer& globalObjectsContainer_,
|
||||
const gd::ObjectsContainer& objectsContainer_) {
|
||||
currentGlobalObjectsContainer = &globalObjectsContainer_;
|
||||
currentObjectsContainer = &objectsContainer_;
|
||||
const gd::ProjectScopedContainers& projectScopedContainers_) {
|
||||
projectScopedContainers = &projectScopedContainers_;
|
||||
ArbitraryEventsWorker::Launch(events);
|
||||
};
|
||||
|
||||
void Launch(gd::EventsList& events) = delete;
|
||||
|
||||
protected:
|
||||
const gd::ObjectsContainer& GetGlobalObjectsContainer() {
|
||||
const gd::ProjectScopedContainers& GetProjectScopedContainers() {
|
||||
// Pointers are guaranteed to be not nullptr after
|
||||
// Launch was called.
|
||||
return *currentGlobalObjectsContainer;
|
||||
return *projectScopedContainers;
|
||||
};
|
||||
const gd::ObjectsContainer& GetObjectsContainer() {
|
||||
const gd::ObjectsContainersList& GetObjectsContainersList() {
|
||||
// Pointers are guaranteed to be not nullptr after
|
||||
// Launch was called.
|
||||
return *currentObjectsContainer;
|
||||
return projectScopedContainers->GetObjectsContainersList();
|
||||
};
|
||||
|
||||
private:
|
||||
const gd::ObjectsContainer* currentGlobalObjectsContainer;
|
||||
const gd::ObjectsContainer* currentObjectsContainer;
|
||||
const gd::ProjectScopedContainers* projectScopedContainers;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -129,9 +152,9 @@ class GD_CORE_API ArbitraryEventsWorkerWithContext
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ReadOnlyArbitraryEventsWorker {
|
||||
class GD_CORE_API ReadOnlyArbitraryEventsWorker : private ReadOnlyEventVisitor {
|
||||
public:
|
||||
ReadOnlyArbitraryEventsWorker(){};
|
||||
ReadOnlyArbitraryEventsWorker() : shouldStopIteration(false) {};
|
||||
virtual ~ReadOnlyArbitraryEventsWorker();
|
||||
|
||||
/**
|
||||
@@ -139,12 +162,17 @@ class GD_CORE_API ReadOnlyArbitraryEventsWorker {
|
||||
*/
|
||||
void Launch(const gd::EventsList& events) { VisitEventList(events); };
|
||||
|
||||
protected:
|
||||
void StopAnyEventIteration() override;
|
||||
|
||||
private:
|
||||
void VisitEventList(const gd::EventsList& events);
|
||||
void VisitEvent(const gd::BaseEvent& event);
|
||||
void VisitEvent(const gd::BaseEvent& event) override;
|
||||
void VisitLinkEvent(const gd::LinkEvent& linkEvent) override;
|
||||
void VisitInstructionList(const gd::InstructionsList& instructions,
|
||||
bool areConditions);
|
||||
void VisitInstruction(const gd::Instruction& instruction, bool isCondition);
|
||||
void VisitEventExpression(const gd::Expression& expression, const gd::ParameterMetadata& metadata);
|
||||
|
||||
/**
|
||||
* Called to do some work on an event list.
|
||||
@@ -156,6 +184,13 @@ class GD_CORE_API ReadOnlyArbitraryEventsWorker {
|
||||
*/
|
||||
virtual void DoVisitEvent(const gd::BaseEvent& event) {};
|
||||
|
||||
/**
|
||||
* Called to do some work on a link event.
|
||||
*
|
||||
* Note that DoVisitEvent is also called with this event.
|
||||
*/
|
||||
virtual void DoVisitLinkEvent(const gd::LinkEvent& linkEvent) {};
|
||||
|
||||
/**
|
||||
* Called to do some work on an instruction list
|
||||
*/
|
||||
@@ -167,6 +202,15 @@ class GD_CORE_API ReadOnlyArbitraryEventsWorker {
|
||||
*/
|
||||
virtual void DoVisitInstruction(const gd::Instruction& instruction,
|
||||
bool isCondition) {};
|
||||
|
||||
/**
|
||||
* Called to do some work on an expression of an event.
|
||||
*/
|
||||
virtual void DoVisitEventExpression(const gd::Expression& expression,
|
||||
const gd::ParameterMetadata& metadata) {
|
||||
}
|
||||
|
||||
bool shouldStopIteration;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -181,8 +225,7 @@ class GD_CORE_API ReadOnlyArbitraryEventsWorkerWithContext
|
||||
: public ReadOnlyArbitraryEventsWorker {
|
||||
public:
|
||||
ReadOnlyArbitraryEventsWorkerWithContext()
|
||||
: currentGlobalObjectsContainer(nullptr),
|
||||
currentObjectsContainer(nullptr){};
|
||||
: projectScopedContainers(nullptr){};
|
||||
virtual ~ReadOnlyArbitraryEventsWorkerWithContext();
|
||||
|
||||
/**
|
||||
@@ -190,30 +233,22 @@ class GD_CORE_API ReadOnlyArbitraryEventsWorkerWithContext
|
||||
* giving the objects container on which the events are applying to.
|
||||
*/
|
||||
void Launch(const gd::EventsList& events,
|
||||
const gd::ObjectsContainer& globalObjectsContainer_,
|
||||
const gd::ObjectsContainer& objectsContainer_) {
|
||||
currentGlobalObjectsContainer = &globalObjectsContainer_;
|
||||
currentObjectsContainer = &objectsContainer_;
|
||||
const gd::ProjectScopedContainers& projectScopedContainers_) {
|
||||
projectScopedContainers = &projectScopedContainers_;
|
||||
ReadOnlyArbitraryEventsWorker::Launch(events);
|
||||
};
|
||||
|
||||
void Launch(gd::EventsList& events) = delete;
|
||||
|
||||
protected:
|
||||
const gd::ObjectsContainer& GetGlobalObjectsContainer() {
|
||||
const gd::ProjectScopedContainers& GetProjectScopedContainers() {
|
||||
// Pointers are guaranteed to be not nullptr after
|
||||
// Launch was called.
|
||||
return *currentGlobalObjectsContainer;
|
||||
};
|
||||
const gd::ObjectsContainer& GetObjectsContainer() {
|
||||
// Pointers are guaranteed to be not nullptr after
|
||||
// Launch was called.
|
||||
return *currentObjectsContainer;
|
||||
return *projectScopedContainers;
|
||||
};
|
||||
|
||||
private:
|
||||
const gd::ObjectsContainer* currentGlobalObjectsContainer;
|
||||
const gd::ObjectsContainer* currentObjectsContainer;
|
||||
const gd::ProjectScopedContainers* projectScopedContainers;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
23
Core/GDCore/IDE/Events/BehaviorDefaultFlagClearer.cpp
Normal file
23
Core/GDCore/IDE/Events/BehaviorDefaultFlagClearer.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "BehaviorDefaultFlagClearer.h"
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/WholeProjectRefactorer.h"
|
||||
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
void BehaviorDefaultFlagClearer::DoVisitObject(gd::Object& object) {
|
||||
};
|
||||
|
||||
void BehaviorDefaultFlagClearer::DoVisitBehavior(gd::Behavior& behavior) {
|
||||
behavior.SetDefaultBehavior(false);
|
||||
};
|
||||
|
||||
BehaviorDefaultFlagClearer::~BehaviorDefaultFlagClearer() {}
|
||||
|
||||
} // namespace gd
|
34
Core/GDCore/IDE/Events/BehaviorDefaultFlagClearer.h
Normal file
34
Core/GDCore/IDE/Events/BehaviorDefaultFlagClearer.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <set>
|
||||
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class Object;
|
||||
class Behavior;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* @brief This is used for project exports to keep default behaviors in
|
||||
* serialized data used by Runtime.
|
||||
*/
|
||||
class GD_CORE_API BehaviorDefaultFlagClearer : public ArbitraryObjectsWorker {
|
||||
public:
|
||||
BehaviorDefaultFlagClearer() {};
|
||||
virtual ~BehaviorDefaultFlagClearer();
|
||||
|
||||
private:
|
||||
void DoVisitObject(gd::Object& object) override;
|
||||
void DoVisitBehavior(gd::Behavior& behavior) override;
|
||||
};
|
||||
|
||||
}; // namespace gd
|
@@ -4,7 +4,6 @@
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/WholeProjectRefactorer.h"
|
||||
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
@@ -4,7 +4,6 @@
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/WholeProjectRefactorer.h"
|
||||
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
@@ -31,14 +31,10 @@ namespace gd {
|
||||
class GD_CORE_API ExpressionBehaviorRenamer
|
||||
: public ExpressionParser2NodeWorker {
|
||||
public:
|
||||
ExpressionBehaviorRenamer(const gd::ObjectsContainer& globalObjectsContainer_,
|
||||
const gd::ObjectsContainer& objectsContainer_,
|
||||
const gd::String& objectName_,
|
||||
ExpressionBehaviorRenamer(const gd::String& objectName_,
|
||||
const gd::String& oldBehaviorName_,
|
||||
const gd::String& newBehaviorName_)
|
||||
: hasDoneRenaming(false),
|
||||
globalObjectsContainer(globalObjectsContainer_),
|
||||
objectsContainer(objectsContainer_),
|
||||
objectName(objectName_),
|
||||
oldBehaviorName(oldBehaviorName_),
|
||||
newBehaviorName(newBehaviorName_){};
|
||||
@@ -97,8 +93,6 @@ class GD_CORE_API ExpressionBehaviorRenamer
|
||||
|
||||
private:
|
||||
bool hasDoneRenaming;
|
||||
const gd::ObjectsContainer& globalObjectsContainer;
|
||||
const gd::ObjectsContainer& objectsContainer;
|
||||
const gd::String& objectName; // The object name for which the behavior
|
||||
// must be replaced.
|
||||
const gd::String& oldBehaviorName;
|
||||
@@ -132,9 +126,7 @@ bool EventsBehaviorRenamer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
} else {
|
||||
auto node = parameterValue.GetRootNode();
|
||||
if (node) {
|
||||
ExpressionBehaviorRenamer renamer(GetGlobalObjectsContainer(),
|
||||
GetObjectsContainer(),
|
||||
objectName,
|
||||
ExpressionBehaviorRenamer renamer(objectName,
|
||||
oldBehaviorName,
|
||||
newBehaviorName);
|
||||
node->Visit(renamer);
|
||||
|
@@ -19,6 +19,8 @@
|
||||
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/ObjectsContainersList.h"
|
||||
#include "GDCore/Project/ProjectScopedContainers.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
@@ -33,13 +35,11 @@ class GD_CORE_API ExpressionObjectsAnalyzer
|
||||
public:
|
||||
ExpressionObjectsAnalyzer(
|
||||
const gd::Platform &platform_,
|
||||
const gd::ObjectsContainer &globalObjectsContainer_,
|
||||
const gd::ObjectsContainer &objectsContainer_,
|
||||
const gd::ProjectScopedContainers &projectScopedContainers_,
|
||||
const gd::String &rootType_,
|
||||
EventsContext& context_) :
|
||||
platform(platform_),
|
||||
globalObjectsContainer(globalObjectsContainer_),
|
||||
objectsContainer(objectsContainer_),
|
||||
projectScopedContainers(projectScopedContainers_),
|
||||
rootType(rootType_),
|
||||
context(context_){};
|
||||
virtual ~ExpressionObjectsAnalyzer(){};
|
||||
@@ -58,6 +58,25 @@ class GD_CORE_API ExpressionObjectsAnalyzer
|
||||
void OnVisitNumberNode(NumberNode& node) override {}
|
||||
void OnVisitTextNode(TextNode& node) override {}
|
||||
void OnVisitVariableNode(VariableNode& node) override {
|
||||
auto type = gd::ExpressionTypeFinder::GetType(platform, projectScopedContainers, rootType, node);
|
||||
|
||||
if (gd::ParameterMetadata::IsExpression("variable", type)) {
|
||||
// Nothing to do (this can't reference an object)
|
||||
} else {
|
||||
projectScopedContainers.MatchIdentifierWithName<void>(node.name, [&]() {
|
||||
// This is an object variable.
|
||||
context.AddObjectName(projectScopedContainers, node.name);
|
||||
}, [&]() {
|
||||
// This is a variable.
|
||||
}, [&]() {
|
||||
// This is a property.
|
||||
}, [&]() {
|
||||
// This is a parameter.
|
||||
}, [&]() {
|
||||
// This is something else.
|
||||
});
|
||||
}
|
||||
|
||||
if (node.child) node.child->Visit(*this);
|
||||
}
|
||||
void OnVisitVariableAccessorNode(VariableAccessorNode& node) override {
|
||||
@@ -69,26 +88,41 @@ class GD_CORE_API ExpressionObjectsAnalyzer
|
||||
if (node.child) node.child->Visit(*this);
|
||||
}
|
||||
void OnVisitIdentifierNode(IdentifierNode& node) override {
|
||||
auto type = gd::ExpressionTypeFinder::GetType(platform, globalObjectsContainer, objectsContainer, rootType, node);
|
||||
auto type = gd::ExpressionTypeFinder::GetType(platform, projectScopedContainers, rootType, node);
|
||||
if (gd::ParameterMetadata::IsObject(type)) {
|
||||
context.AddObjectName(node.identifierName);
|
||||
context.AddObjectName(projectScopedContainers, node.identifierName);
|
||||
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
|
||||
// Nothing to do (identifier is a variable but not an object).
|
||||
} else {
|
||||
projectScopedContainers.MatchIdentifierWithName<void>(node.identifierName, [&]() {
|
||||
// This is an object variable.
|
||||
context.AddObjectName(projectScopedContainers, node.identifierName);
|
||||
}, [&]() {
|
||||
// This is a variable.
|
||||
}, [&]() {
|
||||
// This is a property.
|
||||
}, [&]() {
|
||||
// This is a parameter.
|
||||
}, [&]() {
|
||||
// This is something else.
|
||||
});
|
||||
}
|
||||
}
|
||||
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {
|
||||
if (!node.objectName.empty()) {
|
||||
context.AddObjectName(node.objectName);
|
||||
context.AddObjectName(projectScopedContainers, node.objectName);
|
||||
|
||||
if (!node.behaviorFunctionName.empty()) {
|
||||
context.AddBehaviorName(node.objectName, node.objectFunctionOrBehaviorName);
|
||||
context.AddBehaviorName(projectScopedContainers, node.objectName, node.objectFunctionOrBehaviorName);
|
||||
}
|
||||
}
|
||||
}
|
||||
void OnVisitFunctionCallNode(FunctionCallNode& node) override {
|
||||
if (!node.objectName.empty()) {
|
||||
context.AddObjectName(node.objectName);
|
||||
context.AddObjectName(projectScopedContainers, node.objectName);
|
||||
|
||||
if (!node.behaviorName.empty()) {
|
||||
context.AddBehaviorName(node.objectName, node.behaviorName);
|
||||
context.AddBehaviorName(projectScopedContainers, node.objectName, node.behaviorName);
|
||||
}
|
||||
}
|
||||
for (auto& parameter : node.parameters) {
|
||||
@@ -99,8 +133,7 @@ class GD_CORE_API ExpressionObjectsAnalyzer
|
||||
|
||||
private:
|
||||
const gd::Platform &platform;
|
||||
const gd::ObjectsContainer &globalObjectsContainer;
|
||||
const gd::ObjectsContainer &objectsContainer;
|
||||
const gd::ProjectScopedContainers &projectScopedContainers;
|
||||
const gd::String rootType;
|
||||
|
||||
EventsContext& context;
|
||||
@@ -121,8 +154,7 @@ bool EventsContextAnalyzer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
const gd::Expression& parameterValue,
|
||||
const gd::String& lastObjectName) {
|
||||
AnalyzeParameter(platform,
|
||||
project,
|
||||
layout,
|
||||
GetProjectScopedContainers(),
|
||||
parameterMetadata,
|
||||
parameterValue,
|
||||
context,
|
||||
@@ -134,8 +166,7 @@ bool EventsContextAnalyzer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
|
||||
void EventsContextAnalyzer::AnalyzeParameter(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ParameterMetadata& metadata,
|
||||
const gd::Expression& parameter,
|
||||
EventsContext& context,
|
||||
@@ -143,59 +174,39 @@ void EventsContextAnalyzer::AnalyzeParameter(
|
||||
const auto& value = parameter.GetPlainString();
|
||||
const auto& type = metadata.GetType();
|
||||
if (ParameterMetadata::IsObject(type)) {
|
||||
context.AddObjectName(value);
|
||||
context.AddObjectName(projectScopedContainers, value);
|
||||
} else if (ParameterMetadata::IsExpression("number", type)) {
|
||||
auto node = parameter.GetRootNode();
|
||||
|
||||
ExpressionObjectsAnalyzer analyzer(platform, project, layout, "number", context);
|
||||
ExpressionObjectsAnalyzer analyzer(platform, projectScopedContainers, "number", context);
|
||||
node->Visit(analyzer);
|
||||
} else if (ParameterMetadata::IsExpression("string", type)) {
|
||||
auto node = parameter.GetRootNode();
|
||||
|
||||
ExpressionObjectsAnalyzer analyzer(platform, project, layout, "string", context);
|
||||
ExpressionObjectsAnalyzer analyzer(platform, projectScopedContainers, "string", context);
|
||||
node->Visit(analyzer);
|
||||
} else if (ParameterMetadata::IsBehavior(type)) {
|
||||
context.AddBehaviorName(lastObjectName, value);
|
||||
context.AddBehaviorName(projectScopedContainers, lastObjectName, value);
|
||||
}
|
||||
}
|
||||
|
||||
void EventsContext::AddObjectName(const gd::String& objectOrGroupName) {
|
||||
for (auto& realObjectName : ExpandObjectsName(objectOrGroupName)) {
|
||||
void EventsContext::AddObjectName(const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::String& objectOrGroupName) {
|
||||
auto& objectsContainersList = projectScopedContainers.GetObjectsContainersList();
|
||||
for (auto& realObjectName : objectsContainersList.ExpandObjectName(objectOrGroupName)) {
|
||||
objectNames.insert(realObjectName);
|
||||
}
|
||||
referencedObjectOrGroupNames.insert(objectOrGroupName);
|
||||
}
|
||||
|
||||
void EventsContext::AddBehaviorName(const gd::String& objectOrGroupName,
|
||||
void EventsContext::AddBehaviorName(const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::String& objectOrGroupName,
|
||||
const gd::String& behaviorName) {
|
||||
for (auto& realObjectName : ExpandObjectsName(objectOrGroupName)) {
|
||||
auto& objectsContainersList = projectScopedContainers.GetObjectsContainersList();
|
||||
for (auto& realObjectName : objectsContainersList.ExpandObjectName(objectOrGroupName)) {
|
||||
objectOrGroupBehaviorNames[realObjectName].insert(behaviorName);
|
||||
}
|
||||
objectOrGroupBehaviorNames[objectOrGroupName].insert(behaviorName);
|
||||
}
|
||||
|
||||
std::vector<gd::String> EventsContext::ExpandObjectsName(
|
||||
const gd::String& objectName) {
|
||||
// Note: this logic is duplicated in EventsCodeGenerator::ExpandObjectsName
|
||||
std::vector<gd::String> realObjects;
|
||||
if (project.GetObjectGroups().Has(objectName))
|
||||
realObjects =
|
||||
project.GetObjectGroups().Get(objectName).GetAllObjectsNames();
|
||||
else if (layout.GetObjectGroups().Has(objectName))
|
||||
realObjects = layout.GetObjectGroups().Get(objectName).GetAllObjectsNames();
|
||||
else
|
||||
realObjects.push_back(objectName);
|
||||
|
||||
// Ensure that all returned objects actually exists.
|
||||
for (std::size_t i = 0; i < realObjects.size();) {
|
||||
if (!layout.HasObjectNamed(realObjects[i]) &&
|
||||
!project.HasObjectNamed(realObjects[i]))
|
||||
realObjects.erase(realObjects.begin() + i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
return realObjects;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -15,6 +15,7 @@ namespace gd {
|
||||
class BaseEvent;
|
||||
class Platform;
|
||||
class ObjectsContainer;
|
||||
class ObjectsContainersList;
|
||||
class Project;
|
||||
class Layout;
|
||||
class EventsList;
|
||||
@@ -29,12 +30,13 @@ namespace gd {
|
||||
*/
|
||||
class GD_CORE_API EventsContext {
|
||||
public:
|
||||
EventsContext(gd::ObjectsContainer& project_, gd::ObjectsContainer& layout_)
|
||||
: project(project_), layout(layout_){};
|
||||
EventsContext(){};
|
||||
virtual ~EventsContext(){};
|
||||
|
||||
void AddObjectName(const gd::String& objectOrGroupName);
|
||||
void AddBehaviorName(const gd::String& objectOrGroupName,
|
||||
void AddObjectName(const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::String& objectOrGroupName);
|
||||
void AddBehaviorName(const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::String& objectOrGroupName,
|
||||
const gd::String& behaviorName);
|
||||
|
||||
/**
|
||||
@@ -59,13 +61,9 @@ class GD_CORE_API EventsContext {
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<gd::String> ExpandObjectsName(const gd::String& objectOrGroupName);
|
||||
|
||||
std::set<gd::String> referencedObjectOrGroupNames;
|
||||
std::set<gd::String> objectNames;
|
||||
std::map<gd::String, std::set<gd::String>> objectOrGroupBehaviorNames;
|
||||
gd::ObjectsContainer& project;
|
||||
gd::ObjectsContainer& layout;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -73,15 +71,10 @@ class GD_CORE_API EventsContext {
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API EventsContextAnalyzer : public ArbitraryEventsWorker {
|
||||
class GD_CORE_API EventsContextAnalyzer : public ArbitraryEventsWorkerWithContext {
|
||||
public:
|
||||
EventsContextAnalyzer(const gd::Platform& platform_,
|
||||
gd::ObjectsContainer& project_,
|
||||
gd::ObjectsContainer& layout_)
|
||||
: platform(platform_),
|
||||
project(project_),
|
||||
layout(layout_),
|
||||
context(project, layout){};
|
||||
EventsContextAnalyzer(const gd::Platform& platform_)
|
||||
: platform(platform_) {};
|
||||
virtual ~EventsContextAnalyzer(){};
|
||||
|
||||
/**
|
||||
@@ -90,8 +83,7 @@ class GD_CORE_API EventsContextAnalyzer : public ArbitraryEventsWorker {
|
||||
const EventsContext& GetEventsContext() { return context; }
|
||||
|
||||
static void AnalyzeParameter(const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ParameterMetadata& metadata,
|
||||
const gd::Expression& parameter,
|
||||
EventsContext& context,
|
||||
@@ -102,8 +94,6 @@ class GD_CORE_API EventsContextAnalyzer : public ArbitraryEventsWorker {
|
||||
bool isCondition);
|
||||
|
||||
const gd::Platform& platform;
|
||||
gd::ObjectsContainer& project;
|
||||
gd::ObjectsContainer& layout;
|
||||
EventsContext context;
|
||||
};
|
||||
|
||||
|
175
Core/GDCore/IDE/Events/EventsFunctionSelfCallChecker.cpp
Normal file
175
Core/GDCore/IDE/Events/EventsFunctionSelfCallChecker.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "EventsFunctionSelfCallChecker.h"
|
||||
|
||||
#include "GDCore/Events/Expression.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2Node.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/Project/EventsBasedBehavior.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/Project/EventsFunction.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Check the type of the first condition or action.
|
||||
*/
|
||||
class GD_CORE_API FirstInstructionTypeChecker
|
||||
: public ReadOnlyArbitraryEventsWorker {
|
||||
public:
|
||||
FirstInstructionTypeChecker(const gd::String &eventFunctionType_,
|
||||
const bool isEventFunctionCondition_)
|
||||
: eventFunctionType(eventFunctionType_),
|
||||
isEventFunctionCondition(isEventFunctionCondition_),
|
||||
isOnlyCallingItself(false){};
|
||||
virtual ~FirstInstructionTypeChecker(){};
|
||||
|
||||
void DoVisitInstruction(const gd::Instruction &instruction,
|
||||
bool isCondition) override {
|
||||
if (isCondition == isEventFunctionCondition) {
|
||||
isOnlyCallingItself = instruction.GetType() == eventFunctionType;
|
||||
StopAnyEventIteration();
|
||||
}
|
||||
};
|
||||
|
||||
bool isOnlyCallingItself;
|
||||
|
||||
private:
|
||||
gd::String eventFunctionType;
|
||||
bool isEventFunctionCondition;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Check the type of the first condition or action.
|
||||
*/
|
||||
class GD_CORE_API FirstActionExpressionTypeChecker
|
||||
: public ReadOnlyArbitraryEventsWorker,
|
||||
ExpressionParser2NodeWorker {
|
||||
public:
|
||||
FirstActionExpressionTypeChecker(const gd::Platform &platform_,
|
||||
const gd::String &eventFunctionType_)
|
||||
: platform(platform_), eventFunctionType(eventFunctionType_),
|
||||
isOnlyCallingItself(false){};
|
||||
virtual ~FirstActionExpressionTypeChecker(){};
|
||||
|
||||
void DoVisitInstruction(const gd::Instruction &instruction,
|
||||
bool isCondition) override {
|
||||
// Typically, it should be a "return" action.
|
||||
if (!isCondition) {
|
||||
gd::String lastObjectParameter = "";
|
||||
const gd::InstructionMetadata &instrInfos =
|
||||
MetadataProvider::GetActionMetadata(platform, instruction.GetType());
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
|
||||
if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters[pNb].GetType()) ||
|
||||
ParameterMetadata::IsExpression(
|
||||
"string", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = instruction.GetParameter(pNb).GetRootNode();
|
||||
node->Visit(*this);
|
||||
}
|
||||
}
|
||||
StopAnyEventIteration();
|
||||
}
|
||||
}
|
||||
|
||||
// Only check expressions that directly calls a function.
|
||||
void OnVisitFunctionCallNode(FunctionCallNode &node) override {
|
||||
isOnlyCallingItself |= node.functionName == eventFunctionType;
|
||||
}
|
||||
|
||||
// Handle extra parenthesis.
|
||||
void OnVisitSubExpressionNode(SubExpressionNode &node) override {
|
||||
node.expression->Visit(*this);
|
||||
}
|
||||
void OnVisitOperatorNode(OperatorNode &node) override {}
|
||||
// Handle sign that could have been forgotten
|
||||
void OnVisitUnaryOperatorNode(UnaryOperatorNode &node) override {
|
||||
node.factor->Visit(*this);
|
||||
}
|
||||
void OnVisitNumberNode(NumberNode &node) override {}
|
||||
void OnVisitTextNode(TextNode &node) override {}
|
||||
void OnVisitVariableNode(VariableNode &node) override {}
|
||||
void OnVisitVariableAccessorNode(VariableAccessorNode &node) override {}
|
||||
void OnVisitVariableBracketAccessorNode(
|
||||
VariableBracketAccessorNode &node) override {}
|
||||
void OnVisitIdentifierNode(IdentifierNode &node) override {}
|
||||
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode &node) override {}
|
||||
void OnVisitEmptyNode(EmptyNode &node) override {}
|
||||
|
||||
bool isOnlyCallingItself;
|
||||
|
||||
private:
|
||||
const gd::Platform &platform;
|
||||
gd::String eventFunctionType;
|
||||
};
|
||||
|
||||
bool EventsFunctionSelfCallChecker::IsOnlyCallingItself(
|
||||
const gd::Project &project, const gd::String &functionFullType,
|
||||
const gd::EventsFunction &eventsFunction) {
|
||||
bool isOnlyCallingItself = false;
|
||||
|
||||
if (eventsFunction.IsExpression()) {
|
||||
FirstActionExpressionTypeChecker eventWorker(project.GetCurrentPlatform(),
|
||||
functionFullType);
|
||||
eventWorker.Launch(eventsFunction.GetEvents());
|
||||
isOnlyCallingItself = eventWorker.isOnlyCallingItself;
|
||||
} else {
|
||||
FirstInstructionTypeChecker eventWorker(functionFullType,
|
||||
!eventsFunction.IsAction());
|
||||
eventWorker.Launch(eventsFunction.GetEvents());
|
||||
isOnlyCallingItself = eventWorker.isOnlyCallingItself;
|
||||
}
|
||||
return isOnlyCallingItself;
|
||||
}
|
||||
|
||||
bool EventsFunctionSelfCallChecker::IsFreeFunctionOnlyCallingItself(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsFunction &eventsFunction) {
|
||||
return IsOnlyCallingItself(
|
||||
project,
|
||||
PlatformExtension::GetEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(), eventsFunction.GetName()),
|
||||
eventsFunction);
|
||||
}
|
||||
|
||||
bool EventsFunctionSelfCallChecker::IsBehaviorFunctionOnlyCallingItself(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsBasedBehavior &eventsBasedBehavior,
|
||||
const gd::EventsFunction &eventsFunction) {
|
||||
return IsOnlyCallingItself(
|
||||
project,
|
||||
PlatformExtension::GetBehaviorEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(), eventsBasedBehavior.GetName(),
|
||||
eventsFunction.GetName()),
|
||||
eventsFunction);
|
||||
}
|
||||
bool EventsFunctionSelfCallChecker::IsObjectFunctionOnlyCallingItself(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject &eventsBasedObject,
|
||||
const gd::EventsFunction &eventsFunction) {
|
||||
return IsOnlyCallingItself(project,
|
||||
PlatformExtension::GetObjectEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName(),
|
||||
eventsFunction.GetName()),
|
||||
eventsFunction);
|
||||
}
|
||||
|
||||
} // namespace gd
|
64
Core/GDCore/IDE/Events/EventsFunctionSelfCallChecker.h
Normal file
64
Core/GDCore/IDE/Events/EventsFunctionSelfCallChecker.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/String.h"
|
||||
#include <vector>
|
||||
namespace gd {
|
||||
class Project;
|
||||
class EventsFunctionsExtension;
|
||||
class EventsFunctionsContainer;
|
||||
class EventsFunction;
|
||||
class EventsBasedBehavior;
|
||||
class EventsBasedObject;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
/**
|
||||
* \brief Check if functions are only calling themselves.
|
||||
*
|
||||
* It allows to detect mistakes when implementing functions for compatibility
|
||||
* after a function renaming.
|
||||
* Infinite loops can happens when the legacy function call itself instead of
|
||||
* the new function.
|
||||
*
|
||||
* \note Only the first instruction or the expressions of the first action is
|
||||
* checked.
|
||||
*/
|
||||
class GD_CORE_API EventsFunctionSelfCallChecker {
|
||||
public:
|
||||
/**
|
||||
* \brief Check if a free function is only calling itself.
|
||||
*/
|
||||
static bool IsFreeFunctionOnlyCallingItself(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsFunction &eventsFunction);
|
||||
|
||||
/**
|
||||
* \brief Check if a behavior function is only calling itself.
|
||||
*/
|
||||
static bool IsBehaviorFunctionOnlyCallingItself(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsBasedBehavior &eventsBasedBehavior,
|
||||
const gd::EventsFunction &eventsFunction);
|
||||
|
||||
/**
|
||||
* \brief Check if an object function is only calling itself.
|
||||
*/
|
||||
static bool IsObjectFunctionOnlyCallingItself(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject &eventsBasedObject,
|
||||
const gd::EventsFunction &eventsFunction);
|
||||
|
||||
private:
|
||||
static bool IsOnlyCallingItself(const gd::Project &project,
|
||||
const gd::String &functionFullType,
|
||||
const gd::EventsFunction &eventsFunction);
|
||||
};
|
||||
} // namespace gd
|
@@ -34,14 +34,12 @@ class GD_CORE_API IdentifierFinderExpressionNodeWorker
|
||||
public:
|
||||
IdentifierFinderExpressionNodeWorker(std::set<gd::String>& results_,
|
||||
const gd::Platform &platform_,
|
||||
const gd::ObjectsContainer &globalObjectsContainer_,
|
||||
const gd::ObjectsContainer &objectsContainer_,
|
||||
const gd::ProjectScopedContainers &projectScopedContainers_,
|
||||
const gd::String& identifierType_,
|
||||
const gd::String& objectName_ = "")
|
||||
: results(results_),
|
||||
platform(platform_),
|
||||
globalObjectsContainer(globalObjectsContainer_),
|
||||
objectsContainer(objectsContainer_),
|
||||
projectScopedContainers(projectScopedContainers_),
|
||||
identifierType(identifierType_),
|
||||
objectName(objectName_){};
|
||||
virtual ~IdentifierFinderExpressionNodeWorker(){};
|
||||
@@ -79,14 +77,14 @@ class GD_CORE_API IdentifierFinderExpressionNodeWorker
|
||||
const gd::ExpressionMetadata &metadata = isObjectFunction ?
|
||||
MetadataProvider::GetObjectAnyExpressionMetadata(
|
||||
platform,
|
||||
GetTypeOfObject(globalObjectsContainer, objectsContainer, objectName),
|
||||
projectScopedContainers.GetObjectsContainersList().GetTypeOfObject(objectName),
|
||||
node.functionName):
|
||||
MetadataProvider::GetAnyExpressionMetadata(platform, node.functionName);
|
||||
|
||||
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
size_t parameterIndex = 0;
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0); metadataIndex < metadata.parameters.size()
|
||||
&& parameterIndex < node.parameters.size(); ++metadataIndex) {
|
||||
@@ -111,8 +109,7 @@ class GD_CORE_API IdentifierFinderExpressionNodeWorker
|
||||
|
||||
private:
|
||||
const gd::Platform &platform;
|
||||
const gd::ObjectsContainer &globalObjectsContainer;
|
||||
const gd::ObjectsContainer &objectsContainer;
|
||||
const gd::ProjectScopedContainers &projectScopedContainers;
|
||||
|
||||
std::set<gd::String>& results; ///< Reference to the std::set where argument
|
||||
///< values must be stored.
|
||||
@@ -166,8 +163,7 @@ class GD_CORE_API IdentifierFinderEventWorker
|
||||
IdentifierFinderExpressionNodeWorker searcher(
|
||||
results,
|
||||
platform,
|
||||
GetGlobalObjectsContainer(),
|
||||
GetObjectsContainer(),
|
||||
GetProjectScopedContainers(),
|
||||
identifierType,
|
||||
objectName);
|
||||
node->Visit(searcher);
|
||||
@@ -227,7 +223,8 @@ void EventsIdentifiersFinder::FindArgumentsInEventsAndDependencies(
|
||||
platform,
|
||||
identifierType,
|
||||
objectName);
|
||||
eventWorker.Launch(layout.GetEvents(), project, layout);
|
||||
eventWorker.Launch(layout.GetEvents(),
|
||||
gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout));
|
||||
|
||||
DependenciesAnalyzer dependenciesAnalyzer = DependenciesAnalyzer(project, layout);
|
||||
dependenciesAnalyzer.Analyze();
|
||||
@@ -238,7 +235,8 @@ void EventsIdentifiersFinder::FindArgumentsInEventsAndDependencies(
|
||||
platform,
|
||||
identifierType,
|
||||
objectName);
|
||||
eventWorker.Launch(externalEvents.GetEvents(), project, layout);
|
||||
eventWorker.Launch(externalEvents.GetEvents(),
|
||||
gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout));
|
||||
}
|
||||
for (const gd::String& sceneName : dependenciesAnalyzer.GetScenesDependencies()) {
|
||||
const gd::Layout& dependencyLayout = project.GetLayout(sceneName);
|
||||
@@ -247,7 +245,8 @@ void EventsIdentifiersFinder::FindArgumentsInEventsAndDependencies(
|
||||
platform,
|
||||
identifierType,
|
||||
objectName);
|
||||
eventWorker.Launch(dependencyLayout.GetEvents(), project, dependencyLayout);
|
||||
eventWorker.Launch(dependencyLayout.GetEvents(),
|
||||
gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, dependencyLayout));
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user