mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
855 Commits
better-sto
...
v5.4.208
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d082d4f5a4 | ||
![]() |
eaa0f4077f | ||
![]() |
7d73f58bc4 | ||
![]() |
9171b40429 | ||
![]() |
242fc49342 | ||
![]() |
7081fd570c | ||
![]() |
34ecdce7fa | ||
![]() |
3a0903a19f | ||
![]() |
e1a4f88ba6 | ||
![]() |
ed59498835 | ||
![]() |
4b70653a0b | ||
![]() |
48dd91043a | ||
![]() |
30e7ef5865 | ||
![]() |
289c555fe4 | ||
![]() |
803a55869c | ||
![]() |
282f4c184f | ||
![]() |
875237cc8b | ||
![]() |
7aeb44d05e | ||
![]() |
e445ff710e | ||
![]() |
e016babf71 | ||
![]() |
6a34e3c1db | ||
![]() |
82e819c033 | ||
![]() |
72e5deeef3 | ||
![]() |
a91cc4557f | ||
![]() |
b2c953a31d | ||
![]() |
b29fbaa1f8 | ||
![]() |
e8faa17e12 | ||
![]() |
2585ad5dca | ||
![]() |
a9108fa87b | ||
![]() |
cd3186d2d8 | ||
![]() |
6a737f7d51 | ||
![]() |
9211aa7a3b | ||
![]() |
864ba181e9 | ||
![]() |
10fa3296a9 | ||
![]() |
2fb39b9dbe | ||
![]() |
6f43e896d6 | ||
![]() |
122df05f99 | ||
![]() |
b7a5122b07 | ||
![]() |
eb9d680d95 | ||
![]() |
354da42a9e | ||
![]() |
aca37fdade | ||
![]() |
bb6eb01153 | ||
![]() |
9fb086dcdf | ||
![]() |
7e60a0246e | ||
![]() |
3cb2da3de5 | ||
![]() |
ef23470a00 | ||
![]() |
196ea5e480 | ||
![]() |
e732f1952c | ||
![]() |
f5f024cc42 | ||
![]() |
6a3df62598 | ||
![]() |
75f049d911 | ||
![]() |
4d0ac6f355 | ||
![]() |
00a5c93b35 | ||
![]() |
a90cc83967 | ||
![]() |
87a5934df3 | ||
![]() |
d0245b8f1a | ||
![]() |
45d73df6fb | ||
![]() |
7ac600e92d | ||
![]() |
7ba8d0133e | ||
![]() |
e9adaa94c5 | ||
![]() |
35da31c5c5 | ||
![]() |
e65492e1a1 | ||
![]() |
44827ea372 | ||
![]() |
ab3ffe6785 | ||
![]() |
d83d049ac9 | ||
![]() |
67a7bd7af2 | ||
![]() |
6db5267878 | ||
![]() |
a51c223c9c | ||
![]() |
0a4e5a1012 | ||
![]() |
acce714736 | ||
![]() |
3c34a8806b | ||
![]() |
1d4cb7bef0 | ||
![]() |
7badacd24a | ||
![]() |
11ab92fc0e | ||
![]() |
ddb1e335bc | ||
![]() |
8d035a774d | ||
![]() |
5b1e3565d3 | ||
![]() |
8c88038bfb | ||
![]() |
f62811974d | ||
![]() |
b516037d2b | ||
![]() |
98befc8000 | ||
![]() |
377231fb37 | ||
![]() |
22ae8ac489 | ||
![]() |
40674fd3b9 | ||
![]() |
0792e59b24 | ||
![]() |
8ba6ad7b43 | ||
![]() |
84b07bc84d | ||
![]() |
c46d39cbed | ||
![]() |
b96132964c | ||
![]() |
130cd1e3a7 | ||
![]() |
fbbcf25bf5 | ||
![]() |
ffaae4d3d4 | ||
![]() |
75d79a7758 | ||
![]() |
d91fb78848 | ||
![]() |
e0a2ed1654 | ||
![]() |
d5f2be1c19 | ||
![]() |
7abcfe8af2 | ||
![]() |
b86dd9efce | ||
![]() |
15f6b62c5b | ||
![]() |
eb995ec7c7 | ||
![]() |
a076571120 | ||
![]() |
ec9cb790e7 | ||
![]() |
4a283add00 | ||
![]() |
6b3faa42bb | ||
![]() |
555ee61e63 | ||
![]() |
b838c8549b | ||
![]() |
33db6ee359 | ||
![]() |
f361d3e1fa | ||
![]() |
441401f34c | ||
![]() |
558daa2075 | ||
![]() |
cd475316df | ||
![]() |
8b21e72c85 | ||
![]() |
a9d6f18c11 | ||
![]() |
f58e1113b6 | ||
![]() |
f82b5fc66d | ||
![]() |
2f19a9bb33 | ||
![]() |
8f739d85c2 | ||
![]() |
f23847617d | ||
![]() |
876332a782 | ||
![]() |
93c74c9fd6 | ||
![]() |
e92d8496ac | ||
![]() |
35e67a6d26 | ||
![]() |
740c7ae8bc | ||
![]() |
432a91c47b | ||
![]() |
799bc762aa | ||
![]() |
147a0eed53 | ||
![]() |
920e1d423f | ||
![]() |
c013f319ee | ||
![]() |
db53e84c6f | ||
![]() |
4b85f710a9 | ||
![]() |
07a350dadd | ||
![]() |
7ccbf91973 | ||
![]() |
410fecf715 | ||
![]() |
967bf5cbe3 | ||
![]() |
0020f72850 | ||
![]() |
0eb7b85e77 | ||
![]() |
063bf51783 | ||
![]() |
482fb3b85e | ||
![]() |
9a4a84d2af | ||
![]() |
9a705b98e2 | ||
![]() |
da940abdc2 | ||
![]() |
528b8f4e6c | ||
![]() |
7212d56a1b | ||
![]() |
5cba43335c | ||
![]() |
324698e269 | ||
![]() |
d219bf05d3 | ||
![]() |
9cbc421d74 | ||
![]() |
f63d9d1b5c | ||
![]() |
dd5d0669b1 | ||
![]() |
e681632e60 | ||
![]() |
0bcb219e00 | ||
![]() |
6d5e9c1676 | ||
![]() |
5ded5648bf | ||
![]() |
687f926bc5 | ||
![]() |
4a2d573956 | ||
![]() |
ce77414f85 | ||
![]() |
298ff6311d | ||
![]() |
ca0a000ae1 | ||
![]() |
dc87f138a6 | ||
![]() |
28af860aff | ||
![]() |
4dbc607314 | ||
![]() |
bfefe9baf4 | ||
![]() |
2332359c19 | ||
![]() |
68b6c443c3 | ||
![]() |
37e113baaa | ||
![]() |
a8a8c142a3 | ||
![]() |
012e625a47 | ||
![]() |
c0e6d98e4c | ||
![]() |
ab63e02862 | ||
![]() |
1b13127a2f | ||
![]() |
3de0861172 | ||
![]() |
795417c915 | ||
![]() |
e8540dd720 | ||
![]() |
3c5fee0535 | ||
![]() |
7f2806bd89 | ||
![]() |
886fdb464e | ||
![]() |
6aaeda6c49 | ||
![]() |
830e35b368 | ||
![]() |
fa4a621888 | ||
![]() |
8756932c12 | ||
![]() |
0b5f929773 | ||
![]() |
183fba4720 | ||
![]() |
9d608a0e93 | ||
![]() |
5bbfd81d89 | ||
![]() |
a441bb04ef | ||
![]() |
ccf5e390d6 | ||
![]() |
e633aa77c2 | ||
![]() |
12275d0814 | ||
![]() |
4ed1889856 | ||
![]() |
ae6ac2068b | ||
![]() |
a31c5cfac3 | ||
![]() |
1917d5aedd | ||
![]() |
d0c85cd3bc | ||
![]() |
afed90ccef | ||
![]() |
ff9c6e5cf3 | ||
![]() |
199d315e29 | ||
![]() |
ddf426c2fd | ||
![]() |
43648b0a18 | ||
![]() |
96e5d6966a | ||
![]() |
eb256b3412 | ||
![]() |
d89bfd27f8 | ||
![]() |
7cef3b3a41 | ||
![]() |
f3a87a2159 | ||
![]() |
4df91f3e77 | ||
![]() |
8ca82ef457 | ||
![]() |
0c3719ff0c | ||
![]() |
a76ba988b2 | ||
![]() |
8f002541ef | ||
![]() |
6fd82376a8 | ||
![]() |
db2d6f90a3 | ||
![]() |
f32180d923 | ||
![]() |
4886cf4fd3 | ||
![]() |
0fd25c381a | ||
![]() |
916e642465 | ||
![]() |
eaebc16f49 | ||
![]() |
231d92a2fa | ||
![]() |
e3cc01e902 | ||
![]() |
fe68286eaf | ||
![]() |
7d95e44b51 | ||
![]() |
9b448f1ddf | ||
![]() |
8f34a100e5 | ||
![]() |
cc3a9af8ce | ||
![]() |
75bfa5cb45 | ||
![]() |
5ac8f411fe | ||
![]() |
870247a3df | ||
![]() |
80b68d3bb5 | ||
![]() |
6e8a8d6868 | ||
![]() |
2310f2a618 | ||
![]() |
f8bd3fca00 | ||
![]() |
92b9203ce8 | ||
![]() |
4ca859c8b9 | ||
![]() |
701b5a3250 | ||
![]() |
1e87b74d48 | ||
![]() |
b7a4bab53c | ||
![]() |
2223b6516b | ||
![]() |
7d89208e7b | ||
![]() |
70508292e4 | ||
![]() |
c899db1dba | ||
![]() |
2fb27f430e | ||
![]() |
6cd2400848 | ||
![]() |
fadccba757 | ||
![]() |
29a43514ce | ||
![]() |
e64ab94f76 | ||
![]() |
ed969d2909 | ||
![]() |
77bf67fdf0 | ||
![]() |
580c7a370c | ||
![]() |
266f0f2b6e | ||
![]() |
58af6aacb4 | ||
![]() |
1c4ee1c928 | ||
![]() |
0275476bec | ||
![]() |
3f0194acf0 | ||
![]() |
017d8b28c2 | ||
![]() |
4b518ba0fc | ||
![]() |
e4938b25b5 | ||
![]() |
c56ad2d277 | ||
![]() |
f069f9d942 | ||
![]() |
9f7c60a69e | ||
![]() |
774bf0db61 | ||
![]() |
ccd9c5c0ff | ||
![]() |
5b130a34e3 | ||
![]() |
3e6d147660 | ||
![]() |
433d85db94 | ||
![]() |
b75f707b30 | ||
![]() |
67799eb3eb | ||
![]() |
1173210386 | ||
![]() |
007cc48291 | ||
![]() |
12813c9ad9 | ||
![]() |
e503e34059 | ||
![]() |
4bf576a889 | ||
![]() |
eff1c1bcb6 | ||
![]() |
abce34f2b1 | ||
![]() |
07276d5e16 | ||
![]() |
1fdd8cc792 | ||
![]() |
79e40605d5 | ||
![]() |
fcc91e3fea | ||
![]() |
5c66623631 | ||
![]() |
5637642e1b | ||
![]() |
7e8b44af2e | ||
![]() |
0dd4650aae | ||
![]() |
c7cac31830 | ||
![]() |
56cb8581c4 | ||
![]() |
1993040b70 | ||
![]() |
883991081a | ||
![]() |
7d8afef1ad | ||
![]() |
8178595546 | ||
![]() |
a478068c64 | ||
![]() |
368da1b610 | ||
![]() |
4ee43202e9 | ||
![]() |
602fdf4bfd | ||
![]() |
6110acafcc | ||
![]() |
a3696ca9d1 | ||
![]() |
1bb473b0b0 | ||
![]() |
4376b4f36e | ||
![]() |
6ecbae9c35 | ||
![]() |
93e9fc6aed | ||
![]() |
7c0a7a4152 | ||
![]() |
d4cdb3ff83 | ||
![]() |
a7cac91e45 | ||
![]() |
6a6d72cd9a | ||
![]() |
11d74b3ea5 | ||
![]() |
5b65cf84eb | ||
![]() |
6b7af0474f | ||
![]() |
99f7e55044 | ||
![]() |
6b522b1c31 | ||
![]() |
0f35e48690 | ||
![]() |
53d19dd628 | ||
![]() |
155dc1bec8 | ||
![]() |
be26e39eae | ||
![]() |
90fa5ea8e8 | ||
![]() |
4845251f78 | ||
![]() |
31ef3fec58 | ||
![]() |
292b23ea17 | ||
![]() |
9c5a5db7a8 | ||
![]() |
d73ae4c56e | ||
![]() |
339929e021 | ||
![]() |
cea1cf20f1 | ||
![]() |
4ec2705f75 | ||
![]() |
408f6f8134 | ||
![]() |
c64bac0010 | ||
![]() |
f8d5c89ebf | ||
![]() |
ca3bb40e96 | ||
![]() |
713d437b70 | ||
![]() |
09381c3836 | ||
![]() |
ea4c2e0827 | ||
![]() |
a5d1149c21 | ||
![]() |
119b0fadce | ||
![]() |
7111859768 | ||
![]() |
08dfb4d36b | ||
![]() |
cacd482af9 | ||
![]() |
3568a58019 | ||
![]() |
a32d5fcd7e | ||
![]() |
1a999fd2dd | ||
![]() |
76648764bb | ||
![]() |
c25803c122 | ||
![]() |
ba8d7f4e38 | ||
![]() |
e1c22f6994 | ||
![]() |
7b70f9172f | ||
![]() |
a871e0f2ec | ||
![]() |
f6499e1163 | ||
![]() |
d03e58636d | ||
![]() |
a7be928f2f | ||
![]() |
7c83610d28 | ||
![]() |
1a1e92b072 | ||
![]() |
5118f13e0b | ||
![]() |
f3ee18cdc7 | ||
![]() |
c5584f746e | ||
![]() |
706a6de94c | ||
![]() |
8c750b54dd | ||
![]() |
649d744664 | ||
![]() |
12a6fec18e | ||
![]() |
7fc4aa47f6 | ||
![]() |
483f78fa75 | ||
![]() |
35b80818dc | ||
![]() |
b3f19726dc | ||
![]() |
dd332e3cce | ||
![]() |
dc95a7511f | ||
![]() |
77130c7d2e | ||
![]() |
8d1c3e8290 | ||
![]() |
63570fd3c8 | ||
![]() |
6945409280 | ||
![]() |
e345b2726f | ||
![]() |
3a2a662f62 | ||
![]() |
73d850f933 | ||
![]() |
1f2293e7d6 | ||
![]() |
b038984097 | ||
![]() |
a45a5bfe7e | ||
![]() |
8cbefa0cde | ||
![]() |
1d607d474a | ||
![]() |
3cd6e36a73 | ||
![]() |
cfbec2df4a | ||
![]() |
2823fde86a | ||
![]() |
f29ae50f2e | ||
![]() |
ba40c67941 | ||
![]() |
c8ca3c2931 | ||
![]() |
0bb0969ab8 | ||
![]() |
3b0a7c442f | ||
![]() |
df3c95c466 | ||
![]() |
482d52ff5a | ||
![]() |
5a78c763ef | ||
![]() |
3393af4b3b | ||
![]() |
c2b77c9df7 | ||
![]() |
514e4692ab | ||
![]() |
210e59f201 | ||
![]() |
e2058052f2 | ||
![]() |
90dca41e20 | ||
![]() |
15b463dad1 | ||
![]() |
a97a1f8a86 | ||
![]() |
901f84daaa | ||
![]() |
6af50ae5c0 | ||
![]() |
f7bd4bee6e | ||
![]() |
4a4b015242 | ||
![]() |
75ee0b68e3 | ||
![]() |
778104447c | ||
![]() |
a4ddc0a6ef | ||
![]() |
3e713029e2 | ||
![]() |
7eb5402ee2 | ||
![]() |
25adb026b8 | ||
![]() |
54bd2960ac | ||
![]() |
1fde65b5e3 | ||
![]() |
b4295b4077 | ||
![]() |
c7a929374d | ||
![]() |
7571e64396 | ||
![]() |
198267d7cb | ||
![]() |
0982424d0d | ||
![]() |
29747690c2 | ||
![]() |
ad74532752 | ||
![]() |
80e5376f74 | ||
![]() |
cc24eab2aa | ||
![]() |
423c8165ad | ||
![]() |
0af00818dc | ||
![]() |
9f5c783d73 | ||
![]() |
ad65971c01 | ||
![]() |
85ef9a9561 | ||
![]() |
455d77fcdf | ||
![]() |
02093fec0f | ||
![]() |
8227ab9cad | ||
![]() |
f8eb91f3d2 | ||
![]() |
a260aa5e3e | ||
![]() |
4d8d93a550 | ||
![]() |
cf160bcca1 | ||
![]() |
44a0e22f97 | ||
![]() |
d47d3285b2 | ||
![]() |
2ee6590967 | ||
![]() |
cd77951e1a | ||
![]() |
fa4efef857 | ||
![]() |
bc8204d696 | ||
![]() |
b2eab5a327 | ||
![]() |
dba65822dd | ||
![]() |
8f155e4322 | ||
![]() |
13ebe5c588 | ||
![]() |
bcd8e5608a | ||
![]() |
14e444413d | ||
![]() |
a2f75bc0dc | ||
![]() |
6914e01a15 | ||
![]() |
90b5f7a322 | ||
![]() |
13cf9b1d0b | ||
![]() |
6fc0198298 | ||
![]() |
0999ba611d | ||
![]() |
119d1af76a | ||
![]() |
d6b4dacb1e | ||
![]() |
9edb3cfe91 | ||
![]() |
d44a1c3537 | ||
![]() |
8cc84e5728 | ||
![]() |
76130b43d4 | ||
![]() |
40b0823b91 | ||
![]() |
9b447e08e2 | ||
![]() |
10314a1911 | ||
![]() |
d0195719c2 | ||
![]() |
dd8c040381 | ||
![]() |
5e0c8a92aa | ||
![]() |
977c102ddc | ||
![]() |
849d79d5d7 | ||
![]() |
28f7c9ae0b | ||
![]() |
38e58327fa | ||
![]() |
3cc29efaa2 | ||
![]() |
65eb76fb57 | ||
![]() |
9eb721662f | ||
![]() |
b10b131010 | ||
![]() |
b5fd1bb351 | ||
![]() |
f1c9521625 | ||
![]() |
6ceb3c2c10 | ||
![]() |
43827876cd | ||
![]() |
62b746300a | ||
![]() |
769ebcd91c | ||
![]() |
70d5de16bf | ||
![]() |
7fbe1bd23d | ||
![]() |
de8a679e31 | ||
![]() |
a1a4029b35 | ||
![]() |
a377467031 | ||
![]() |
dd090fd1d7 | ||
![]() |
26ee9b3891 | ||
![]() |
ad18eab4ae | ||
![]() |
007fc36a2e | ||
![]() |
c8ebfde85b | ||
![]() |
d0005ba2cb | ||
![]() |
f623b352ee | ||
![]() |
16e2d8a005 | ||
![]() |
7654883cb1 | ||
![]() |
3ae5db2a49 | ||
![]() |
9ed002c879 | ||
![]() |
d4283c2350 | ||
![]() |
5a176d21e7 | ||
![]() |
bfdfd7f0fb | ||
![]() |
aae75f2232 | ||
![]() |
977092c0a3 | ||
![]() |
556688cedb | ||
![]() |
ce93dc5310 | ||
![]() |
d6d425db4f | ||
![]() |
2737e75639 | ||
![]() |
36eab18133 | ||
![]() |
48acbb12ee | ||
![]() |
21904e46f1 | ||
![]() |
94753ac053 | ||
![]() |
b160ee9b27 | ||
![]() |
f76e8a72b6 | ||
![]() |
5bc342688d | ||
![]() |
3e6204c0eb | ||
![]() |
7b1c340ad0 | ||
![]() |
fac724dc3f | ||
![]() |
9b4151f64c | ||
![]() |
6b5ab6c811 | ||
![]() |
5943092b0c | ||
![]() |
deb0c5ffc3 | ||
![]() |
c56fa03bf6 | ||
![]() |
0d49d449db | ||
![]() |
fdd702cd09 | ||
![]() |
5a8e4a7ca9 | ||
![]() |
2e4e91c21e | ||
![]() |
6ece930809 | ||
![]() |
c5baa81977 | ||
![]() |
d24be38874 | ||
![]() |
1efffbbb78 | ||
![]() |
090d76a368 | ||
![]() |
d44a9375de | ||
![]() |
5a2a3893f9 | ||
![]() |
0a6b0dc785 | ||
![]() |
02e99726dc | ||
![]() |
843055d8df | ||
![]() |
f7fda5cb5e | ||
![]() |
e529642aec | ||
![]() |
c8e10d7043 | ||
![]() |
5f0de0e9a7 | ||
![]() |
e51638ce4b | ||
![]() |
0fbd6a606a | ||
![]() |
2fa543c3db | ||
![]() |
38e35c9695 | ||
![]() |
ad13a1a101 | ||
![]() |
cb9d98d027 | ||
![]() |
064c3f1572 | ||
![]() |
9e5320f9d4 | ||
![]() |
a1826d355d | ||
![]() |
32a3a094d1 | ||
![]() |
ee7dc2654b | ||
![]() |
64ffad3c0a | ||
![]() |
dcc62f078f | ||
![]() |
d920f05dbc | ||
![]() |
ac82be800b | ||
![]() |
2c92ae4042 | ||
![]() |
465e934605 | ||
![]() |
248ba7675e | ||
![]() |
fd2b59ba45 | ||
![]() |
be54236ece | ||
![]() |
6edf63e98f | ||
![]() |
034f1ad9cc | ||
![]() |
94b8c31ac2 | ||
![]() |
57d1241e2d | ||
![]() |
eb4708ca87 | ||
![]() |
fac710780b | ||
![]() |
d28aac325a | ||
![]() |
306b341ee5 | ||
![]() |
1d8e04cb78 | ||
![]() |
3b2855de59 | ||
![]() |
d5c2982b2d | ||
![]() |
315b7387b3 | ||
![]() |
f4f92566f4 | ||
![]() |
7b72d4e080 | ||
![]() |
ae96ebf79c | ||
![]() |
be813a0271 | ||
![]() |
b306d80915 | ||
![]() |
9baed02aa1 | ||
![]() |
1b4c5c1b1c | ||
![]() |
4f04190614 | ||
![]() |
d3134ecde9 | ||
![]() |
61ed7ffa16 | ||
![]() |
8be1961d3f | ||
![]() |
112c306610 | ||
![]() |
423f15b513 | ||
![]() |
a9c89b14c3 | ||
![]() |
bd898463f5 | ||
![]() |
ed4635664c | ||
![]() |
b6f25db40c | ||
![]() |
f78662be5f | ||
![]() |
7aae35a029 | ||
![]() |
6c323614ef | ||
![]() |
eb4170df20 | ||
![]() |
8830bb93ae | ||
![]() |
87fa0a39ac | ||
![]() |
a9cc911ca8 | ||
![]() |
d3fe6cf532 | ||
![]() |
e2c40ff205 | ||
![]() |
970d04b0df | ||
![]() |
8c5076443c | ||
![]() |
3744e98065 | ||
![]() |
b6a1332124 | ||
![]() |
0251997703 | ||
![]() |
57faa9fb4a | ||
![]() |
ba95f66ccd | ||
![]() |
9465873dbd | ||
![]() |
b5a9fe4fe1 | ||
![]() |
6531e2e970 | ||
![]() |
4f900c9451 | ||
![]() |
f97f267a96 | ||
![]() |
6cd8f54869 | ||
![]() |
9718fb788e | ||
![]() |
38651edf3e | ||
![]() |
d34f1a654f | ||
![]() |
5abc74b66b | ||
![]() |
a848764318 | ||
![]() |
c0c6fddcbb | ||
![]() |
95ac26f05d | ||
![]() |
1f852648ef | ||
![]() |
b7da4361c3 | ||
![]() |
71b369d40e | ||
![]() |
4d8cf56922 | ||
![]() |
1a6e0ba5a1 | ||
![]() |
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 |
@@ -11,13 +11,24 @@
|
||||
version: 2.1
|
||||
orbs:
|
||||
aws-cli: circleci/aws-cli@2.0.6
|
||||
macos: circleci/macos@2.5.1 # For Rosetta (see below)
|
||||
node: circleci/node@5.2.0 # For a recent npm version (see below)
|
||||
jobs:
|
||||
# Build the **entire** app for macOS.
|
||||
build-macos:
|
||||
macos:
|
||||
xcode: 14.2.0
|
||||
resource_class: macos.m1.large.gen1
|
||||
steps:
|
||||
- checkout
|
||||
# Install Rosetta for AWS CLI and disable TSO to speed up S3 uploads (https://support.circleci.com/hc/en-us/articles/19334402064027-Troubleshooting-slow-uploads-to-S3-for-jobs-using-an-m1-macOS-resource-class)
|
||||
- macos/install-rosetta
|
||||
- run: sudo sysctl net.inet.tcp.tso=0
|
||||
|
||||
# Install a recent version of npm to workaround a notarization issue because of a symlink made by npm: https://github.com/electron-userland/electron-builder/issues/7755
|
||||
# Node.js v20.14.0 comes with npm v10.7.0.
|
||||
- node/install:
|
||||
node-version: "20.14.0"
|
||||
|
||||
# System dependencies (for Emscripten and upload)
|
||||
- run:
|
||||
@@ -30,7 +41,7 @@ jobs:
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd ..
|
||||
|
||||
# GDevelop.js dependencies
|
||||
- restore_cache:
|
||||
@@ -62,9 +73,10 @@ 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 && CI=false 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.
|
||||
@@ -106,7 +118,7 @@ jobs:
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd ..
|
||||
|
||||
- run:
|
||||
name: Install system dependencies for Electron builder
|
||||
@@ -126,7 +138,8 @@ jobs:
|
||||
# Build GDevelop.js (and run tests to ensure it works)
|
||||
- run:
|
||||
name: Build GDevelop.js
|
||||
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test && cd ..
|
||||
# Use "--runInBand" as it's faster and avoid deadlocks on CircleCI Linux machines (probably because limited in processes number).
|
||||
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test -- --runInBand && cd ..
|
||||
|
||||
# GDevelop IDE dependencies (after building GDevelop.js to avoid downloading a pre-built version)
|
||||
- run:
|
||||
@@ -183,7 +196,7 @@ jobs:
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd ..
|
||||
|
||||
# GDevelop.js dependencies
|
||||
- restore_cache:
|
||||
@@ -199,7 +212,8 @@ jobs:
|
||||
# Build GDevelop.js (and run tests to ensure it works)
|
||||
- run:
|
||||
name: Build GDevelop.js
|
||||
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test && cd ..
|
||||
# Use "--runInBand" as it's faster and avoid deadlocks on CircleCI Linux machines (probably because limited in processes number).
|
||||
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test -- --runInBand && cd ..
|
||||
|
||||
- save_cache:
|
||||
paths:
|
||||
|
14
.devcontainer/devcontainer.json
Normal file
14
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"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"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -1,12 +1,11 @@
|
||||
Core/GDCore/Serialization/rapidjson/rapidjson.h/* linguist-vendored
|
||||
Core/GDCore/TinyXml/* linguist-vendored
|
||||
Extensions/ParticleSystem/SPARK/* linguist-vendored
|
||||
Extensions/PhysicsBehavior/Box2D/* linguist-vendored
|
||||
Extensions/PhysicsBehavior/box2djs/* linguist-vendored
|
||||
Extensions/Physics2Behavior/box2d.js linguist-vendored
|
||||
Extensions/BBText/pixi-multistyle-text/* linguist-vendored
|
||||
Extensions/P2P/A_peer.js linguist-vendored
|
||||
Extensions/Multiplayer/peer.js linguist-vendored
|
||||
Extensions/Shopify/shopify-buy.umd.polyfilled.min.js linguist-vendored
|
||||
Extensions/TileMap/pako/* linguist-vendored
|
||||
Extensions/TileMap/pixi-tilemap/* linguist-vendored
|
||||
Extensions/TweenBehavior/shifty.js linguist-vendored
|
||||
|
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.
|
11
.github/ISSUE_TEMPLATE/--bug-report.yml
vendored
11
.github/ISSUE_TEMPLATE/--bug-report.yml
vendored
@@ -2,18 +2,21 @@ 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
|
||||
- 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: |
|
||||
@@ -27,6 +30,7 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: platform
|
||||
attributes:
|
||||
label: GDevelop platform
|
||||
description: Which platform of GDevelop are you using?
|
||||
@@ -38,6 +42,7 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: gdevelop_version
|
||||
attributes:
|
||||
label: GDevelop version
|
||||
description: |
|
||||
@@ -47,6 +52,7 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: platform_info
|
||||
attributes:
|
||||
label: Platform info
|
||||
value: |
|
||||
@@ -66,6 +72,7 @@ body:
|
||||
|
||||
</details>
|
||||
- type: textarea
|
||||
id: additional_context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here.
|
||||
|
2
.github/workflows/extract-translations.yml
vendored
2
.github/workflows/extract-translations.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
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
|
||||
|
4
.github/workflows/update-translations.yml
vendored
4
.github/workflows/update-translations.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
cache: "npm"
|
||||
cache-dependency-path: "newIDE/app/package-lock.json"
|
||||
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Create a Pull Request with the changes
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
commit-message: Update translations [skip ci]
|
||||
branch: chore/update-translations
|
||||
|
@@ -14,7 +14,7 @@ tasks:
|
||||
init: |
|
||||
sudo apt-get update
|
||||
sudo apt install cmake python-is-python3 python3-distutils -y
|
||||
git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd ..
|
||||
cd GDevelop.js
|
||||
npm install
|
||||
source ../emsdk/emsdk_env.sh && npm run build -- --dev
|
||||
|
@@ -56,6 +56,7 @@ blocks:
|
||||
- name: GDJS typing and documentation generation
|
||||
commands:
|
||||
- checkout
|
||||
- cache restore newIDE-app-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum newIDE/app/package-lock.json)
|
||||
- cache restore GDJS-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/package-lock.json)
|
||||
- cache restore GDJS-tests-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/tests/package-lock.json)
|
||||
- cd GDJS
|
||||
|
37
.travis.yml
37
.travis.yml
@@ -17,11 +17,11 @@ cache:
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
# Build dependencies:
|
||||
- cmake
|
||||
- p7zip-full
|
||||
# Build dependencies:
|
||||
- cmake
|
||||
- p7zip-full
|
||||
|
||||
before_install:
|
||||
# This workaround is required to avoid libstdc++ errors (Emscripten requires a recent version of libstdc++)
|
||||
@@ -29,47 +29,48 @@ before_install:
|
||||
- sudo dpkg --force-all -i libstdc++6
|
||||
|
||||
install:
|
||||
# Ensure we use a recent version of Node.js (and npm).
|
||||
# Ensure we use a recent version of Node.js (and npm).
|
||||
- nvm install v16 && nvm use v16
|
||||
#Compile the tests only for GDCore
|
||||
#Compile the tests only for GDCore
|
||||
- mkdir .build-tests
|
||||
- cd .build-tests
|
||||
- cmake -DBUILD_GDJS=FALSE -DBUILD_TESTS=TRUE -DCMAKE_CXX_COMPILER=$(which $CXX) -DCMAKE_C_COMPILER=$(which $CC) ..
|
||||
- make -j 4
|
||||
- cd ..
|
||||
# Install Emscripten (for GDevelop.js)
|
||||
- git clone https://github.com/juj/emsdk.git
|
||||
- cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
# Install GDevelop.js dependencies
|
||||
# Install Emscripten (for GDevelop.js)
|
||||
# Specify the tag for the core repository to avois breaking changes.
|
||||
- git clone --depth 1 --branch 3.1.21 https://github.com/juj/emsdk.git
|
||||
- cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd ..
|
||||
# Install GDevelop.js dependencies
|
||||
- cd GDevelop.js && npm install && cd ..
|
||||
# Build GDevelop.js
|
||||
# (in a subshell to avoid Emscripten polluting the Node.js and npm version for the rest of the build)
|
||||
# Build GDevelop.js
|
||||
# (in a subshell to avoid Emscripten polluting the Node.js and npm version for the rest of the build)
|
||||
- (set -e; cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && cd ..)
|
||||
# Install newIDE tests dependencies
|
||||
# Install newIDE tests dependencies
|
||||
- npm -v
|
||||
- cd newIDE/app && npm install
|
||||
- cd ../..
|
||||
# Install GDJS tests dependencies
|
||||
# Install GDJS tests dependencies
|
||||
- cd GDJS && npm install && cd tests && npm install
|
||||
- cd ../..
|
||||
|
||||
script:
|
||||
# GDCore tests:
|
||||
# GDCore tests:
|
||||
- cd .build-tests
|
||||
- Core/GDCore_tests
|
||||
- cd ..
|
||||
# GDevelop.js tests
|
||||
# GDevelop.js tests
|
||||
- cd GDevelop.js
|
||||
- npm test
|
||||
- cd ..
|
||||
# newIDE tests:
|
||||
# newIDE tests:
|
||||
- cd newIDE/app
|
||||
- npm test
|
||||
- npm run flow
|
||||
- npm run check-format
|
||||
- npm run check-script-types
|
||||
- cd ../..
|
||||
# GDJS tests:
|
||||
# GDJS tests:
|
||||
- cd GDJS
|
||||
- npm run check-format
|
||||
- cd ..
|
||||
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -113,7 +113,8 @@
|
||||
"memory_resource": "cpp",
|
||||
"__bits": "cpp",
|
||||
"__verbose_abort": "cpp",
|
||||
"variant": "cpp"
|
||||
"variant": "cpp",
|
||||
"charconv": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
|
1
.vscode/tasks.json
vendored
1
.vscode/tasks.json
vendored
@@ -8,6 +8,7 @@
|
||||
"group": "build",
|
||||
"label": "Start development server",
|
||||
"detail": "Starts the GDevelop development server.",
|
||||
"options": { "env": { "NODE_OPTIONS": "--max-old-space-size=8192" } },
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "cra",
|
||||
|
@@ -60,7 +60,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Release" AND NOT WIN32 AND CMAKE_COMPILER_IS_
|
||||
endif()
|
||||
|
||||
#Activate C++11
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
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
|
||||
@@ -77,7 +77,8 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
-Wno-unused-private-field
|
||||
|
||||
# Make as much warnings considered as errors as possible (only one for now).
|
||||
-Werror=return-stack-address)
|
||||
-Werror=return-stack-address
|
||||
-Werror=return-type)
|
||||
endif()
|
||||
|
||||
# Define common directories:
|
||||
|
@@ -58,99 +58,7 @@
|
||||
* Common functions and tools for programming.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup TinyXml Integrated TinyXml library
|
||||
*
|
||||
* See the full documentation of TinyXml [here](http://www.grinninglizard.com/tinyxmldocs/index.html).
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup SpriteObjectExtension Standard Sprite Object extension
|
||||
* \ingroup BuiltinExtensions
|
||||
*/
|
||||
|
||||
/**
|
||||
* \class TiXmlAttribute
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlAttributeSet
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlBase
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlComment
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlCursor
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlDeclaration
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlDocument
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlElement
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlHandle
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlNode
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlOutStream
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlParsingData
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlPrinter
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlString
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlText
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlUnknown
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlVisitor
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
*/
|
@@ -45,10 +45,41 @@ 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("variable");
|
||||
metadata.SetExtraInfo("AllowUndeclaredVariable");
|
||||
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("variable");
|
||||
metadata.SetExtraInfo("AllowUndeclaredVariable");
|
||||
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;
|
||||
|
@@ -8,7 +8,6 @@
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/TinyXml/tinyxml.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@@ -64,12 +64,6 @@ class GD_CORE_API ForEachEvent : public gd::BaseEvent {
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element);
|
||||
|
||||
std::vector<gd::Expression*> GetAllObjectExpressions() {
|
||||
std::vector<gd::Expression*> allObjectExpressions;
|
||||
allObjectExpressions.push_back(&objectsToPick);
|
||||
return allObjectExpressions;
|
||||
}
|
||||
|
||||
private:
|
||||
gd::Expression objectsToPick;
|
||||
gd::InstructionsList conditions;
|
||||
|
@@ -10,7 +10,6 @@
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/TinyXml/tinyxml.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@@ -131,34 +131,40 @@ 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) |
|
||||
return BaseEvent::AcceptVisitor(eventVisitor) ||
|
||||
eventVisitor.VisitLinkEvent(*this);
|
||||
}
|
||||
|
||||
|
@@ -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));
|
||||
|
||||
|
@@ -4,8 +4,8 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_REPEATEVENT_H
|
||||
#define GDCORE_REPEATEVENT_H
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
namespace gd {
|
||||
@@ -36,10 +36,10 @@ class GD_CORE_API RepeatEvent : public gd::BaseEvent {
|
||||
const gd::InstructionsList& GetActions() const { return actions; };
|
||||
gd::InstructionsList& GetActions() { return actions; };
|
||||
|
||||
const gd::String& GetRepeatExpression() const {
|
||||
return repeatNumberExpression.GetPlainString();
|
||||
const gd::Expression& GetRepeatExpression() const {
|
||||
return repeatNumberExpression;
|
||||
};
|
||||
void SetRepeatExpression(gd::String repeatNumberExpression_) {
|
||||
void SetRepeatExpressionPlainString(gd::String repeatNumberExpression_) {
|
||||
repeatNumberExpression = gd::Expression(repeatNumberExpression_);
|
||||
};
|
||||
|
||||
@@ -68,5 +68,3 @@ class GD_CORE_API RepeatEvent : public gd::BaseEvent {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_REPEATEVENT_H
|
||||
|
@@ -15,7 +15,8 @@ using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
StandardEvent::StandardEvent() : BaseEvent() {}
|
||||
StandardEvent::StandardEvent()
|
||||
: BaseEvent(), variables(gd::VariablesContainer::SourceType::Local) {}
|
||||
|
||||
StandardEvent::~StandardEvent(){};
|
||||
|
||||
@@ -57,6 +58,9 @@ void StandardEvent::SerializeTo(SerializerElement& element) const {
|
||||
if (!events.IsEmpty())
|
||||
gd::EventsListSerialization::SerializeEventsTo(events,
|
||||
element.AddChild("events"));
|
||||
if (HasVariables()) {
|
||||
variables.SerializeTo(element.AddChild("variables"));
|
||||
}
|
||||
}
|
||||
|
||||
void StandardEvent::UnserializeFrom(gd::Project& project,
|
||||
@@ -71,6 +75,11 @@ void StandardEvent::UnserializeFrom(gd::Project& project,
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
}
|
||||
|
||||
variables.Clear();
|
||||
if (element.HasChild("variables")) {
|
||||
variables.UnserializeFrom(element.GetChild("variables"));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -4,13 +4,13 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef GDCORE_STANDARDEVENT_H
|
||||
#define GDCORE_STANDARDEVENT_H
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Events/InstructionsList.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
class Project;
|
||||
@@ -33,6 +33,10 @@ class GD_CORE_API StandardEvent : public gd::BaseEvent {
|
||||
virtual const gd::EventsList& GetSubEvents() const { return events; };
|
||||
virtual gd::EventsList& GetSubEvents() { return events; };
|
||||
|
||||
virtual bool CanHaveVariables() const { return true; }
|
||||
virtual const gd::VariablesContainer& GetVariables() const { return variables; };
|
||||
virtual gd::VariablesContainer& GetVariables() { return variables; };
|
||||
|
||||
const gd::InstructionsList& GetConditions() const { return conditions; };
|
||||
gd::InstructionsList& GetConditions() { return conditions; };
|
||||
|
||||
@@ -53,9 +57,7 @@ class GD_CORE_API StandardEvent : public gd::BaseEvent {
|
||||
gd::InstructionsList conditions;
|
||||
gd::InstructionsList actions;
|
||||
EventsList events;
|
||||
VariablesContainer variables;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_STANDARDEVENT_H
|
||||
#endif
|
||||
|
117
Core/GDCore/Events/CodeGeneration/DiagnosticReport.h
Normal file
117
Core/GDCore/Events/CodeGeneration/DiagnosticReport.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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 <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
class GD_CORE_API ProjectDiagnostic {
|
||||
public:
|
||||
enum ErrorType {
|
||||
UndeclaredVariable,
|
||||
MissingBehavior,
|
||||
UnknownObject,
|
||||
MismatchedObjectType,
|
||||
};
|
||||
|
||||
ProjectDiagnostic(ErrorType type_, const gd::String &message_,
|
||||
const gd::String &actualValue_,
|
||||
const gd::String &expectedValue_, const gd::String &objectName_ = "")
|
||||
: type(type_), message(message_), actualValue(actualValue_), expectedValue(expectedValue_),
|
||||
objectName(objectName_){};
|
||||
virtual ~ProjectDiagnostic(){};
|
||||
|
||||
ErrorType GetType() const { return type; };
|
||||
const gd::String &GetMessage() const { return message; }
|
||||
const gd::String &GetObjectName() const { return objectName; }
|
||||
const gd::String &GetActualValue() const { return actualValue; }
|
||||
const gd::String &GetExpectedValue() const { return expectedValue; }
|
||||
|
||||
private:
|
||||
ErrorType type;
|
||||
gd::String message;
|
||||
gd::String objectName;
|
||||
gd::String actualValue;
|
||||
gd::String expectedValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
class GD_CORE_API DiagnosticReport {
|
||||
public:
|
||||
DiagnosticReport(){};
|
||||
virtual ~DiagnosticReport(){};
|
||||
|
||||
void Add(const gd::ProjectDiagnostic &projectDiagnostic) {
|
||||
projectDiagnostics.push_back(
|
||||
gd::make_unique<gd::ProjectDiagnostic>(projectDiagnostic));
|
||||
};
|
||||
|
||||
const ProjectDiagnostic &Get(std::size_t index) const {
|
||||
return *projectDiagnostics[index].get();
|
||||
};
|
||||
|
||||
std::size_t Count() const { return projectDiagnostics.size(); };
|
||||
|
||||
const gd::String &GetSceneName() const { return sceneName; }
|
||||
|
||||
void SetSceneName(const gd::String &sceneName_) {
|
||||
sceneName = sceneName_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<gd::ProjectDiagnostic>> projectDiagnostics;
|
||||
gd::String sceneName;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
class GD_CORE_API WholeProjectDiagnosticReport {
|
||||
public:
|
||||
WholeProjectDiagnosticReport(){};
|
||||
virtual ~WholeProjectDiagnosticReport(){};
|
||||
|
||||
const DiagnosticReport &Get(std::size_t index) const {
|
||||
return *diagnosticReports[index].get();
|
||||
};
|
||||
|
||||
void Clear() {
|
||||
diagnosticReports.clear();
|
||||
};
|
||||
|
||||
DiagnosticReport& AddNewDiagnosticReportForScene(const gd::String &sceneName) {
|
||||
auto diagnosticReport = gd::make_unique<gd::DiagnosticReport>();
|
||||
diagnosticReport->SetSceneName(sceneName);
|
||||
diagnosticReports.push_back(std::move(diagnosticReport));
|
||||
return *diagnosticReports[diagnosticReports.size() - 1].get();
|
||||
};
|
||||
|
||||
std::size_t Count() const { return diagnosticReports.size(); };
|
||||
|
||||
bool HasAnyIssue() {
|
||||
for (auto& diagnosticReport : diagnosticReports) {
|
||||
if (diagnosticReport->Count() > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<gd::DiagnosticReport>> diagnosticReports;
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -15,16 +15,48 @@
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.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.
|
||||
|
||||
// TODO Factorize with the iteration on all effects for resource exposure.
|
||||
// TODO Implement an ArbitraryEffectWorker and add a method in ProjectBrowserHelper
|
||||
|
||||
// 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 +65,34 @@ 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);
|
||||
// Add objects effects
|
||||
gd::ProjectBrowserHelper::ExposeProjectObjects(project, effectsCodeGenerator);
|
||||
|
||||
// Add event-based objects layouts effects
|
||||
for (std::size_t s = 0; s < project.GetEventsFunctionsExtensionsCount();
|
||||
s++) {
|
||||
auto &eventsFunctionExtension = project.GetEventsFunctionsExtension(s);
|
||||
|
||||
auto &eventsBasedObjects = eventsFunctionExtension.GetEventsBasedObjects();
|
||||
for (std::size_t objectIndex = 0;
|
||||
objectIndex < eventsBasedObjects.GetCount(); ++objectIndex) {
|
||||
auto &eventsBasedObject = eventsBasedObjects.Get(objectIndex);
|
||||
|
||||
auto &layers = eventsBasedObject.GetLayers();
|
||||
for (std::size_t l = 0; l < layers.GetLayersCount(); ++l) {
|
||||
auto &effects = layers.GetLayer(l).GetEffects();
|
||||
for (std::size_t e = 0; e < effects.GetEffectsCount(); ++e) {
|
||||
auto &effect = effects.GetEffect(e);
|
||||
effectsCodeGenerator.AddEffectIncludeFiles(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);
|
||||
});
|
||||
}
|
||||
|
||||
} // 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
|
||||
|
@@ -3,8 +3,8 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef EVENTSCODEGENERATIONCONTEXT_H
|
||||
#define EVENTSCODEGENERATIONCONTEXT_H
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
@@ -325,4 +325,3 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
#endif // EVENTSCODEGENERATIONCONTEXT_H
|
||||
|
@@ -14,8 +14,10 @@
|
||||
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/Events/ExpressionVariableNameFinder.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 +70,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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,12 +255,12 @@ gd::String EventsCodeGenerator::GenerateMutatorCall(
|
||||
}
|
||||
|
||||
gd::String operatorStr = arguments[operatorIndex];
|
||||
if (operatorStr.size() > 2)
|
||||
if (operatorStr.size() > 2 && operatorStr[0] == '\"') {
|
||||
operatorStr = operatorStr.substr(
|
||||
1,
|
||||
operatorStr.length() - 1 -
|
||||
1); // Operator contains quote which must be removed.
|
||||
|
||||
}
|
||||
auto mutators = instrInfos.codeExtraInformation.optionalMutators;
|
||||
auto mutator = mutators.find(operatorStr);
|
||||
if (mutator == mutators.end()) {
|
||||
@@ -250,6 +280,9 @@ gd::String EventsCodeGenerator::GenerateMutatorCall(
|
||||
argumentsStr += arguments[i];
|
||||
}
|
||||
}
|
||||
if (instrInfos.GetManipulatedType() == "boolean") {
|
||||
return callStartString + "(" + argumentsStr + ")." + mutator->second;
|
||||
}
|
||||
|
||||
return callStartString + "(" + argumentsStr + ")." + mutator->second + "(" +
|
||||
rhs + ")";
|
||||
@@ -289,23 +322,30 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
condition.SetParameters(parameters);
|
||||
}
|
||||
|
||||
gd::EventsCodeGenerator::CheckBehaviorParameters(condition, instrInfos);
|
||||
// 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(
|
||||
const auto &expectedObjectType =
|
||||
instrInfos.parameters[pNb].GetExtraInfo();
|
||||
const auto &actualObjectType =
|
||||
GetObjectsContainersList().GetTypeOfObject(objectInParameter);
|
||||
if (!GetObjectsContainersList().HasObjectOrGroupNamed(
|
||||
objectInParameter)) {
|
||||
gd::ProjectDiagnostic projectDiagnostic(
|
||||
gd::ProjectDiagnostic::ErrorType::UnknownObject, "",
|
||||
objectInParameter, "");
|
||||
diagnosticReport->Add(projectDiagnostic);
|
||||
return "/* Unknown object - skipped. */";
|
||||
} else if (!instrInfos.parameters[pNb].GetExtraInfo().empty() &&
|
||||
gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
|
||||
GetObjectsAndGroups(),
|
||||
objectInParameter) !=
|
||||
instrInfos.parameters[pNb].GetExtraInfo()) {
|
||||
} else if (!expectedObjectType.empty() &&
|
||||
actualObjectType != expectedObjectType) {
|
||||
gd::ProjectDiagnostic projectDiagnostic(
|
||||
gd::ProjectDiagnostic::ErrorType::MismatchedObjectType, "",
|
||||
actualObjectType, expectedObjectType, objectInParameter);
|
||||
diagnosticReport->Add(projectDiagnostic);
|
||||
return "/* Mismatched object type - skipped. */";
|
||||
}
|
||||
}
|
||||
@@ -315,19 +355,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]);
|
||||
@@ -344,22 +378,25 @@ 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());
|
||||
if (instrInfos.parameters.size() >= 2) {
|
||||
const gd::String &objectName = condition.GetParameter(0).GetPlainString();
|
||||
const gd::String &behaviorName =
|
||||
condition.GetParameter(1).GetPlainString();
|
||||
const gd::String &actualBehaviorType =
|
||||
GetObjectsContainersList().GetTypeOfBehavior(behaviorName);
|
||||
|
||||
std::vector<gd::String> realObjects =
|
||||
ExpandObjectsName(objectName, context);
|
||||
GetObjectsContainersList().ExpandObjectName(
|
||||
objectName, context.GetCurrentObject());
|
||||
|
||||
const BehaviorMetadata &autoInfo =
|
||||
MetadataProvider::GetBehaviorMetadata(platform, actualBehaviorType);
|
||||
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
// Setup context
|
||||
const BehaviorMetadata& autoInfo =
|
||||
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
|
||||
AddIncludeFiles(autoInfo.includeFiles);
|
||||
context.SetCurrentObject(realObjects[i]);
|
||||
context.ObjectsListNeeded(realObjects[i]);
|
||||
@@ -369,7 +406,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
condition.GetParameters(), instrInfos.parameters, context);
|
||||
conditionCode += GenerateBehaviorCondition(
|
||||
realObjects[i],
|
||||
condition.GetParameter(1).GetPlainString(),
|
||||
behaviorName,
|
||||
autoInfo,
|
||||
arguments,
|
||||
instrInfos,
|
||||
@@ -444,6 +481,33 @@ gd::String EventsCodeGenerator::GenerateConditionsListCode(
|
||||
return outputCode;
|
||||
}
|
||||
|
||||
void EventsCodeGenerator::CheckBehaviorParameters(
|
||||
const gd::Instruction &instruction,
|
||||
const gd::InstructionMetadata &instrInfos) {
|
||||
gd::ParameterMetadataTools::IterateOverParameters(
|
||||
instruction.GetParameters(), instrInfos.parameters,
|
||||
[this](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue,
|
||||
const gd::String &lastObjectName) {
|
||||
if (ParameterMetadata::IsBehavior(parameterMetadata.GetType())) {
|
||||
const gd::String &behaviorName = parameterValue.GetPlainString();
|
||||
const gd::String &actualBehaviorType =
|
||||
GetObjectsContainersList().GetTypeOfBehaviorInObjectOrGroup(
|
||||
lastObjectName, behaviorName);
|
||||
const gd::String &expectedBehaviorType =
|
||||
parameterMetadata.GetExtraInfo();
|
||||
|
||||
if (!expectedBehaviorType.empty() &&
|
||||
actualBehaviorType != expectedBehaviorType) {
|
||||
gd::ProjectDiagnostic projectDiagnostic(
|
||||
gd::ProjectDiagnostic::ErrorType::MissingBehavior, "",
|
||||
actualBehaviorType, expectedBehaviorType, lastObjectName);
|
||||
diagnosticReport->Add(projectDiagnostic);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate code for an action.
|
||||
*/
|
||||
@@ -481,21 +545,29 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
action.SetParameters(parameters);
|
||||
}
|
||||
|
||||
gd::EventsCodeGenerator::CheckBehaviorParameters(action, instrInfos);
|
||||
// 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(
|
||||
|
||||
const auto &expectedObjectType =
|
||||
instrInfos.parameters[pNb].GetExtraInfo();
|
||||
const auto &actualObjectType =
|
||||
GetObjectsContainersList().GetTypeOfObject(objectInParameter);
|
||||
if (!GetObjectsContainersList().HasObjectOrGroupNamed(
|
||||
objectInParameter)) {
|
||||
gd::ProjectDiagnostic projectDiagnostic(
|
||||
gd::ProjectDiagnostic::ErrorType::UnknownObject, "",
|
||||
objectInParameter, "");
|
||||
diagnosticReport->Add(projectDiagnostic);
|
||||
return "/* Unknown object - skipped. */";
|
||||
} else if (!instrInfos.parameters[pNb].GetExtraInfo().empty() &&
|
||||
gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
|
||||
GetObjectsAndGroups(),
|
||||
objectInParameter) !=
|
||||
instrInfos.parameters[pNb].GetExtraInfo()) {
|
||||
} else if (!expectedObjectType.empty() &&
|
||||
actualObjectType != expectedObjectType) {
|
||||
gd::ProjectDiagnostic projectDiagnostic(
|
||||
gd::ProjectDiagnostic::ErrorType::MismatchedObjectType, "",
|
||||
actualObjectType, expectedObjectType, objectInParameter);
|
||||
diagnosticReport->Add(projectDiagnostic);
|
||||
return "/* Mismatched object type - skipped. */";
|
||||
}
|
||||
}
|
||||
@@ -507,18 +579,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]);
|
||||
@@ -535,24 +602,25 @@ 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());
|
||||
|
||||
if (instrInfos.parameters.size() >= 2) {
|
||||
const gd::String &objectName = action.GetParameter(0).GetPlainString();
|
||||
const gd::String &behaviorName = action.GetParameter(1).GetPlainString();
|
||||
const gd::String &actualBehaviorType =
|
||||
GetObjectsContainersList().GetTypeOfBehavior(behaviorName);
|
||||
|
||||
std::vector<gd::String> realObjects =
|
||||
ExpandObjectsName(objectName, context);
|
||||
GetObjectsContainersList().ExpandObjectName(
|
||||
objectName, context.GetCurrentObject());
|
||||
|
||||
const BehaviorMetadata &autoInfo =
|
||||
MetadataProvider::GetBehaviorMetadata(platform, actualBehaviorType);
|
||||
|
||||
AddIncludeFiles(autoInfo.includeFiles);
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
// Setup context
|
||||
const BehaviorMetadata& autoInfo =
|
||||
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
|
||||
AddIncludeFiles(autoInfo.includeFiles);
|
||||
context.SetCurrentObject(realObjects[i]);
|
||||
context.ObjectsListNeeded(realObjects[i]);
|
||||
|
||||
@@ -561,7 +629,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
action.GetParameters(), instrInfos.parameters, context);
|
||||
actionCode +=
|
||||
GenerateBehaviorAction(realObjects[i],
|
||||
action.GetParameter(1).GetPlainString(),
|
||||
behaviorName,
|
||||
autoInfo,
|
||||
functionCallName,
|
||||
arguments,
|
||||
@@ -585,6 +653,29 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
return actionCode;
|
||||
}
|
||||
|
||||
gd::String EventsCodeGenerator::GenerateLocalVariablesStackAccessor() {
|
||||
return (HasProjectAndLayout() ? GetCodeNamespace()
|
||||
: "eventsFunctionContext") +
|
||||
".localVariables";
|
||||
}
|
||||
|
||||
gd::String EventsCodeGenerator::GenerateAnyOrSceneVariableGetter(
|
||||
const gd::Expression &variableExpression,
|
||||
EventsCodeGenerationContext &context) {
|
||||
const auto variableName = gd::ExpressionVariableNameFinder::GetVariableName(
|
||||
*variableExpression.GetRootNode());
|
||||
|
||||
gd::String variableParameterType =
|
||||
GetProjectScopedContainers().GetVariablesContainersList().Has(
|
||||
variableName)
|
||||
? "variable"
|
||||
: "scenevar";
|
||||
|
||||
return gd::ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
*this, context, variableParameterType,
|
||||
variableExpression.GetPlainString(), "", "AllowUndeclaredVariable");
|
||||
}
|
||||
|
||||
const EventsCodeGenerator::CallbackDescriptor
|
||||
EventsCodeGenerator::GenerateCallback(
|
||||
const gd::String& callbackID,
|
||||
@@ -609,14 +700,23 @@ EventsCodeGenerator::GenerateCallback(
|
||||
actionsCode += "} //End of subevents\n";
|
||||
}
|
||||
|
||||
gd::String restoreLocalVariablesCode;
|
||||
restoreLocalVariablesCode +=
|
||||
"asyncObjectsList.restoreLocalVariablesContainers(" +
|
||||
GenerateLocalVariablesStackAccessor() + ");\n";
|
||||
|
||||
// Compose the callback function and add outside main
|
||||
const gd::String actionsDeclarationsCode =
|
||||
GenerateObjectsDeclarationCode(callbackContext);
|
||||
|
||||
const gd::String clearLocalVariablesCode =
|
||||
GenerateLocalVariablesStackAccessor() + ".length = 0;\n";
|
||||
|
||||
const gd::String callbackCode = callbackFunctionName + " = function (" +
|
||||
GenerateEventsParameters(callbackContext) +
|
||||
") {\n" + actionsDeclarationsCode +
|
||||
actionsCode + "}\n";
|
||||
") {\n" + restoreLocalVariablesCode +
|
||||
actionsDeclarationsCode + actionsCode +
|
||||
clearLocalVariablesCode + "}\n";
|
||||
|
||||
AddCustomCodeOutsideMain(callbackCode);
|
||||
|
||||
@@ -668,18 +768,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,
|
||||
@@ -691,25 +779,26 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
|
||||
if (ParameterMetadata::IsExpression("number", metadata.GetType())) {
|
||||
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
*this, context, "number", parameter, lastObjectName);
|
||||
*this, context, "number", parameter, lastObjectName, metadata.GetExtraInfo());
|
||||
} else if (ParameterMetadata::IsExpression("string", metadata.GetType())) {
|
||||
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
*this, context, "string", parameter, lastObjectName);
|
||||
*this, context, "string", parameter, lastObjectName, metadata.GetExtraInfo());
|
||||
} else if (ParameterMetadata::IsExpression("variable", metadata.GetType())) {
|
||||
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
*this, context, metadata.GetType(), parameter, lastObjectName);
|
||||
*this, context, metadata.GetType(), parameter, lastObjectName, metadata.GetExtraInfo());
|
||||
} else if (ParameterMetadata::IsObject(metadata.GetType())) {
|
||||
// It would be possible to run a gd::ExpressionCodeGenerator if later
|
||||
// objects can have nested objects, or function returning objects.
|
||||
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();
|
||||
if (argOutput != "=" && argOutput != "+" && argOutput != "-" &&
|
||||
argOutput != "/" && argOutput != "*") {
|
||||
argOutput != "/" && argOutput != "*" && argOutput != "True" &&
|
||||
argOutput != "False" && argOutput != "Toggle") {
|
||||
cout << "Warning: Bad operator: Set to = by default." << endl;
|
||||
argOutput = "=";
|
||||
}
|
||||
@@ -728,6 +817,8 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
metadata.GetType() == "tilesetResource" ||
|
||||
metadata.GetType() == "videoResource" ||
|
||||
metadata.GetType() == "model3DResource" ||
|
||||
metadata.GetType() == "atlasResource" ||
|
||||
metadata.GetType() == "spineResource" ||
|
||||
// Deprecated, old parameter names:
|
||||
metadata.GetType() == "password" || metadata.GetType() == "musicfile" ||
|
||||
metadata.GetType() == "soundfile" || metadata.GetType() == "police") {
|
||||
@@ -877,6 +968,11 @@ gd::String EventsCodeGenerator::GenerateEventsListCode(
|
||||
gd::EventsList& events, EventsCodeGenerationContext& parentContext) {
|
||||
gd::String output;
|
||||
for (std::size_t eId = 0; eId < events.size(); ++eId) {
|
||||
auto& event = events[eId];
|
||||
if (event.HasVariables()) {
|
||||
GetProjectScopedContainers().GetVariablesContainersList().Push(event.GetVariables());
|
||||
}
|
||||
|
||||
// Each event has its own context : Objects picked in an event are totally
|
||||
// different than the one picked in another.
|
||||
gd::EventsCodeGenerationContext newContext;
|
||||
@@ -897,13 +993,17 @@ gd::String EventsCodeGenerator::GenerateEventsListCode(
|
||||
|
||||
auto& context = reuseParentContext ? reusedContext : newContext;
|
||||
|
||||
gd::String eventCoreCode = events[eId].GenerateEventCode(*this, context);
|
||||
gd::String eventCoreCode = event.GenerateEventCode(*this, context);
|
||||
gd::String scopeBegin = GenerateScopeBegin(context);
|
||||
gd::String scopeEnd = GenerateScopeEnd(context);
|
||||
gd::String declarationsCode = GenerateObjectsDeclarationCode(context);
|
||||
|
||||
output += "\n" + scopeBegin + "\n" + declarationsCode + "\n" +
|
||||
eventCoreCode + "\n" + scopeEnd + "\n";
|
||||
|
||||
if (event.HasVariables()) {
|
||||
GetProjectScopedContainers().GetVariablesContainersList().Pop();
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
@@ -923,41 +1023,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
|
||||
@@ -974,6 +1039,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
|
||||
@@ -1112,7 +1179,13 @@ gd::String EventsCodeGenerator::GenerateFreeAction(
|
||||
// Generate call
|
||||
gd::String call;
|
||||
if (instrInfos.codeExtraInformation.type == "number" ||
|
||||
instrInfos.codeExtraInformation.type == "string") {
|
||||
instrInfos.codeExtraInformation.type == "string" ||
|
||||
// Boolean actions declared with addExpressionAndConditionAndAction uses
|
||||
// MutatorAndOrAccessor even though they don't declare an operator parameter.
|
||||
// Boolean operators are only used with SetMutators or SetCustomCodeGenerator.
|
||||
(instrInfos.codeExtraInformation.type == "boolean" &&
|
||||
instrInfos.codeExtraInformation.accessType ==
|
||||
gd::InstructionMetadata::ExtraInformation::AccessType::Mutators)) {
|
||||
if (instrInfos.codeExtraInformation.accessType ==
|
||||
gd::InstructionMetadata::ExtraInformation::MutatorAndOrAccessor)
|
||||
call = GenerateOperatorCall(
|
||||
@@ -1271,12 +1344,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),
|
||||
@@ -1284,15 +1369,14 @@ EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
|
||||
compilationForRuntime(false),
|
||||
maxCustomConditionsDepth(0),
|
||||
maxConditionsListsSize(0),
|
||||
eventsListNextUniqueId(0){};
|
||||
eventsListNextUniqueId(0),
|
||||
diagnosticReport(nullptr){};
|
||||
|
||||
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),
|
||||
@@ -1300,6 +1384,7 @@ EventsCodeGenerator::EventsCodeGenerator(
|
||||
compilationForRuntime(false),
|
||||
maxCustomConditionsDepth(0),
|
||||
maxConditionsListsSize(0),
|
||||
eventsListNextUniqueId(0){};
|
||||
eventsListNextUniqueId(0),
|
||||
diagnosticReport(nullptr){};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -3,8 +3,7 @@
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_EVENTSCODEGENERATOR_H
|
||||
#define GDCORE_EVENTSCODEGENERATOR_H
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <utility>
|
||||
@@ -12,13 +11,17 @@
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Events/CodeGeneration/DiagnosticReport.h"
|
||||
#include "GDCore/Project/ProjectScopedContainers.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class EventsList;
|
||||
class Expression;
|
||||
class Project;
|
||||
class Layout;
|
||||
class ObjectsContainer;
|
||||
class ObjectsContainersList;
|
||||
class ExternalEvents;
|
||||
class ParameterMetadata;
|
||||
class ObjectMetadata;
|
||||
@@ -56,9 +59,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 +329,22 @@ 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();
|
||||
};
|
||||
|
||||
const gd::ProjectScopedContainers& GetProjectScopedContainers() const {
|
||||
return projectScopedContainers;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the objects/groups used for code generation.
|
||||
* @brief Give access to the project scoped containers as code generation might
|
||||
* push and pop variable containers (for local variables).
|
||||
* This could be passed as a parameter recursively in code generation, but this requires
|
||||
* heavy refactoring. Instead, we use this single instance.
|
||||
*/
|
||||
const gd::ObjectsContainer& GetObjectsAndGroups() const {
|
||||
return objectsAndGroups;
|
||||
gd::ProjectScopedContainers& GetProjectScopedContainers() {
|
||||
return projectScopedContainers;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -363,22 +370,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.
|
||||
@@ -392,6 +383,14 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
*/
|
||||
size_t GetMaxConditionsListsSize() const { return maxConditionsListsSize; }
|
||||
|
||||
void SetDiagnosticReport(gd::DiagnosticReport* diagnosticReport_) {
|
||||
diagnosticReport = diagnosticReport_;
|
||||
}
|
||||
|
||||
gd::DiagnosticReport* GetDiagnosticReport() {
|
||||
return diagnosticReport;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate the full name for accessing to a boolean variable used for
|
||||
* conditions.
|
||||
@@ -468,7 +467,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
*/
|
||||
virtual gd::String GetCodeNamespace() { return ""; };
|
||||
|
||||
enum VariableScope { LAYOUT_VARIABLE = 0, PROJECT_VARIABLE, OBJECT_VARIABLE };
|
||||
enum VariableScope { LAYOUT_VARIABLE = 0, PROJECT_VARIABLE, OBJECT_VARIABLE, ANY_VARIABLE };
|
||||
|
||||
/**
|
||||
* Generate a single unique number for the specified instruction.
|
||||
@@ -493,10 +492,28 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
*/
|
||||
size_t GenerateSingleUsageUniqueIdForEventsList();
|
||||
|
||||
virtual gd::String GenerateRelationalOperation(
|
||||
const gd::String& relationalOperator,
|
||||
const gd::String& lhs,
|
||||
const gd::String& rhs);
|
||||
|
||||
/**
|
||||
* \brief Generate the code to access the local variables stack.
|
||||
*/
|
||||
virtual gd::String GenerateLocalVariablesStackAccessor();
|
||||
|
||||
/**
|
||||
* \brief Generate an any variable getter that fallbacks on scene variable for
|
||||
* compatibility reason.
|
||||
*/
|
||||
gd::String
|
||||
GenerateAnyOrSceneVariableGetter(const gd::Expression &variableExpression,
|
||||
EventsCodeGenerationContext &context);
|
||||
|
||||
protected:
|
||||
virtual const gd::String GenerateRelationalOperatorCodes(
|
||||
const gd::String& operatorString);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* \brief Generate the code for a single parameter.
|
||||
*
|
||||
@@ -549,11 +566,15 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
const VariableScope& scope,
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
const gd::String& objectName) {
|
||||
// This code is only used as a mock.
|
||||
// See the real implementation in GDJS.
|
||||
if (scope == LAYOUT_VARIABLE) {
|
||||
return "getLayoutVariable(" + variableName + ")";
|
||||
|
||||
} else if (scope == PROJECT_VARIABLE) {
|
||||
return "getProjectVariable(" + variableName + ")";
|
||||
} else if (scope == ANY_VARIABLE) {
|
||||
return "getAnyVariable(" + variableName + ")";
|
||||
}
|
||||
|
||||
return "getVariableForObject(" + objectName + ", " + variableName + ")";
|
||||
@@ -566,6 +587,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.
|
||||
@@ -594,6 +621,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.
|
||||
@@ -673,7 +711,8 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* The default implementation generates C-style code : It wraps the predicate
|
||||
* inside parenthesis and add a !.
|
||||
*/
|
||||
virtual gd::String GenerateNegatedPredicate(const gd::String& predicate) const {
|
||||
virtual gd::String GenerateNegatedPredicate(
|
||||
const gd::String& predicate) const {
|
||||
return "!(" + predicate + ")";
|
||||
};
|
||||
|
||||
@@ -734,6 +773,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,
|
||||
@@ -775,10 +815,13 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
virtual gd::String GenerateGetBehaviorNameCode(
|
||||
const gd::String& behaviorName);
|
||||
|
||||
void CheckBehaviorParameters(
|
||||
const gd::Instruction &instruction,
|
||||
const gd::InstructionMetadata &instrInfos);
|
||||
|
||||
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.
|
||||
@@ -806,8 +849,9 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
instructionUniqueIds; ///< The unique ids generated for instructions.
|
||||
size_t eventsListNextUniqueId; ///< The next identifier to use for an events
|
||||
///< list function name.
|
||||
|
||||
gd::DiagnosticReport* diagnosticReport;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EVENTSCODEGENERATOR_H
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
@@ -25,8 +26,12 @@
|
||||
#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"
|
||||
#include "GDCore/Events/CodeGeneration/DiagnosticReport.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -35,7 +40,8 @@ gd::String ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
EventsCodeGenerationContext& context,
|
||||
const gd::String& rootType,
|
||||
const gd::Expression& expression,
|
||||
const gd::String& rootObjectName) {
|
||||
const gd::String& rootObjectName,
|
||||
const gd::String& extraInfo) {
|
||||
ExpressionCodeGenerator generator(rootType, rootObjectName, codeGenerator, context);
|
||||
|
||||
auto node = expression.GetRootNode();
|
||||
@@ -47,15 +53,35 @@ gd::String ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
}
|
||||
|
||||
gd::ExpressionValidator validator(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
rootType);
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType,
|
||||
extraInfo);
|
||||
node->Visit(validator);
|
||||
if (!validator.GetFatalErrors().empty()) {
|
||||
std::cout << "Error: \"" << validator.GetFatalErrors()[0]->GetMessage()
|
||||
<< "\" in: \"" << expression.GetPlainString() << "\" ("
|
||||
<< rootType << ")" << std::endl;
|
||||
|
||||
auto *diagnosticReport = codeGenerator.GetDiagnosticReport();
|
||||
if (diagnosticReport) {
|
||||
for (auto *error : validator.GetFatalErrors()) {
|
||||
if (error->GetType() ==
|
||||
gd::ExpressionParserError::ErrorType::UndeclaredVariable ||
|
||||
error->GetType() ==
|
||||
gd::ExpressionParserError::ErrorType::UnknownIdentifier) {
|
||||
|
||||
const auto& variableName = error->GetActualValue();
|
||||
if (!variableName.empty()) {
|
||||
gd::ProjectDiagnostic projectDiagnostic(
|
||||
gd::ProjectDiagnostic::ErrorType::UndeclaredVariable,
|
||||
error->GetMessage(), error->GetActualValue(),
|
||||
"", error->GetObjectName());
|
||||
diagnosticReport->Add(projectDiagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return generator.GenerateDefaultValue(rootType);
|
||||
}
|
||||
|
||||
@@ -100,35 +126,86 @@ 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 == "variable"
|
||||
? gd::EventsCodeGenerator::ANY_VARIABLE
|
||||
: 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);
|
||||
}, [&]() {
|
||||
output += codeGenerator.GenerateGetVariable(
|
||||
node.name, gd::EventsCodeGenerator::ANY_VARIABLE, 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,24 +214,25 @@ 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);
|
||||
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
|
||||
EventsCodeGenerator::VariableScope scope =
|
||||
type == "globalvar"
|
||||
type == "variable"
|
||||
? gd::EventsCodeGenerator::ANY_VARIABLE
|
||||
: type == "globalvar"
|
||||
? gd::EventsCodeGenerator::PROJECT_VARIABLE
|
||||
: ((type == "scenevar")
|
||||
: type == "scenevar"
|
||||
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
|
||||
: gd::EventsCodeGenerator::OBJECT_VARIABLE);
|
||||
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
|
||||
|
||||
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsContainersList(),
|
||||
rootObjectName,
|
||||
node);
|
||||
output += codeGenerator.GenerateGetVariable(
|
||||
@@ -162,30 +240,50 @@ 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 apart 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);
|
||||
}, [&]() {
|
||||
output += codeGenerator.GenerateGetVariable(
|
||||
node.identifierName, gd::EventsCodeGenerator::ANY_VARIABLE, 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)) {
|
||||
@@ -236,11 +334,6 @@ 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.GetIncludeFiles());
|
||||
|
||||
@@ -261,20 +354,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 +370,6 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
|
||||
parametersCode,
|
||||
functionOutput,
|
||||
context);
|
||||
}
|
||||
}
|
||||
|
||||
return functionOutput;
|
||||
@@ -294,11 +380,6 @@ 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.GetIncludeFiles());
|
||||
|
||||
@@ -317,12 +398,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 +438,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 +508,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 +517,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);
|
||||
|
@@ -59,7 +59,8 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
|
||||
EventsCodeGenerationContext& context,
|
||||
const gd::String& type,
|
||||
const gd::Expression& expression,
|
||||
const gd::String& objectName = "");
|
||||
const gd::String& objectName = "",
|
||||
const gd::String& extraInfo = "");
|
||||
|
||||
const gd::String& GetOutput() { return output; };
|
||||
|
||||
@@ -102,6 +103,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;
|
||||
|
@@ -17,6 +17,7 @@
|
||||
namespace gd {
|
||||
|
||||
EventsList BaseEvent::badSubEvents;
|
||||
VariablesContainer BaseEvent::badLocalVariables;
|
||||
std::vector<gd::String> BaseEvent::emptyDependencies;
|
||||
gd::String BaseEvent::emptySourceFile;
|
||||
|
||||
@@ -28,6 +29,8 @@ BaseEvent::BaseEvent()
|
||||
|
||||
bool BaseEvent::HasSubEvents() const { return !GetSubEvents().IsEmpty(); }
|
||||
|
||||
bool BaseEvent::HasVariables() const { return GetVariables().Count() > 0; }
|
||||
|
||||
gd::String BaseEvent::GenerateEventCode(
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
|
@@ -3,9 +3,7 @@
|
||||
* 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 GDCORE_EVENT_H
|
||||
#define GDCORE_EVENT_H
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
@@ -26,6 +24,7 @@ class SerializerElement;
|
||||
class Instruction;
|
||||
class EventVisitor;
|
||||
class ReadOnlyEventVisitor;
|
||||
class VariablesContainer;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -92,6 +91,32 @@ class GD_CORE_API BaseEvent {
|
||||
*/
|
||||
bool HasSubEvents() const;
|
||||
|
||||
/**
|
||||
* Derived class have to redefine this function, so as to return true, if they
|
||||
* can have local variables.
|
||||
*/
|
||||
virtual bool CanHaveVariables() const { return false; }
|
||||
|
||||
/**
|
||||
* Return the local variables, if applicable.
|
||||
*/
|
||||
virtual const gd::VariablesContainer& GetVariables() const {
|
||||
return badLocalVariables;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the local variables, if applicable.
|
||||
*/
|
||||
virtual gd::VariablesContainer& GetVariables() {
|
||||
return badLocalVariables;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return true if the events has local variables.
|
||||
* \warning This is only applicable when CanHaveVariables() return true.
|
||||
*/
|
||||
bool HasVariables() const;
|
||||
|
||||
/**
|
||||
* \brief Return a list of all conditions of the event.
|
||||
* \note Used to preprocess or search in the conditions.
|
||||
@@ -240,7 +265,7 @@ 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;
|
||||
///@}
|
||||
@@ -281,15 +306,6 @@ class GD_CORE_API BaseEvent {
|
||||
* \brief True if the event should be folded in the events editor.
|
||||
*/
|
||||
bool IsFolded() const { return folded; }
|
||||
|
||||
/**
|
||||
* \brief Return a list of all objects linked to the event.
|
||||
*/
|
||||
virtual std::vector<gd::Expression*> GetAllObjectExpressions() {
|
||||
std::vector<gd::Expression*> allObjectExpressions;
|
||||
return allObjectExpressions;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
std::weak_ptr<gd::BaseEvent>
|
||||
@@ -310,6 +326,7 @@ class GD_CORE_API BaseEvent {
|
||||
///< Used for saving the event for instance.
|
||||
|
||||
static gd::EventsList badSubEvents;
|
||||
static gd::VariablesContainer badLocalVariables;
|
||||
static std::vector<gd::String> emptyDependencies;
|
||||
static gd::String emptySourceFile;
|
||||
};
|
||||
@@ -334,6 +351,3 @@ class EmptyEvent : public BaseEvent {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EVENT_H
|
||||
#endif
|
||||
|
@@ -18,7 +18,6 @@ class BaseEvent;
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
class TiXmlElement;
|
||||
|
||||
#undef CreateEvent
|
||||
|
||||
|
@@ -38,7 +38,7 @@ using namespace gd::GrammarTerminals;
|
||||
* parser by refactoring out the dependency on gd::MetadataProvider (injecting
|
||||
* instead functions to be called to query supported functions).
|
||||
*
|
||||
* \see gd::ExpressionParserDiagnostic
|
||||
* \see gd::ExpressionParserError
|
||||
* \see gd::ExpressionNode
|
||||
*/
|
||||
class GD_CORE_API ExpressionParser2 {
|
||||
@@ -47,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.
|
||||
*/
|
||||
@@ -267,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());
|
||||
@@ -283,8 +277,11 @@ class GD_CORE_API ExpressionParser2 {
|
||||
|
||||
std::unique_ptr<VariableNode> Variable(const gd::String &name, gd::ExpressionParserLocation nameLocation) {
|
||||
auto variable = gd::make_unique<VariableNode>(name);
|
||||
variable->child = VariableAccessorOrVariableBracketAccessor();
|
||||
variable->child->parent = variable.get();
|
||||
|
||||
if (CheckIfChar(IsOpeningSquareBracket) || CheckIfChar(IsDot)) {
|
||||
variable->child = VariableAccessorOrVariableBracketAccessor();
|
||||
variable->child->parent = variable.get();
|
||||
}
|
||||
|
||||
variable->location = ExpressionParserLocation(
|
||||
nameLocation.GetStartPosition(), GetCurrentPosition());
|
||||
@@ -308,8 +305,12 @@ class GD_CORE_API ExpressionParser2 {
|
||||
"bracket for each opening bracket."));
|
||||
}
|
||||
SkipIfChar(IsClosingSquareBracket);
|
||||
child->child = VariableAccessorOrVariableBracketAccessor();
|
||||
child->child->parent = child.get();
|
||||
|
||||
SkipAllWhitespaces();
|
||||
if (CheckIfChar(IsOpeningSquareBracket) || CheckIfChar(IsDot)) {
|
||||
child->child = VariableAccessorOrVariableBracketAccessor();
|
||||
child->child->parent = child.get();
|
||||
}
|
||||
child->location =
|
||||
ExpressionParserLocation(childStartPosition, GetCurrentPosition());
|
||||
|
||||
@@ -318,11 +319,18 @@ 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();
|
||||
child->child->parent = child.get();
|
||||
if (identifierAndLocation.name.empty()) {
|
||||
child->diagnostic = RaiseSyntaxError(_("A name should be entered after the dot."));
|
||||
}
|
||||
|
||||
SkipAllWhitespaces();
|
||||
if (CheckIfChar(IsOpeningSquareBracket) || CheckIfChar(IsDot)) {
|
||||
child->child = VariableAccessorOrVariableBracketAccessor();
|
||||
child->child->parent = child.get();
|
||||
}
|
||||
child->nameLocation = identifierAndLocation.location;
|
||||
child->dotLocation = dotLocation;
|
||||
child->location =
|
||||
@@ -331,7 +339,11 @@ class GD_CORE_API ExpressionParser2 {
|
||||
return std::move(child);
|
||||
}
|
||||
|
||||
return std::move(gd::make_unique<VariableAccessorOrVariableBracketAccessorNode>());
|
||||
// Should never happen, unless a node called this function without checking if the current character
|
||||
// was a dot or an opening bracket - this means there is an error in the grammar.
|
||||
auto unrecognisedNode = gd::make_unique<VariableAccessorOrVariableBracketAccessorNode>();
|
||||
unrecognisedNode->diagnostic = RaiseSyntaxError(_("A dot or bracket was expected here."));
|
||||
return std::move(unrecognisedNode);
|
||||
}
|
||||
|
||||
std::unique_ptr<FunctionCallNode> FreeFunction(
|
||||
@@ -358,27 +370,33 @@ 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;
|
||||
|
||||
std::unique_ptr<gd::ExpressionParserError> emptyNameError = childIdentifierName.empty() ?
|
||||
RaiseSyntaxError(_("A name should be entered after the dot.")) : nullptr;
|
||||
|
||||
SkipAllWhitespaces();
|
||||
|
||||
if (IsNamespaceSeparator()) {
|
||||
ExpressionParserLocation namespaceSeparatorLocation =
|
||||
SkipNamespaceSeparator();
|
||||
SkipAllWhitespaces();
|
||||
return BehaviorFunction(parentIdentifier,
|
||||
auto behaviorFunction = BehaviorFunction(parentIdentifier,
|
||||
childIdentifierName,
|
||||
parentIdentifierLocation,
|
||||
parentIdentifierDotLocation,
|
||||
childIdentifierNameLocation,
|
||||
namespaceSeparatorLocation);
|
||||
|
||||
if (emptyNameError) behaviorFunction->diagnostic = std::move(emptyNameError);
|
||||
return std::move(behaviorFunction);
|
||||
} else if (CheckIfChar(IsOpeningParenthesis)) {
|
||||
ExpressionParserLocation openingParenthesisLocation = SkipChar();
|
||||
|
||||
@@ -387,7 +405,7 @@ class GD_CORE_API ExpressionParser2 {
|
||||
childIdentifierName);
|
||||
auto parametersNode = Parameters(function.get(), parentIdentifier);
|
||||
function->parameters = std::move(parametersNode.parameters),
|
||||
function->diagnostic = std::move(parametersNode.diagnostic);
|
||||
function->diagnostic = emptyNameError ? std::move(emptyNameError) : std::move(parametersNode.diagnostic);
|
||||
|
||||
function->location = ExpressionParserLocation(
|
||||
parentIdentifierLocation.GetStartPosition(), GetCurrentPosition());
|
||||
@@ -400,6 +418,8 @@ class GD_CORE_API ExpressionParser2 {
|
||||
return std::move(function);
|
||||
} else if (CheckIfChar(IsDot) || CheckIfChar(IsOpeningSquareBracket)) {
|
||||
auto variable = gd::make_unique<VariableNode>(parentIdentifier);
|
||||
variable->diagnostic = std::move(emptyNameError);
|
||||
|
||||
auto child =
|
||||
gd::make_unique<VariableAccessorNode>(childIdentifierName);
|
||||
child->child = VariableAccessorOrVariableBracketAccessor();
|
||||
@@ -420,17 +440,12 @@ 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;
|
||||
node->identifierNameDotLocation = parentIdentifierDotLocation;
|
||||
node->childIdentifierNameLocation = childIdentifierNameLocation;
|
||||
node->diagnostic = std::move(emptyNameError);
|
||||
return std::move(node);
|
||||
}
|
||||
|
||||
@@ -503,11 +518,6 @@ class GD_CORE_API ExpressionParser2 {
|
||||
std::vector<std::unique_ptr<ExpressionNode>> parameters;
|
||||
gd::String lastObjectName = "";
|
||||
|
||||
// By convention, object is always the first parameter, and behavior the
|
||||
// second one.
|
||||
size_t parameterIndex =
|
||||
WrittenParametersFirstIndex(objectName, behaviorName);
|
||||
|
||||
bool previousCharacterIsParameterSeparator = false;
|
||||
while (!IsEndReached()) {
|
||||
SkipAllWhitespaces();
|
||||
@@ -526,7 +536,6 @@ class GD_CORE_API ExpressionParser2 {
|
||||
SkipAllWhitespaces();
|
||||
previousCharacterIsParameterSeparator = CheckIfChar(IsParameterSeparator);
|
||||
SkipIfChar(IsParameterSeparator);
|
||||
parameterIndex++;
|
||||
}
|
||||
|
||||
ExpressionParserLocation invalidClosingParenthesisLocation;
|
||||
@@ -538,28 +547,28 @@ class GD_CORE_API ExpressionParser2 {
|
||||
}
|
||||
///@}
|
||||
|
||||
std::unique_ptr<ExpressionParserDiagnostic> ValidateOperator(
|
||||
std::unique_ptr<ExpressionParserError> ValidateOperator(
|
||||
gd::String::value_type operatorChar) {
|
||||
if (operatorChar == '+' || operatorChar == '-' || operatorChar == '/' ||
|
||||
operatorChar == '*') {
|
||||
return gd::make_unique<ExpressionParserDiagnostic>();
|
||||
return std::unique_ptr<ExpressionParserError>(nullptr);
|
||||
}
|
||||
return gd::make_unique<ExpressionParserError>(
|
||||
"invalid_operator",
|
||||
gd::ExpressionParserError::ErrorType::InvalidOperator,
|
||||
_("You've used an operator that is not supported. Operator should be "
|
||||
"either +, -, / or *."),
|
||||
GetCurrentPosition());
|
||||
}
|
||||
|
||||
std::unique_ptr<ExpressionParserDiagnostic> ValidateUnaryOperator(
|
||||
std::unique_ptr<ExpressionParserError> ValidateUnaryOperator(
|
||||
gd::String::value_type operatorChar,
|
||||
size_t position) {
|
||||
if (operatorChar == '+' || operatorChar == '-') {
|
||||
return gd::make_unique<ExpressionParserDiagnostic>();
|
||||
return std::unique_ptr<ExpressionParserError>(nullptr);
|
||||
}
|
||||
|
||||
return gd::make_unique<ExpressionParserError>(
|
||||
"invalid_operator",
|
||||
gd::ExpressionParserError::ErrorType::InvalidOperator,
|
||||
_("You've used an \"unary\" operator that is not supported. Operator "
|
||||
"should be "
|
||||
"either + or -."),
|
||||
@@ -625,13 +634,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() &&
|
||||
(CheckIfChar(IsAllowedInIdentifier)
|
||||
// Allow whitespace in identifier name for compatibility
|
||||
|| expression[currentPosition] == ' ')) {
|
||||
|| (allowDeprecatedSpacesInName && expression[currentPosition] == ' '))) {
|
||||
name += expression[currentPosition];
|
||||
currentPosition++;
|
||||
}
|
||||
@@ -710,13 +719,15 @@ class GD_CORE_API ExpressionParser2 {
|
||||
std::unique_ptr<ExpressionParserError> RaiseSyntaxError(
|
||||
const gd::String &message) {
|
||||
return std::move(gd::make_unique<ExpressionParserError>(
|
||||
"syntax_error", message, GetCurrentPosition()));
|
||||
gd::ExpressionParserError::ErrorType::SyntaxError, message,
|
||||
GetCurrentPosition()));
|
||||
}
|
||||
|
||||
std::unique_ptr<ExpressionParserError> RaiseTypeError(
|
||||
const gd::String &message, size_t beginningPosition) {
|
||||
return std::move(gd::make_unique<ExpressionParserError>(
|
||||
"type_error", message, beginningPosition, GetCurrentPosition()));
|
||||
gd::ExpressionParserError::ErrorType::MismatchedType, message,
|
||||
beginningPosition, GetCurrentPosition()));
|
||||
}
|
||||
///@}
|
||||
|
||||
|
@@ -6,5 +6,5 @@
|
||||
#include "ExpressionParser2Node.h"
|
||||
|
||||
namespace gd {
|
||||
gd::String ExpressionParserDiagnostic::noMessage = "";
|
||||
|
||||
}
|
@@ -3,14 +3,14 @@
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_EXPRESSIONPARSER2NODES_H
|
||||
#define GDCORE_EXPRESSIONPARSER2NODES_H
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "ExpressionParser2NodeWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class Expression;
|
||||
class ObjectsContainer;
|
||||
@@ -40,50 +40,57 @@ struct GD_CORE_API ExpressionParserLocation {
|
||||
size_t endPosition;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief A diagnostic that can be attached to a gd::ExpressionNode.
|
||||
*/
|
||||
struct GD_CORE_API ExpressionParserDiagnostic {
|
||||
virtual ~ExpressionParserDiagnostic() = default;
|
||||
virtual bool IsError() { return false; }
|
||||
virtual const gd::String &GetMessage() { return noMessage; }
|
||||
virtual size_t GetStartPosition() { return 0; }
|
||||
virtual size_t GetEndPosition() { return 0; }
|
||||
|
||||
private:
|
||||
static gd::String noMessage;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief An error that can be attached to a gd::ExpressionNode.
|
||||
*/
|
||||
struct GD_CORE_API ExpressionParserError : public ExpressionParserDiagnostic {
|
||||
ExpressionParserError(const gd::String &type_,
|
||||
struct GD_CORE_API ExpressionParserError {
|
||||
enum ErrorType {
|
||||
SyntaxError,
|
||||
InvalidOperator,
|
||||
MismatchedType,
|
||||
UndeclaredVariable,
|
||||
UnknownIdentifier,
|
||||
BracketsNotAllowedForObjects,
|
||||
TooFewParameters,
|
||||
TooManyParameters,
|
||||
InvalidFunctionName,
|
||||
MalformedVariableParameter,
|
||||
MalformedObjectParameter,
|
||||
UnknownParameterType,
|
||||
MissingBehavior,
|
||||
VariableNameCollision,
|
||||
};
|
||||
|
||||
ExpressionParserError(gd::ExpressionParserError::ErrorType type_,
|
||||
const gd::String &message_,
|
||||
const ExpressionParserLocation &location_)
|
||||
: type(type_), message(message_), location(location_){};
|
||||
ExpressionParserError(const gd::String &type_,
|
||||
const gd::String &message_,
|
||||
size_t position_)
|
||||
const ExpressionParserLocation &location_,
|
||||
const gd::String &actualValue_ = "",
|
||||
const gd::String &objectName_ = "")
|
||||
: type(type_), message(message_), location(location_),
|
||||
actualValue(actualValue_), objectName(objectName_){};
|
||||
ExpressionParserError(gd::ExpressionParserError::ErrorType type_,
|
||||
const gd::String &message_, size_t position_)
|
||||
: type(type_), message(message_), location(position_){};
|
||||
ExpressionParserError(const gd::String &type_,
|
||||
const gd::String &message_,
|
||||
size_t startPosition_,
|
||||
ExpressionParserError(gd::ExpressionParserError::ErrorType type_,
|
||||
const gd::String &message_, size_t startPosition_,
|
||||
size_t endPosition_)
|
||||
: type(type_),
|
||||
message(message_),
|
||||
: type(type_), message(message_),
|
||||
location(startPosition_, endPosition_){};
|
||||
virtual ~ExpressionParserError(){};
|
||||
|
||||
bool IsError() override { return true; }
|
||||
const gd::String &GetMessage() override { return message; }
|
||||
size_t GetStartPosition() override { return location.GetStartPosition(); }
|
||||
size_t GetEndPosition() override { return location.GetEndPosition(); }
|
||||
gd::ExpressionParserError::ErrorType GetType() { return type; }
|
||||
const gd::String &GetMessage() { return message; }
|
||||
const gd::String &GetObjectName() { return objectName; }
|
||||
const gd::String &GetActualValue() { return actualValue; }
|
||||
size_t GetStartPosition() { return location.GetStartPosition(); }
|
||||
size_t GetEndPosition() { return location.GetEndPosition(); }
|
||||
|
||||
private:
|
||||
gd::String type;
|
||||
private:
|
||||
gd::ExpressionParserError::ErrorType type;
|
||||
gd::String message;
|
||||
ExpressionParserLocation location;
|
||||
gd::String objectName;
|
||||
gd::String actualValue;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -95,7 +102,7 @@ struct GD_CORE_API ExpressionNode {
|
||||
virtual ~ExpressionNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker){};
|
||||
|
||||
std::unique_ptr<ExpressionParserDiagnostic> diagnostic;
|
||||
std::unique_ptr<ExpressionParserError> diagnostic;
|
||||
ExpressionParserLocation location; ///< The location of the entire node. Some
|
||||
/// nodes might have other locations
|
||||
/// stored inside them. For example, a
|
||||
@@ -189,7 +196,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 +246,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 +275,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 +293,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 +311,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
|
||||
@@ -424,5 +432,3 @@ struct GD_CORE_API EmptyNode : public FunctionCallOrObjectFunctionNameOrEmptyNod
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
||||
|
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2Node.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
|
||||
namespace gd {
|
||||
@@ -43,6 +44,11 @@ class GD_CORE_API ExpressionParser2NodePrinter
|
||||
*/
|
||||
const gd::String& GetOutput() { return output; };
|
||||
|
||||
static gd::String PrintStringLiteral(const gd::String& str) {
|
||||
return "\"" +
|
||||
str.FindAndReplace("\\", "\\\\").FindAndReplace("\"", "\\\"") + "\"";
|
||||
}
|
||||
|
||||
protected:
|
||||
void OnVisitSubExpressionNode(SubExpressionNode& node) override {
|
||||
output += "(";
|
||||
@@ -69,10 +75,7 @@ class GD_CORE_API ExpressionParser2NodePrinter
|
||||
}
|
||||
void OnVisitNumberNode(NumberNode& node) override { output += node.number; }
|
||||
void OnVisitTextNode(TextNode& node) override {
|
||||
output +=
|
||||
"\"" +
|
||||
node.text.FindAndReplace("\\", "\\\\").FindAndReplace("\"", "\\\"") +
|
||||
"\"";
|
||||
output += PrintStringLiteral(node.text);
|
||||
}
|
||||
void OnVisitVariableNode(VariableNode& node) override {
|
||||
output += node.name;
|
||||
@@ -97,8 +100,8 @@ class GD_CORE_API ExpressionParser2NodePrinter
|
||||
}
|
||||
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {
|
||||
if (!node.behaviorFunctionName.empty()) {
|
||||
output +=
|
||||
node.objectName + "." + node.objectFunctionOrBehaviorName + "::" + node.behaviorFunctionName;
|
||||
output += node.objectName + "." + node.objectFunctionOrBehaviorName +
|
||||
"::" + node.behaviorFunctionName;
|
||||
} else {
|
||||
output += node.objectName + "." + node.objectFunctionOrBehaviorName;
|
||||
}
|
||||
|
@@ -75,10 +75,21 @@ 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 whitespaces (space, line break, carriage return).
|
||||
* `, . " () [] {} + - < > ? ^ = \ : ! / * ~ ' % # @ | & $ ;`
|
||||
* 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
|
||||
@@ -96,7 +107,7 @@ inline bool IsAllowedInIdentifier(gd::String::value_type character) {
|
||||
if (!IsParameterSeparator(character) && !IsDot(character) &&
|
||||
!IsQuote(character) && !IsBracket(character) &&
|
||||
!IsExpressionOperator(character) && !IsTermOperator(character) &&
|
||||
!IsWhitespace(character)) {
|
||||
!IsWhitespace(character) && !IsAdditionalReservedCharacter(character)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -66,6 +66,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Deprecated
|
||||
extension
|
||||
.AddAction("CopyArgumentToVariable",
|
||||
_("Copy function parameter to variable"),
|
||||
@@ -78,9 +79,25 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
.SetHelpPath("/events/functions/return")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "variable")
|
||||
.AddParameter("scenevar", _("Scene variable"))
|
||||
.SetHidden()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("CopyArgumentToVariable2",
|
||||
_("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("variable", _("Variable"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Deprecated
|
||||
extension
|
||||
.AddAction("CopyVariableToArgument",
|
||||
_("Copy variable to function parameter"),
|
||||
@@ -93,6 +110,21 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
.SetHelpPath("/events/functions/return")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "variable")
|
||||
.AddParameter("scenevar", _("Scene variable"))
|
||||
.SetHidden()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("CopyVariableToArgument2",
|
||||
_("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("variable", _("Variable"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -115,21 +147,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"), "number,string,boolean")
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
.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"), "number,string,boolean")
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.SetHidden();
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
|
@@ -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")
|
||||
|
||||
@@ -409,6 +417,93 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.SetDefaultValue("\"\"")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddAction("SetNumberObjectVariable",
|
||||
_("Change variable value"),
|
||||
_("Modify the number value of an object variable."),
|
||||
_("the variable _PARAM1_"),
|
||||
_("Variables"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.UseStandardOperatorParameters("number",
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForLayoutEventsOnly();
|
||||
|
||||
obj.AddAction("SetStringObjectVariable",
|
||||
_("Change text variable"),
|
||||
_("Modify the text of an object variable."),
|
||||
_("the variable _PARAM1_"),
|
||||
_("Variables"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.UseStandardOperatorParameters("string",
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForLayoutEventsOnly();
|
||||
|
||||
obj.AddAction("SetBooleanObjectVariable",
|
||||
_("Change boolean variable"),
|
||||
_("Modify the boolean value of an object variable."),
|
||||
_("Change the variable _PARAM1_ of _PARAM0_: _PARAM2_"),
|
||||
_("Variables"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.AddParameter("operator", _("Value"), "boolean")
|
||||
// This parameter allows to keep the operand expression
|
||||
// when the editor switch between variable instructions.
|
||||
.AddCodeOnlyParameter("yesorno", _("Value"))
|
||||
.SetRelevantForLayoutEventsOnly();
|
||||
|
||||
obj.AddCondition("NumberObjectVariable",
|
||||
_("Variable value"),
|
||||
_("Compare the number value of an object variable."),
|
||||
_("the variable _PARAM1_"),
|
||||
_("Variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForLayoutEventsOnly();
|
||||
|
||||
obj.AddCondition("StringObjectVariable",
|
||||
_("Text variable"),
|
||||
_("Compare the text of an object variable."),
|
||||
_("the variable _PARAM1_"),
|
||||
_("Variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"string", ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForLayoutEventsOnly();
|
||||
|
||||
obj.AddCondition("BooleanObjectVariable",
|
||||
_("Boolean variable"),
|
||||
_("Compare the boolean value of an object variable."),
|
||||
_("The variable _PARAM1_ of _PARAM0_ is _PARAM2_"),
|
||||
_("Variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.AddParameter("trueorfalse", _("Check if the value is"))
|
||||
.SetDefaultValue("true")
|
||||
// This parameter allows to keep the operand expression
|
||||
// when the editor switch between variable instructions.
|
||||
.AddCodeOnlyParameter("yesorno", _("Value"))
|
||||
.SetRelevantForLayoutEventsOnly();
|
||||
|
||||
obj.AddAction("ModVarObjet",
|
||||
_("Change number variable"),
|
||||
_("Modify the number value of an object variable."),
|
||||
@@ -420,7 +515,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.UseStandardOperatorParameters("number",
|
||||
ParameterOptions::MakeNewOptions());
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
obj.AddAction("ModVarObjetTxt",
|
||||
_("Change text variable"),
|
||||
@@ -433,7 +529,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.UseStandardOperatorParameters("string",
|
||||
ParameterOptions::MakeNewOptions());
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
obj.AddAction("SetObjectVariableAsBoolean",
|
||||
_("Change boolean variable"),
|
||||
@@ -446,7 +543,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.AddParameter("trueorfalse", _("New Value:"));
|
||||
.AddParameter("trueorfalse", _("New Value:"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
obj.AddAction(
|
||||
"ToggleObjectVariableAsBoolean",
|
||||
@@ -461,7 +559,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/var.png")
|
||||
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"));
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
obj.AddCondition("ObjectVariableChildExists",
|
||||
_("Child existence"),
|
||||
@@ -542,7 +641,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 +708,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 +718,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"))
|
||||
@@ -635,7 +748,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions());
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
obj.AddCondition("VarObjetTxt",
|
||||
_("Text variable"),
|
||||
@@ -648,7 +762,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"string", ParameterOptions::MakeNewOptions());
|
||||
"string", ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
obj.AddCondition("ObjectVariableAsBoolean",
|
||||
_("Boolean variable"),
|
||||
@@ -661,7 +776,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.AddParameter("trueorfalse", _("Check if the value is"))
|
||||
.SetDefaultValue("true");
|
||||
.SetDefaultValue("true")
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
obj.AddCondition("VarObjetDef",
|
||||
"Variable defined",
|
||||
@@ -675,6 +791,48 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("string", _("Variable"))
|
||||
.SetHidden(); // Deprecated.
|
||||
|
||||
obj.AddAction(
|
||||
"PushStringToObjectVariable",
|
||||
_("Add text variable"),
|
||||
_("Adds a text (string) to the end of an object array variable."),
|
||||
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
|
||||
_("Variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Array variable"))
|
||||
.AddParameter("string", _("Text to add"))
|
||||
.MarkAsAdvanced()
|
||||
.SetRelevantForLayoutEventsOnly();
|
||||
|
||||
obj.AddAction("PushNumberToObjectVariable",
|
||||
_("Add variable array value"),
|
||||
_("Adds a number to the end of an object array variable."),
|
||||
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
|
||||
_("Variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Array variable"))
|
||||
.AddParameter("expression", _("Number to add"))
|
||||
.MarkAsAdvanced()
|
||||
.SetRelevantForLayoutEventsOnly();
|
||||
|
||||
obj.AddAction(
|
||||
"PushBooleanToObjectVariable",
|
||||
_("Add boolean variable"),
|
||||
_("Adds a boolean to the end of an object array variable."),
|
||||
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
|
||||
_("Variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Array variable"))
|
||||
.AddParameter("trueorfalse", _("Boolean to add"))
|
||||
.MarkAsAdvanced()
|
||||
.SetRelevantForLayoutEventsOnly();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction(
|
||||
"ObjectVariablePush",
|
||||
_("Add existing variable"),
|
||||
@@ -686,6 +844,23 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Array variable"))
|
||||
.AddParameter("scenevar", _("Scene variable with the content to add"))
|
||||
.SetParameterLongDescription(_("The content of the object variable will "
|
||||
"*be copied* and added at the "
|
||||
"end of the array."))
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
obj.AddAction(
|
||||
"ObjectVariablePush2",
|
||||
_("Add existing variable"),
|
||||
_("Adds an existing variable to the end of an object array variable."),
|
||||
_("Add variable _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
|
||||
_("Variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Array variable"))
|
||||
.AddParameter("variable", _("Scene variable with the content to add"))
|
||||
.SetParameterLongDescription(_("The content of the object variable will "
|
||||
"*be copied* and added at the "
|
||||
"end of the array."))
|
||||
@@ -702,7 +877,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Array variable"))
|
||||
.AddParameter("string", _("Text to add"))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
obj.AddAction("ObjectVariablePushNumber",
|
||||
_("Add number variable"),
|
||||
@@ -714,7 +890,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Array variable"))
|
||||
.AddParameter("expression", _("Number to add"))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
obj.AddAction(
|
||||
"ObjectVariablePushBool",
|
||||
@@ -727,7 +904,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Array variable"))
|
||||
.AddParameter("trueorfalse", _("Boolean to add"))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
obj.AddAction(
|
||||
"ObjectVariableRemoveAt",
|
||||
@@ -1101,6 +1279,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 +1295,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 +1307,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"));
|
||||
|
||||
@@ -1179,7 +1359,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"));
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
obj.AddExpression(
|
||||
"VariableChildCount",
|
||||
@@ -1196,12 +1377,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectvar", _("Variable"));
|
||||
.AddParameter("objectvar", _("Variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
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,79 +1433,84 @@ 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"),
|
||||
_("Enable effect _PARAM1_ on _PARAM0_: _PARAM2_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
"res/actions/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.AddParameter("object", _("Object"))
|
||||
.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"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
"res/actions/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.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"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
"res/actions/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.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"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
"res/actions/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.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."),
|
||||
_("Effect _PARAM1_ of _PARAM0_ is enabled"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
"res/actions/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.MarkAsSimple()
|
||||
.SetRequiresBaseObjectCapability("effect");
|
||||
.SetHidden();
|
||||
|
||||
obj.AddAction("SetIncludedInParentCollisionMask",
|
||||
_("Include in parent collision mask"),
|
||||
@@ -1595,7 +1782,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("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"))
|
||||
@@ -1626,7 +1813,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("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"))
|
||||
|
@@ -27,7 +27,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Layers and cameras"))
|
||||
.SetIcon("res/conditions/camera24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
|
||||
.SetIcon("res/actions/effect24.png");
|
||||
.SetIcon("res/actions/effect_black.svg");
|
||||
|
||||
extension
|
||||
.AddExpressionAndConditionAndAction(
|
||||
@@ -327,7 +327,25 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
// TODO Deprecated: hide this action in a future release.
|
||||
extension
|
||||
.AddCondition(
|
||||
"CameraZoom",
|
||||
_("Camera zoom"),
|
||||
_("Compare the zoom of a camera of a layer."),
|
||||
_("Zoom of camera _PARAM2_ of layer _PARAM1_"),
|
||||
"",
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Zoom")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"FixCamera",
|
||||
@@ -339,6 +357,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.SetHidden()
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("objectPtr", _("Object"))
|
||||
.AddParameter("expression",
|
||||
@@ -386,7 +405,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
_("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", "")
|
||||
@@ -444,58 +463,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")
|
||||
"res/actions/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.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")
|
||||
"res/actions/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.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")
|
||||
"res/actions/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.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
|
||||
@@ -504,8 +523,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
_("The effect on a layer is enabled"),
|
||||
_("Effect _PARAM2_ on layer _PARAM1_ is enabled"),
|
||||
_(""),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
"res/actions/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
@@ -518,8 +537,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
_("Enable an effect on a layer"),
|
||||
_("Enable effect _PARAM2_ on layer _PARAM1_: _PARAM3_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
"res/actions/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
@@ -548,7 +567,7 @@ 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_"),
|
||||
"",
|
||||
@@ -594,7 +613,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
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_"),
|
||||
|
@@ -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/effect_black.svg");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"EffectBehavior",
|
||||
_("Effect capability"),
|
||||
"Effect",
|
||||
_("Apply visual effects to objects."),
|
||||
"",
|
||||
"res/actions/effect_black.svg",
|
||||
"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/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.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/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.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/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.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/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.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/effect_black.svg",
|
||||
"res/actions/effect_black.svg")
|
||||
.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/effect_black.svg");
|
||||
|
||||
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
|
@@ -68,19 +68,22 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
|
||||
|
||||
extension
|
||||
.AddStrExpression("ToJSON",
|
||||
_("Convert scene variable to JSON"),
|
||||
_("Convert a scene variable to JSON"),
|
||||
_("Convert variable to JSON"),
|
||||
_("Convert a variable to JSON"),
|
||||
_("JSON"),
|
||||
"res/conditions/toujours24_black.png")
|
||||
.AddParameter("scenevar", _("Scene variable to be stringified"));
|
||||
.AddParameter("variable", _("The variable to be stringified"),
|
||||
"AllowUndeclaredVariable");
|
||||
|
||||
// Deprecated
|
||||
extension
|
||||
.AddStrExpression("GlobalVarToJSON",
|
||||
_("Convert global variable to JSON"),
|
||||
_("Convert a global variable to JSON"),
|
||||
_("JSON"),
|
||||
"res/conditions/toujours24_black.png")
|
||||
.AddParameter("globalvar", _("The global variable to be stringified"));
|
||||
.AddParameter("globalvar", _("The global variable to be stringified"))
|
||||
.SetHidden();
|
||||
|
||||
extension
|
||||
.AddStrExpression("ObjectVarToJSON",
|
||||
@@ -91,6 +94,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
|
||||
.AddParameter("objectPtr", _("The object with the variable"))
|
||||
.AddParameter("objectvar", _("The object variable to be stringified"));
|
||||
|
||||
// Deprecated
|
||||
extension
|
||||
.AddAction(
|
||||
"JSONToVariableStructure",
|
||||
@@ -102,8 +106,10 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
|
||||
"res/actions/net.png")
|
||||
.AddParameter("string", _("JSON string"))
|
||||
.AddParameter("scenevar", _("Variable where store the JSON object"))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
extension
|
||||
.AddAction("JSONToGlobalVariableStructure",
|
||||
_("Convert JSON to global variable"),
|
||||
@@ -116,6 +122,20 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
|
||||
.AddParameter("string", _("JSON string"))
|
||||
.AddParameter("globalvar",
|
||||
_("Global variable where store the JSON object"))
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"JSONToVariableStructure2",
|
||||
_("Convert JSON to a variable"),
|
||||
_("Parse a JSON object and store it into a variable"),
|
||||
_("Convert JSON string _PARAM0_ and store it into variable _PARAM1_"),
|
||||
"",
|
||||
"res/actions/net24.png",
|
||||
"res/actions/net.png")
|
||||
.AddParameter("string", _("JSON string"))
|
||||
.AddParameter("variable", _("Variable where to store the JSON object"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
|
@@ -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();
|
||||
}
|
||||
|
||||
|
@@ -98,6 +98,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
.AddParameter("string", _("Group"))
|
||||
.AddParameter("string", _("Text"));
|
||||
|
||||
// Deprecated
|
||||
extension
|
||||
.AddAction(
|
||||
"LireFichierExp",
|
||||
@@ -114,8 +115,27 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
.AddParameter("string", _("Storage name"))
|
||||
.AddParameter("string", _("Group"))
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("scenevar", _("Scene variables"));
|
||||
.AddParameter("scenevar", _("Scene variable"))
|
||||
.SetHidden();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"ReadNumberFromStorage",
|
||||
_("Load a value"),
|
||||
_("Load the value saved in the specified element and store it in a "
|
||||
"variable.\nSpecify the structure leading to the element using / "
|
||||
"(example : Root/Level/Current)\nSpaces are forbidden in element "
|
||||
"names."),
|
||||
_("Load _PARAM1_ from storage _PARAM0_ and store value in _PARAM3_"),
|
||||
"",
|
||||
"res/actions/fichier24.png",
|
||||
"res/actions/fichier.png")
|
||||
.AddParameter("string", _("Storage name"))
|
||||
.AddParameter("string", _("Group"))
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("variable", _("Variable"));
|
||||
|
||||
// Deprecated
|
||||
extension
|
||||
.AddAction(
|
||||
"LireFichierTxt",
|
||||
@@ -133,7 +153,26 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
.AddParameter("string", _("Storage name"))
|
||||
.AddParameter("string", _("Group"))
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("scenevar", _("Scene variables"));
|
||||
.AddParameter("scenevar", _("Scene variable"))
|
||||
.SetHidden();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"ReadStringFromStorage",
|
||||
_("Load a text"),
|
||||
_("Load the text saved in the specified element and store it in a "
|
||||
"variable.\nSpecify the structure leading to the element using / "
|
||||
"(example : Root/Level/Current)\nSpaces are forbidden in element "
|
||||
"names."),
|
||||
_("Load _PARAM1_ from storage _PARAM0_ and store as text in "
|
||||
"_PARAM3_"),
|
||||
"",
|
||||
"res/actions/fichier24.png",
|
||||
"res/actions/fichier.png")
|
||||
.AddParameter("string", _("Storage name"))
|
||||
.AddParameter("string", _("Group"))
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("variable", _("Variable"));
|
||||
|
||||
extension
|
||||
.AddAction("DeleteGroupFichier",
|
||||
|
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
#include "AllBuiltinExtensions.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
@@ -57,7 +58,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
|
||||
extension
|
||||
.AddCondition("DoesSceneExist",
|
||||
_("Does scene exist"),
|
||||
_("Check if scene exists."),
|
||||
_("Check if a scene exists."),
|
||||
_("Scene _PARAM1_ exists"),
|
||||
"",
|
||||
"res/actions/texte.png",
|
||||
@@ -163,6 +164,45 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
|
||||
"res/actions/window.png")
|
||||
.SetHelpPath("/interface/scene-editor/events")
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
|
||||
extension
|
||||
.AddAction("PrioritizeLoadingOfScene",
|
||||
_("Preload scene"),
|
||||
_("Preload a scene resources as soon as possible in background."),
|
||||
_("Preload scene _PARAM1_ in background"),
|
||||
"",
|
||||
"res/actions/hourglass_black.svg",
|
||||
"res/actions/hourglass_black.svg")
|
||||
.SetHelpPath("/all-features/resources-loading")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("sceneName", _("Name of the new scene"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension.AddExpressionAndCondition("number",
|
||||
"SceneLoadingProgress",
|
||||
_("Scene loading progress"),
|
||||
_("The progress of resources loading in background for a scene (between 0 and 1)."),
|
||||
_("_PARAM0_ loading progress"),
|
||||
_(""),
|
||||
"res/actions/hourglass_black.svg")
|
||||
.SetHelpPath("/all-features/resources-loading")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("sceneName", _("Scene name"))
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("AreSceneAssetsLoaded",
|
||||
_("Scene preloaded"),
|
||||
_("Check if scene resources have finished to load in background."),
|
||||
_("Scene _PARAM1_ was preloaded in background"),
|
||||
"",
|
||||
"res/actions/hourglass_black.svg",
|
||||
"res/actions/hourglass_black.svg")
|
||||
.SetHelpPath("/all-features/resources-loading")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("sceneName", _("Scene name"))
|
||||
.MarkAsAdvanced();
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -6,8 +6,6 @@
|
||||
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Animation.h"
|
||||
#include <vector>
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
@@ -4,13 +4,11 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_ANIMATION_H
|
||||
#define GDCORE_ANIMATION_H
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Direction;
|
||||
}
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -93,4 +91,3 @@ class GD_CORE_API Animation {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
#endif // GDCORE_ANIMATION_H
|
||||
|
@@ -3,12 +3,12 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_DIRECTION_H
|
||||
#define GDCORE_DIRECTION_H
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
|
||||
namespace gd {
|
||||
class Sprite;
|
||||
class SerializerElement;
|
||||
}
|
||||
|
||||
@@ -142,4 +142,3 @@ class GD_CORE_API Direction {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
#endif // GDCORE_DIRECTION_H
|
||||
|
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteAnimationList.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Animation.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/Project/InitialInstance.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
Animation SpriteAnimationList::badAnimation;
|
||||
|
||||
SpriteAnimationList::SpriteAnimationList()
|
||||
: adaptCollisionMaskAutomatically(true) {}
|
||||
|
||||
SpriteAnimationList::~SpriteAnimationList(){};
|
||||
|
||||
void SpriteAnimationList::UnserializeFrom(const gd::SerializerElement& element) {
|
||||
adaptCollisionMaskAutomatically =
|
||||
element.GetBoolAttribute("adaptCollisionMaskAutomatically", false);
|
||||
|
||||
RemoveAllAnimations();
|
||||
const gd::SerializerElement& animationsElement =
|
||||
element.GetChild("animations", 0, "Animations");
|
||||
animationsElement.ConsiderAsArrayOf("animation", "Animation");
|
||||
for (std::size_t i = 0; i < animationsElement.GetChildrenCount(); ++i) {
|
||||
const gd::SerializerElement& animationElement =
|
||||
animationsElement.GetChild(i);
|
||||
Animation newAnimation;
|
||||
|
||||
newAnimation.useMultipleDirections = animationElement.GetBoolAttribute(
|
||||
"useMultipleDirections", false, "typeNormal");
|
||||
newAnimation.SetName(animationElement.GetStringAttribute("name", ""));
|
||||
|
||||
// Compatibility with GD <= 3.3
|
||||
if (animationElement.HasChild("Direction")) {
|
||||
for (std::size_t j = 0;
|
||||
j < animationElement.GetChildrenCount("Direction");
|
||||
++j) {
|
||||
Direction direction;
|
||||
direction.UnserializeFrom(animationElement.GetChild("Direction", j));
|
||||
|
||||
newAnimation.SetDirectionsCount(newAnimation.GetDirectionsCount() + 1);
|
||||
newAnimation.SetDirection(direction,
|
||||
newAnimation.GetDirectionsCount() - 1);
|
||||
}
|
||||
}
|
||||
// End of compatibility code
|
||||
else {
|
||||
const gd::SerializerElement& directionsElement =
|
||||
animationElement.GetChild("directions");
|
||||
directionsElement.ConsiderAsArrayOf("direction");
|
||||
for (std::size_t j = 0; j < directionsElement.GetChildrenCount(); ++j) {
|
||||
Direction direction;
|
||||
direction.UnserializeFrom(directionsElement.GetChild(j));
|
||||
|
||||
newAnimation.SetDirectionsCount(newAnimation.GetDirectionsCount() + 1);
|
||||
newAnimation.SetDirection(direction,
|
||||
newAnimation.GetDirectionsCount() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
AddAnimation(newAnimation);
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteAnimationList::SerializeTo(gd::SerializerElement& element) const {
|
||||
element.SetAttribute("adaptCollisionMaskAutomatically",
|
||||
adaptCollisionMaskAutomatically);
|
||||
|
||||
// Animations
|
||||
gd::SerializerElement& animationsElement = element.AddChild("animations");
|
||||
animationsElement.ConsiderAsArrayOf("animation");
|
||||
for (std::size_t k = 0; k < GetAnimationsCount(); k++) {
|
||||
gd::SerializerElement& animationElement =
|
||||
animationsElement.AddChild("animation");
|
||||
|
||||
animationElement.SetAttribute("useMultipleDirections",
|
||||
GetAnimation(k).useMultipleDirections);
|
||||
animationElement.SetAttribute("name", GetAnimation(k).GetName());
|
||||
|
||||
gd::SerializerElement& directionsElement =
|
||||
animationElement.AddChild("directions");
|
||||
directionsElement.ConsiderAsArrayOf("direction");
|
||||
for (std::size_t l = 0; l < GetAnimation(k).GetDirectionsCount(); l++) {
|
||||
GetAnimation(k).GetDirection(l).SerializeTo(
|
||||
directionsElement.AddChild("direction"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteAnimationList::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
for (std::size_t j = 0; j < GetAnimationsCount(); j++) {
|
||||
for (std::size_t k = 0; k < GetAnimation(j).GetDirectionsCount(); k++) {
|
||||
for (std::size_t l = 0;
|
||||
l < GetAnimation(j).GetDirection(k).GetSpritesCount();
|
||||
l++) {
|
||||
worker.ExposeImage(
|
||||
GetAnimation(j).GetDirection(k).GetSprite(l).GetImageName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SpriteAnimationList::HasAnimationNamed(const gd::String &name) const {
|
||||
return !name.empty() && (find_if(animations.begin(), animations.end(),
|
||||
[&name](const Animation &animation) {
|
||||
return animation.GetName() == name;
|
||||
}) != animations.end());
|
||||
}
|
||||
|
||||
const Animation& SpriteAnimationList::GetAnimation(std::size_t nb) const {
|
||||
if (nb >= animations.size()) return badAnimation;
|
||||
|
||||
return animations[nb];
|
||||
}
|
||||
|
||||
Animation& SpriteAnimationList::GetAnimation(std::size_t nb) {
|
||||
if (nb >= animations.size()) return badAnimation;
|
||||
|
||||
return animations[nb];
|
||||
}
|
||||
|
||||
void SpriteAnimationList::AddAnimation(const Animation& animation) {
|
||||
animations.push_back(animation);
|
||||
}
|
||||
|
||||
bool SpriteAnimationList::RemoveAnimation(std::size_t nb) {
|
||||
if (nb >= GetAnimationsCount()) return false;
|
||||
|
||||
animations.erase(animations.begin() + nb);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SpriteAnimationList::SwapAnimations(std::size_t firstIndex,
|
||||
std::size_t secondIndex) {
|
||||
if (firstIndex < animations.size() && secondIndex < animations.size() &&
|
||||
firstIndex != secondIndex)
|
||||
std::swap(animations[firstIndex], animations[secondIndex]);
|
||||
}
|
||||
|
||||
void SpriteAnimationList::MoveAnimation(std::size_t oldIndex, std::size_t newIndex) {
|
||||
if (oldIndex >= animations.size() || newIndex >= animations.size()) return;
|
||||
|
||||
auto animation = animations[oldIndex];
|
||||
animations.erase(animations.begin() + oldIndex);
|
||||
animations.insert(animations.begin() + newIndex, animation);
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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 "GDCore/Extensions/Builtin/SpriteExtension/Animation.h"
|
||||
|
||||
namespace gd {
|
||||
class InitialInstance;
|
||||
class SerializerElement;
|
||||
class PropertyDescriptor;
|
||||
class ArbitraryResourceWorker;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief A list of animations, containing directions with images and collision mask.
|
||||
*
|
||||
* It's used in the configuration of object that implements image-based animations.
|
||||
*
|
||||
* \see Animation
|
||||
* \see Direction
|
||||
* \see Sprite
|
||||
* \ingroup SpriteObjectExtension
|
||||
*/
|
||||
class GD_CORE_API SpriteAnimationList {
|
||||
public:
|
||||
SpriteAnimationList();
|
||||
virtual ~SpriteAnimationList();
|
||||
|
||||
void ExposeResources(gd::ArbitraryResourceWorker& worker);
|
||||
|
||||
/**
|
||||
* \brief Return the animation at the specified index.
|
||||
* If the index is out of bound, a "bad animation" object is returned.
|
||||
*/
|
||||
const Animation& GetAnimation(std::size_t nb) const;
|
||||
|
||||
/**
|
||||
* \brief Return the animation at the specified index.
|
||||
* If the index is out of bound, a "bad animation" object is returned.
|
||||
*/
|
||||
Animation& GetAnimation(std::size_t nb);
|
||||
|
||||
/**
|
||||
* \brief Return the number of animations this object has.
|
||||
*/
|
||||
std::size_t GetAnimationsCount() const { return animations.size(); };
|
||||
|
||||
/**
|
||||
* \brief Return true if an animation exists for a given name.
|
||||
*/
|
||||
bool HasAnimationNamed(const gd::String &name) const;
|
||||
|
||||
/**
|
||||
* \brief Add an animation at the end of the existing ones.
|
||||
*/
|
||||
void AddAnimation(const Animation& animation);
|
||||
|
||||
/**
|
||||
* \brief Remove an animation.
|
||||
*/
|
||||
bool RemoveAnimation(std::size_t nb);
|
||||
|
||||
/**
|
||||
* \brief Remove all animations.
|
||||
*/
|
||||
void RemoveAllAnimations() { animations.clear(); }
|
||||
|
||||
/**
|
||||
* \brief Return true if the object hasn't any animation.
|
||||
*/
|
||||
bool HasNoAnimations() const { return animations.empty(); }
|
||||
|
||||
/**
|
||||
* \brief Swap the position of two animations
|
||||
*/
|
||||
void SwapAnimations(std::size_t firstIndex, std::size_t secondIndex);
|
||||
|
||||
/**
|
||||
* \brief Change the position of the specified animation
|
||||
*/
|
||||
void MoveAnimation(std::size_t oldIndex, std::size_t newIndex);
|
||||
|
||||
/**
|
||||
* \brief Return a read-only reference to the vector containing all the
|
||||
* animation of the object.
|
||||
*/
|
||||
const std::vector<Animation>& GetAllAnimations() const { return animations; }
|
||||
|
||||
/**
|
||||
* @brief Check if the collision mask adapts automatically to the animation.
|
||||
*/
|
||||
bool AdaptCollisionMaskAutomatically() const {
|
||||
return adaptCollisionMaskAutomatically;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set if the collision mask adapts automatically to the animation.
|
||||
*/
|
||||
void SetAdaptCollisionMaskAutomatically(bool enable) {
|
||||
adaptCollisionMaskAutomatically = enable;
|
||||
}
|
||||
|
||||
void UnserializeFrom(const gd::SerializerElement& element);
|
||||
void SerializeTo(gd::SerializerElement& element) const;
|
||||
|
||||
private:
|
||||
|
||||
mutable std::vector<Animation> animations;
|
||||
|
||||
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
|
@@ -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,8 +319,10 @@ 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 played by the object."),
|
||||
@@ -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",
|
||||
|
@@ -23,88 +23,20 @@
|
||||
|
||||
namespace gd {
|
||||
|
||||
Animation SpriteObject::badAnimation;
|
||||
|
||||
SpriteObject::SpriteObject()
|
||||
: updateIfNotVisible(false), adaptCollisionMaskAutomatically(true) {}
|
||||
: updateIfNotVisible(false) {}
|
||||
|
||||
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 =
|
||||
element.GetChild("animations", 0, "Animations");
|
||||
animationsElement.ConsiderAsArrayOf("animation", "Animation");
|
||||
for (std::size_t i = 0; i < animationsElement.GetChildrenCount(); ++i) {
|
||||
const gd::SerializerElement& animationElement =
|
||||
animationsElement.GetChild(i);
|
||||
Animation newAnimation;
|
||||
|
||||
newAnimation.useMultipleDirections = animationElement.GetBoolAttribute(
|
||||
"useMultipleDirections", false, "typeNormal");
|
||||
newAnimation.SetName(animationElement.GetStringAttribute("name", ""));
|
||||
|
||||
// Compatibility with GD <= 3.3
|
||||
if (animationElement.HasChild("Direction")) {
|
||||
for (std::size_t j = 0;
|
||||
j < animationElement.GetChildrenCount("Direction");
|
||||
++j) {
|
||||
Direction direction;
|
||||
direction.UnserializeFrom(animationElement.GetChild("Direction", j));
|
||||
|
||||
newAnimation.SetDirectionsCount(newAnimation.GetDirectionsCount() + 1);
|
||||
newAnimation.SetDirection(direction,
|
||||
newAnimation.GetDirectionsCount() - 1);
|
||||
}
|
||||
}
|
||||
// End of compatibility code
|
||||
else {
|
||||
const gd::SerializerElement& directionsElement =
|
||||
animationElement.GetChild("directions");
|
||||
directionsElement.ConsiderAsArrayOf("direction");
|
||||
for (std::size_t j = 0; j < directionsElement.GetChildrenCount(); ++j) {
|
||||
Direction direction;
|
||||
direction.UnserializeFrom(directionsElement.GetChild(j));
|
||||
|
||||
newAnimation.SetDirectionsCount(newAnimation.GetDirectionsCount() + 1);
|
||||
newAnimation.SetDirection(direction,
|
||||
newAnimation.GetDirectionsCount() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
AddAnimation(newAnimation);
|
||||
}
|
||||
animations.UnserializeFrom(element);
|
||||
}
|
||||
|
||||
void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
element.SetAttribute("updateIfNotVisible", updateIfNotVisible);
|
||||
element.SetAttribute("adaptCollisionMaskAutomatically",
|
||||
adaptCollisionMaskAutomatically);
|
||||
|
||||
// Animations
|
||||
gd::SerializerElement& animationsElement = element.AddChild("animations");
|
||||
animationsElement.ConsiderAsArrayOf("animation");
|
||||
for (std::size_t k = 0; k < GetAnimationsCount(); k++) {
|
||||
gd::SerializerElement& animationElement =
|
||||
animationsElement.AddChild("animation");
|
||||
|
||||
animationElement.SetAttribute("useMultipleDirections",
|
||||
GetAnimation(k).useMultipleDirections);
|
||||
animationElement.SetAttribute("name", GetAnimation(k).GetName());
|
||||
|
||||
gd::SerializerElement& directionsElement =
|
||||
animationElement.AddChild("directions");
|
||||
directionsElement.ConsiderAsArrayOf("direction");
|
||||
for (std::size_t l = 0; l < GetAnimation(k).GetDirectionsCount(); l++) {
|
||||
GetAnimation(k).GetDirection(l).SerializeTo(
|
||||
directionsElement.AddChild("direction"));
|
||||
}
|
||||
}
|
||||
animations.SerializeTo(element);
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties()
|
||||
@@ -127,23 +59,12 @@ bool SpriteObject::UpdateProperty(const gd::String& name,
|
||||
}
|
||||
|
||||
void SpriteObject::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
for (std::size_t j = 0; j < GetAnimationsCount(); j++) {
|
||||
for (std::size_t k = 0; k < GetAnimation(j).GetDirectionsCount(); k++) {
|
||||
for (std::size_t l = 0;
|
||||
l < GetAnimation(j).GetDirection(k).GetSpritesCount();
|
||||
l++) {
|
||||
worker.ExposeImage(
|
||||
GetAnimation(j).GetDirection(k).GetSprite(l).GetImageName());
|
||||
}
|
||||
}
|
||||
}
|
||||
animations.ExposeResources(worker);
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
SpriteObject::GetInitialInstanceProperties(
|
||||
const gd::InitialInstance& initialInstance,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) {
|
||||
const gd::InitialInstance& initialInstance) {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties["animation"] =
|
||||
gd::PropertyDescriptor(
|
||||
@@ -157,9 +78,7 @@ SpriteObject::GetInitialInstanceProperties(
|
||||
bool SpriteObject::UpdateInitialInstanceProperty(
|
||||
gd::InitialInstance& initialInstance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) {
|
||||
const gd::String& value) {
|
||||
if (name == "animation") {
|
||||
initialInstance.SetRawDoubleProperty(
|
||||
"animation", std::max(0, value.empty() ? 0 : value.To<int>()));
|
||||
@@ -168,42 +87,25 @@ bool SpriteObject::UpdateInitialInstanceProperty(
|
||||
return true;
|
||||
}
|
||||
|
||||
const Animation& SpriteObject::GetAnimation(std::size_t nb) const {
|
||||
if (nb >= animations.size()) return badAnimation;
|
||||
|
||||
return animations[nb];
|
||||
size_t SpriteObject::GetAnimationsCount() const {
|
||||
return animations.GetAnimationsCount();
|
||||
}
|
||||
|
||||
Animation& SpriteObject::GetAnimation(std::size_t nb) {
|
||||
if (nb >= animations.size()) return badAnimation;
|
||||
|
||||
return animations[nb];
|
||||
const gd::String &SpriteObject::GetAnimationName(size_t index) const {
|
||||
return animations.GetAnimation(index).GetName();
|
||||
}
|
||||
|
||||
void SpriteObject::AddAnimation(const Animation& animation) {
|
||||
animations.push_back(animation);
|
||||
bool SpriteObject::HasAnimationNamed(
|
||||
const gd::String &name) const {
|
||||
return animations.HasAnimationNamed(name);
|
||||
}
|
||||
|
||||
bool SpriteObject::RemoveAnimation(std::size_t nb) {
|
||||
if (nb >= GetAnimationsCount()) return false;
|
||||
|
||||
animations.erase(animations.begin() + nb);
|
||||
return true;
|
||||
const SpriteAnimationList& SpriteObject::GetAnimations() const {
|
||||
return animations;
|
||||
}
|
||||
|
||||
void SpriteObject::SwapAnimations(std::size_t firstIndex,
|
||||
std::size_t secondIndex) {
|
||||
if (firstIndex < animations.size() && secondIndex < animations.size() &&
|
||||
firstIndex != secondIndex)
|
||||
std::swap(animations[firstIndex], animations[secondIndex]);
|
||||
}
|
||||
|
||||
void SpriteObject::MoveAnimation(std::size_t oldIndex, std::size_t newIndex) {
|
||||
if (oldIndex >= animations.size() || newIndex >= animations.size()) return;
|
||||
|
||||
auto animation = animations[oldIndex];
|
||||
animations.erase(animations.begin() + oldIndex);
|
||||
animations.insert(animations.begin() + newIndex, animation);
|
||||
SpriteAnimationList& SpriteObject::GetAnimations() {
|
||||
return animations;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -4,18 +4,15 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_SPRITEOBJECT_H
|
||||
#define GDCORE_SPRITEOBJECT_H
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Animation.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteAnimationList.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
|
||||
namespace gd {
|
||||
class InitialInstance;
|
||||
class Object;
|
||||
class Layout;
|
||||
class Sprite;
|
||||
class Animation;
|
||||
class SerializerElement;
|
||||
class PropertyDescriptor;
|
||||
} // namespace gd
|
||||
@@ -50,85 +47,26 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) override;
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties(
|
||||
const gd::InitialInstance& position,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
const gd::InitialInstance& position) override;
|
||||
bool UpdateInitialInstanceProperty(gd::InitialInstance& position,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
const gd::String& value) override;
|
||||
|
||||
/** \name Animations
|
||||
* Methods related to animations management
|
||||
*/
|
||||
///@{
|
||||
size_t GetAnimationsCount() const override;
|
||||
|
||||
const gd::String &GetAnimationName(size_t index) const override;
|
||||
|
||||
bool HasAnimationNamed(const gd::String &animationName) const override;
|
||||
|
||||
/**
|
||||
* \brief Return the animation at the specified index.
|
||||
* If the index is out of bound, a "bad animation" object is returned.
|
||||
* \brief Return the animation configuration.
|
||||
*/
|
||||
const Animation& GetAnimation(std::size_t nb) const;
|
||||
const SpriteAnimationList& GetAnimations() const;
|
||||
|
||||
/**
|
||||
* \brief Return the animation at the specified index.
|
||||
* If the index is out of bound, a "bad animation" object is returned.
|
||||
* @brief Return the animation configuration.
|
||||
*/
|
||||
Animation& GetAnimation(std::size_t nb);
|
||||
|
||||
/**
|
||||
* \brief Return the number of animations this object has.
|
||||
*/
|
||||
std::size_t GetAnimationsCount() const { return animations.size(); };
|
||||
|
||||
/**
|
||||
* \brief Add an animation at the end of the existing ones.
|
||||
*/
|
||||
void AddAnimation(const Animation& animation);
|
||||
|
||||
/**
|
||||
* \brief Remove an animation.
|
||||
*/
|
||||
bool RemoveAnimation(std::size_t nb);
|
||||
|
||||
/**
|
||||
* \brief Remove all animations.
|
||||
*/
|
||||
void RemoveAllAnimations() { animations.clear(); }
|
||||
|
||||
/**
|
||||
* \brief Return true if the object hasn't any animation.
|
||||
*/
|
||||
bool HasNoAnimations() const { return animations.empty(); }
|
||||
|
||||
/**
|
||||
* \brief Swap the position of two animations
|
||||
*/
|
||||
void SwapAnimations(std::size_t firstIndex, std::size_t secondIndex);
|
||||
|
||||
/**
|
||||
* \brief Change the position of the specified animation
|
||||
*/
|
||||
void MoveAnimation(std::size_t oldIndex, std::size_t newIndex);
|
||||
|
||||
/**
|
||||
* \brief Return a read-only reference to the vector containing all the
|
||||
* animation of the object.
|
||||
*/
|
||||
const std::vector<Animation>& GetAllAnimations() const { return animations; }
|
||||
|
||||
/**
|
||||
* @brief Check if the collision mask adapts automatically to the animation.
|
||||
*/
|
||||
bool AdaptCollisionMaskAutomatically() const {
|
||||
return adaptCollisionMaskAutomatically;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set if the collision mask adapts automatically to the animation.
|
||||
*/
|
||||
void SetAdaptCollisionMaskAutomatically(bool enable) {
|
||||
adaptCollisionMaskAutomatically = enable;
|
||||
}
|
||||
SpriteAnimationList& GetAnimations();
|
||||
|
||||
/**
|
||||
* \brief Set if the object animation should be played even if the object is
|
||||
@@ -143,25 +81,17 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
* is hidden or far from the camera (false by default).
|
||||
*/
|
||||
bool GetUpdateIfNotVisible() const { return updateIfNotVisible; }
|
||||
///@}
|
||||
|
||||
private:
|
||||
void DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) override;
|
||||
void DoSerializeTo(gd::SerializerElement& element) const override;
|
||||
|
||||
mutable std::vector<Animation> animations;
|
||||
SpriteAnimationList animations;
|
||||
|
||||
bool updateIfNotVisible; ///< If set to true, ask the game engine to play
|
||||
///< object animation even if hidden or far from
|
||||
///< the screen.
|
||||
|
||||
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
|
||||
#endif // GDCORE_SPRITEOBJECT_H
|
||||
|
@@ -25,29 +25,271 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Variables"))
|
||||
.SetIcon("res/conditions/var24.png");
|
||||
|
||||
extension
|
||||
.AddCondition("NumberVariable",
|
||||
_("Variable value"),
|
||||
_("Compare the number value of a variable."),
|
||||
_("The variable _PARAM0_"),
|
||||
"",
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("variable", _("Variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions());
|
||||
|
||||
extension
|
||||
.AddCondition("StringVariable",
|
||||
_("Variable value"),
|
||||
_("Compare the text (string) of a variable."),
|
||||
_("The variable _PARAM0_"),
|
||||
"",
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("variable", _("Variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"string", ParameterOptions::MakeNewOptions());
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"BooleanVariable",
|
||||
_("Variable value"),
|
||||
_("Compare the boolean value of a variable."),
|
||||
_("The variable _PARAM0_ is _PARAM1_"),
|
||||
"",
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("variable", _("Variable"))
|
||||
.AddParameter("trueorfalse", _("Check if the value is"))
|
||||
.SetDefaultValue("true")
|
||||
// This parameter allows to keep the operand expression
|
||||
// when the editor switch between variable instructions.
|
||||
.AddCodeOnlyParameter("trueorfalse", "");
|
||||
|
||||
extension
|
||||
.AddAction("SetNumberVariable",
|
||||
_("Change variable value"),
|
||||
_("Modify the number value of a variable."),
|
||||
_("the variable _PARAM0_"),
|
||||
"",
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Variable"))
|
||||
.UseStandardOperatorParameters("number",
|
||||
ParameterOptions::MakeNewOptions());
|
||||
|
||||
extension
|
||||
.AddAction("SetStringVariable",
|
||||
_("Change text variable"),
|
||||
_("Modify the text (string) of a variable."),
|
||||
_("the variable _PARAM0_"),
|
||||
"",
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Variable"))
|
||||
.UseStandardOperatorParameters("string",
|
||||
ParameterOptions::MakeNewOptions());
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"SetBooleanVariable",
|
||||
_("Change boolean variable"),
|
||||
_("Modify the boolean value of a variable."),
|
||||
_("Change the variable _PARAM0_: _PARAM1_"),
|
||||
"",
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("variable", _("Variable"))
|
||||
.AddParameter("operator", _("Value"), "boolean")
|
||||
// This parameter allows to keep the operand expression
|
||||
// when the editor switch between variable instructions.
|
||||
.AddCodeOnlyParameter("trueorfalse", "");
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"VariableChildCount",
|
||||
_("Number of children"),
|
||||
_("Compare the number of children in an array variable."),
|
||||
_("The number of children in the array variable _PARAM0_"),
|
||||
_("Arrays and structures"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("variable", _("Array variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("VariableChildExists2",
|
||||
_("Child existence"),
|
||||
_("Check if the specified child of the structure "
|
||||
"variable exists."),
|
||||
_("Child _PARAM1_ of variable _PARAM0_ exists"),
|
||||
_("Arrays and structures"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("variable", _("Variable"))
|
||||
.AddParameter("string", _("Name of the child"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"RemoveVariableChild",
|
||||
_("Remove a child"),
|
||||
_("Remove a child from a structure variable."),
|
||||
_("Remove child _PARAM1_ from structure variable _PARAM0_"),
|
||||
_("Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Structure variable"))
|
||||
.AddParameter("string", _("Child's name"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("ClearVariableChildren",
|
||||
_("Clear children"),
|
||||
_("Remove all the children from the structure or array "
|
||||
"variable."),
|
||||
_("Clear children from variable _PARAM0_"),
|
||||
_("Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Structure or array variable"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("PushVariable",
|
||||
_("Add existing variable"),
|
||||
_("Adds an existing variable at the end of an array "
|
||||
"variable."),
|
||||
_("Add variable _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Array variable"))
|
||||
.AddParameter("variable", _("Variable with the content to add"))
|
||||
.SetParameterLongDescription(
|
||||
_("The content of the variable will *be copied* and added at the "
|
||||
"end of the array."))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"PushString",
|
||||
_("Add text variable"),
|
||||
_("Adds a text (string) at the end of a array variable."),
|
||||
_("Add the value _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Array variable"))
|
||||
.AddParameter("string", _("Text to add"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("PushNumber",
|
||||
_("Add variable array value"),
|
||||
_("Adds a number at the end of an array variable."),
|
||||
_("Add the value _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Array variable"))
|
||||
.AddParameter("expression", _("Number to add"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("PushBoolean",
|
||||
_("Add boolean variable"),
|
||||
_("Adds a boolean at the end of an array variable."),
|
||||
_("Add the value _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Array variable"))
|
||||
.AddParameter("trueorfalse", _("Boolean to add"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("RemoveVariableAt",
|
||||
_("Remove variable by index"),
|
||||
_("Removes a variable at the specified index of an array "
|
||||
"variable."),
|
||||
_("Remove variable at index _PARAM1_ from array "
|
||||
"variable _PARAM0_"),
|
||||
_("Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Array variable"))
|
||||
.AddParameter("expression", _("Index to remove"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddStrExpression(
|
||||
"VariableFirstString",
|
||||
_("First text child"),
|
||||
_("Get the value of the first element of an array variable, if "
|
||||
"it is a text (string)."),
|
||||
_("Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Array variable"));
|
||||
|
||||
extension
|
||||
.AddExpression(
|
||||
"VariableFirstNumber",
|
||||
_("First number child"),
|
||||
_("Get the value of the first element of an array variable, if "
|
||||
"it is a number."),
|
||||
_("Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Array variable"));
|
||||
|
||||
extension
|
||||
.AddStrExpression(
|
||||
"VariableLastString",
|
||||
_("Last text child"),
|
||||
_("Get the value of the last element of an array variable, if "
|
||||
"it is a text (string)."),
|
||||
_("Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Array variable"));
|
||||
|
||||
extension
|
||||
.AddExpression(
|
||||
"VariableLastNumber",
|
||||
_("Last number child"),
|
||||
_("Get the value of the last element of an array variable, if "
|
||||
"it is a number."),
|
||||
_("Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("variable", _("Array variable"));
|
||||
|
||||
// Legacy instructions
|
||||
|
||||
extension
|
||||
.AddCondition("VarScene",
|
||||
_("Number variable"),
|
||||
_("Compare the number value of a scene variable."),
|
||||
_("The number of scene variable _PARAM0_"),
|
||||
_("Scene variables"),
|
||||
_("External variables/Scene variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions());
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddCondition("VarSceneTxt",
|
||||
_("Text variable"),
|
||||
_("Compare the text (string) of a scene variable."),
|
||||
_("The text of scene variable _PARAM0_"),
|
||||
_("Scene variables"),
|
||||
_("External variables/Scene variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"string", ParameterOptions::MakeNewOptions());
|
||||
"string", ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
@@ -55,12 +297,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Boolean variable"),
|
||||
_("Compare the boolean value of a scene variable."),
|
||||
_("The boolean value of scene variable _PARAM0_ is _PARAM1_"),
|
||||
_("Scene variables"),
|
||||
_("External variables/Scene variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
.AddParameter("trueorfalse", _("Check if the value is"))
|
||||
.SetDefaultValue("true");
|
||||
.SetDefaultValue("true")
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddCondition("VariableChildExists",
|
||||
@@ -68,11 +311,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Check if the specified child of the scene structure "
|
||||
"variable exists."),
|
||||
_("Child _PARAM1_ of scene variable _PARAM0_ exists"),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
.AddParameter("string", _("Name of the child"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -81,11 +325,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Check if the specified child of the global structure "
|
||||
"variable exists."),
|
||||
_("Child _PARAM1_ of global variable _PARAM0_ exists"),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("globalvar", _("Variable"))
|
||||
.AddParameter("string", _("Name of the child"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -93,7 +338,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
"Variable defined",
|
||||
"Test if the scene variable exists.",
|
||||
"Scene variable _PARAM0_ is defined",
|
||||
_("Scene variables"),
|
||||
_("External variables/Scene variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -105,12 +350,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Number variable"),
|
||||
_("Compare the number value of a global variable."),
|
||||
_("the global variable _PARAM0_"),
|
||||
_("Global variables"),
|
||||
_("External variables/Global variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("globalvar", _("Variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -118,12 +364,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Text variable"),
|
||||
_("Compare the text (string) of a global variable."),
|
||||
_("the text of the global variable _PARAM0_"),
|
||||
_("Global variables"),
|
||||
_("External variables/Global variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("globalvar", _("Variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"string", ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -132,19 +379,20 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Boolean variable"),
|
||||
_("Compare the boolean value of a global variable."),
|
||||
_("The boolean value of global variable _PARAM0_ is _PARAM1_"),
|
||||
_("Global variables"),
|
||||
_("External variables/Global variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("globalvar", _("Variable"))
|
||||
.AddParameter("trueorfalse", _("Check if the value is"))
|
||||
.SetDefaultValue("true");
|
||||
.SetDefaultValue("true")
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddCondition("VarGlobalDef",
|
||||
"Variable defined",
|
||||
"Test if a global variable exists.",
|
||||
"Global variable _PARAM0_ is defined",
|
||||
_("Global variables"),
|
||||
_("External variables/Global variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -157,24 +405,26 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Change number variable"),
|
||||
_("Modify the number value of a scene variable."),
|
||||
_("the scene variable _PARAM0_"),
|
||||
_("Scene variables"),
|
||||
_("External variables/Scene variables"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
.UseStandardOperatorParameters("number",
|
||||
ParameterOptions::MakeNewOptions());
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddAction("ModVarSceneTxt",
|
||||
_("Change text variable"),
|
||||
_("Modify the text (string) of a scene variable."),
|
||||
_("the text of scene variable _PARAM0_"),
|
||||
_("Scene variables"),
|
||||
_("External variables/Scene variables"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
.UseStandardOperatorParameters("string",
|
||||
ParameterOptions::MakeNewOptions());
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
@@ -182,11 +432,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Change boolean variable"),
|
||||
_("Modify the boolean value of a scene variable."),
|
||||
_("Set the boolean value of scene variable _PARAM0_ to _PARAM1_"),
|
||||
_("Scene variables"),
|
||||
_("External variables/Scene variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
.AddParameter("trueorfalse", _("New Value:"));
|
||||
.AddParameter("trueorfalse", _("New Value:"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddAction("ToggleSceneVariableAsBoolean",
|
||||
@@ -195,22 +446,24 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("If it was true, it will become false, and if it was "
|
||||
"false it will become true."),
|
||||
_("Toggle the boolean value of scene variable _PARAM0_"),
|
||||
_("Scene variables"),
|
||||
_("External variables/Scene variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"));
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddAction("ModVarGlobal",
|
||||
_("Change number variable"),
|
||||
_("Modify the number value of a global variable."),
|
||||
_("the global variable _PARAM0_"),
|
||||
_("Global variables"),
|
||||
_("External variables/Global variables"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Variable"))
|
||||
.UseStandardOperatorParameters("number",
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -218,12 +471,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Change text variable"),
|
||||
_("Modify the text (string) of a global variable."),
|
||||
_("the text of global variable _PARAM0_"),
|
||||
_("Global variables"),
|
||||
_("External variables/Global variables"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Variable"))
|
||||
.UseStandardOperatorParameters("string",
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -232,11 +486,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Change boolean variable"),
|
||||
_("Modify the boolean value of a global variable."),
|
||||
_("Set the boolean value of global variable _PARAM0_ to _PARAM1_"),
|
||||
_("Global variables"),
|
||||
_("External variables/Global variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("globalvar", _("Variable"))
|
||||
.AddParameter("trueorfalse", _("New Value:"));
|
||||
.AddParameter("trueorfalse", _("New Value:"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddAction("ToggleGlobalVariableAsBoolean",
|
||||
@@ -245,10 +500,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("If it was true, it will become false, and if it was "
|
||||
"false it will become true."),
|
||||
_("Toggle the boolean value of global variable _PARAM0_"),
|
||||
_("Global variables"),
|
||||
_("External variables/Global variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("globalvar", _("Variable"));
|
||||
.AddParameter("globalvar", _("Variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
@@ -256,12 +512,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Remove a child"),
|
||||
_("Remove a child from a scene structure variable."),
|
||||
_("Remove child _PARAM1_ from scene structure variable _PARAM0_"),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Structure variable"))
|
||||
.AddParameter("string", _("Child's name"))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
@@ -269,12 +526,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Remove a child"),
|
||||
_("Remove a child from a global structure variable."),
|
||||
_("Remove child _PARAM1_ from global structure variable _PARAM0_"),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Structure variable"))
|
||||
.AddParameter("string", _("Child's name"))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddAction("VariableClearChildren",
|
||||
@@ -282,10 +540,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Remove all the children from the scene structure or array "
|
||||
"variable."),
|
||||
_("Clear children from scene variable _PARAM0_"),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Structure or array variable"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -294,10 +553,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Remove all the children from the global structure or array "
|
||||
"variable."),
|
||||
_("Clear children from global variable _PARAM0_"),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Structure or array variable"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -306,7 +566,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Adds an existing variable at the end of a scene array "
|
||||
"variable."),
|
||||
_("Add variable _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
@@ -314,6 +574,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
.SetParameterLongDescription(
|
||||
_("The content of the variable will *be copied* and added at the "
|
||||
"end of the array."))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -322,11 +583,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Add text variable"),
|
||||
_("Adds a text (string) at the end of a scene array variable."),
|
||||
_("Add text _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
.AddParameter("string", _("Text to add"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -334,11 +596,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Add number variable"),
|
||||
_("Adds a number at the end of a scene array variable."),
|
||||
_("Add number _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
.AddParameter("expression", _("Number to add"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -346,11 +609,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Add boolean variable"),
|
||||
_("Adds a boolean at the end of a scene array variable."),
|
||||
_("Add boolean _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
.AddParameter("trueorfalse", _("Boolean to add"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -360,11 +624,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
"variable."),
|
||||
_("Remove variable at index _PARAM1_ from scene array "
|
||||
"variable _PARAM0_"),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
.AddParameter("expression", _("Index to remove"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -373,12 +638,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Number of children"),
|
||||
_("Compare the number of children in a scene array variable."),
|
||||
_("The number of children in the array variable _PARAM0_"),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -387,9 +653,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("First text child"),
|
||||
_("Get the value of the first element of a scene array variable, if "
|
||||
"it is a text (string)."),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"));
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddExpression(
|
||||
@@ -397,9 +664,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("First number child"),
|
||||
_("Get the value of the first element of a scene array variable, if "
|
||||
"it is a number."),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"));
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddStrExpression(
|
||||
@@ -407,9 +675,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Last text child"),
|
||||
_("Get the value of the last element of a scene array variable, if "
|
||||
"it is a text (string)."),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"));
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddExpression(
|
||||
@@ -417,9 +686,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Last number child"),
|
||||
_("Get the value of the last element of a scene array variable, if "
|
||||
"it is a number."),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("External variables/Scene variables/Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"));
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
@@ -427,7 +697,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Add existing variable"),
|
||||
_("Adds an existing variable at the end of a global array variable."),
|
||||
_("Add variable _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Array variable"))
|
||||
@@ -435,6 +705,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
.SetParameterLongDescription(
|
||||
_("The content of the variable will *be copied* and added at the "
|
||||
"end of the array."))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -444,11 +715,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
"array variable."),
|
||||
_("Remove variable at index _PARAM1_ from global array "
|
||||
"variable _PARAM0_"),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Array variable"))
|
||||
.AddParameter("expression", _("Index to remove"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -457,11 +729,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Add text variable"),
|
||||
_("Adds a text (string) at the end of a global array variable."),
|
||||
_("Add text _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Array variable"))
|
||||
.AddParameter("string", _("Text to add"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -469,11 +742,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Add number variable"),
|
||||
_("Adds a number at the end of a global array variable."),
|
||||
_("Add number _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Array variable"))
|
||||
.AddParameter("expression", _("Number to add"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -481,11 +755,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Add boolean variable"),
|
||||
_("Adds a boolean at the end of a global array variable."),
|
||||
_("Add boolean _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Array variable"))
|
||||
.AddParameter("trueorfalse", _("Boolean to add"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -494,12 +769,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Number of children"),
|
||||
_("Compare the number of children in a global array variable."),
|
||||
_("The number of children of the array variable _PARAM0_"),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("globalvar", _("Array variable"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -507,18 +783,20 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("First text child"),
|
||||
_("Value of the first element of a global array "
|
||||
"variable, if it is a text (string) variable."),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Array variable"));
|
||||
.AddParameter("globalvar", _("Array variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddExpression("GlobalVariableFirstNumber",
|
||||
_("First number child"),
|
||||
_("Value of the first element of a global array "
|
||||
"variable, if it is a number variable"),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Array variable"));
|
||||
.AddParameter("globalvar", _("Array variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddStrExpression(
|
||||
@@ -526,9 +804,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Last text child"),
|
||||
_("Value of the last element of a global array variable, if "
|
||||
"it is a text (string) variable."),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Array variable"));
|
||||
.AddParameter("globalvar", _("Array variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddExpression(
|
||||
@@ -536,59 +815,65 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Last number child"),
|
||||
_("Value of the last element of a global array variable, if "
|
||||
"it is a number variable"),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Array variable"));
|
||||
.AddParameter("globalvar", _("Array variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddExpression("GlobalVariableChildCount",
|
||||
_("Number of children"),
|
||||
_("Number of children in a global array or "
|
||||
"structure variable"),
|
||||
_("Global variables/Arrays and structures"),
|
||||
_("External variables/Global variables/Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Array or structure variable"));
|
||||
.AddParameter("globalvar", _("Array or structure variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddExpression("VariableChildCount",
|
||||
_("Number of children"),
|
||||
_("Number of children in a scene array or "
|
||||
"structure variable"),
|
||||
_("Scene variables/Arrays and structures"),
|
||||
_("Arrays and structures"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array or structure variable"));
|
||||
.AddParameter("variable", _("Array or structure variable"), "AllowUndeclaredVariable");
|
||||
|
||||
extension
|
||||
.AddExpression("Variable",
|
||||
_("Number variable"),
|
||||
_("Number value of a scene variable"),
|
||||
_("Scene variables"),
|
||||
_("External variables/Scene variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"));
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddStrExpression("VariableString",
|
||||
_("Text variable"),
|
||||
_("Text of a scene variable"),
|
||||
_("Scene variables"),
|
||||
_("External variables/Scene variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"));
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddExpression("GlobalVariable",
|
||||
_("Number variable"),
|
||||
_("Number value of a global variable"),
|
||||
_("Global variables"),
|
||||
_("External variables/Global variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Name of the global variable"));
|
||||
.AddParameter("globalvar", _("Name of the global variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddStrExpression("GlobalVariableString",
|
||||
_("Text variable"),
|
||||
_("Text of a global variable"),
|
||||
_("Global variables"),
|
||||
_("External variables/Global variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Variable"));
|
||||
.AddParameter("globalvar", _("Variable"))
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -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."),
|
||||
|
@@ -114,6 +114,8 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
virtual AbstractFunctionMetadata &
|
||||
SetIncludeFile(const gd::String &includeFile) = 0;
|
||||
|
@@ -13,12 +13,15 @@
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
const std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::badProperties;
|
||||
|
||||
BehaviorMetadata::BehaviorMetadata(
|
||||
const gd::String& extensionNamespace_,
|
||||
const gd::String& nameWithNamespace,
|
||||
@@ -34,8 +37,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_));
|
||||
@@ -48,33 +50,16 @@ BehaviorMetadata::BehaviorMetadata(
|
||||
"BehaviorMetadata is valid for: " + nameWithNamespace);
|
||||
}
|
||||
|
||||
if (instance) instance->SetTypeName(nameWithNamespace);
|
||||
if (sharedDatasInstance) sharedDatasInstance->SetTypeName(nameWithNamespace);
|
||||
if (instance) {
|
||||
instance->SetTypeName(nameWithNamespace);
|
||||
instance->InitializeContent();
|
||||
}
|
||||
if (sharedDatasInstance) {
|
||||
sharedDatasInstance->SetTypeName(nameWithNamespace);
|
||||
sharedDatasInstance->InitializeContent();
|
||||
}
|
||||
}
|
||||
|
||||
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 +405,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 "
|
||||
@@ -433,12 +414,41 @@ gd::Behavior& BehaviorMetadata::Get() const {
|
||||
return *instance;
|
||||
}
|
||||
|
||||
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
|
||||
if (isEventBased) {
|
||||
gd::LogFatalError("Error: Event-based behaviors don't have blueprint. "
|
||||
"This method should not never be called.");
|
||||
std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::GetProperties() const {
|
||||
if (!instance) {
|
||||
return badProperties;
|
||||
}
|
||||
// TODO Properties should be declared on BehaviorMetadata directly.
|
||||
// - Add 2 `properties` members (one for shared properties)
|
||||
// - Add methods to declare new properties
|
||||
return instance->GetProperties();
|
||||
}
|
||||
|
||||
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
|
||||
return sharedDatasInstance.get();
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::GetSharedProperties() const {
|
||||
if (!sharedDatasInstance) {
|
||||
return badProperties;
|
||||
}
|
||||
// TODO Properties should be declared on BehaviorMetadata directly.
|
||||
// - Add 2 `properties` members (one for shared properties)
|
||||
// - Add methods to declare new properties
|
||||
return sharedDatasInstance->GetProperties();
|
||||
}
|
||||
|
||||
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
|
||||
|
@@ -18,6 +18,7 @@ class BehaviorsSharedData;
|
||||
class MultipleInstructionMetadata;
|
||||
class InstructionMetadata;
|
||||
class ExpressionMetadata;
|
||||
class PropertyDescriptor;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -204,6 +205,8 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
* \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.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
BehaviorMetadata& SetIncludeFile(const gd::String& includeFile) override;
|
||||
|
||||
@@ -259,6 +262,11 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
*/
|
||||
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.
|
||||
@@ -274,6 +282,21 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
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.
|
||||
*
|
||||
@@ -282,6 +305,15 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
*/
|
||||
gd::Behavior& Get() const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of the
|
||||
* behavior.
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const;
|
||||
|
||||
/**
|
||||
* \brief Return the associated gd::BehaviorsSharedData, handling behavior
|
||||
* shared data, if any (nullptr if none).
|
||||
@@ -291,6 +323,15 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
*/
|
||||
gd::BehaviorsSharedData* GetSharedDataInstance() const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom shared properties
|
||||
* of the behavior.
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetSharedProperties() const;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a map containing the names of the actions
|
||||
* (as keys) and the metadata associated with (as values).
|
||||
@@ -330,12 +371,15 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
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;
|
||||
|
||||
static const std::map<gd::String, gd::PropertyDescriptor> badProperties;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -65,6 +65,8 @@ class GD_CORE_API EffectMetadata {
|
||||
|
||||
/**
|
||||
* \brief Clear any existing include file and add the specified include file.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
EffectMetadata& SetIncludeFile(const gd::String& includeFile);
|
||||
|
||||
|
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
#include "ExpressionMetadata.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
@@ -46,16 +47,14 @@ gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
|
||||
// For objects/behavior, the supplementary information
|
||||
// parameter is an object/behavior type...
|
||||
((gd::ParameterMetadata::IsObject(type) ||
|
||||
gd::ParameterMetadata::IsBehavior(type))
|
||||
// Prefix with the namespace if it's not already there.
|
||||
&& !(supplementaryInformation.rfind(extensionNamespace, 0) == 0))
|
||||
? (supplementaryInformation.empty()
|
||||
? ""
|
||||
: extensionNamespace +
|
||||
supplementaryInformation //... so prefix it with the extension
|
||||
// namespace.
|
||||
)
|
||||
: supplementaryInformation); // Otherwise don't change anything
|
||||
gd::ParameterMetadata::IsBehavior(type))
|
||||
// Prefix with the namespace if it's not already there.
|
||||
&& (supplementaryInformation.find(
|
||||
PlatformExtension::GetNamespaceSeparator()) == gd::String::npos)
|
||||
? (supplementaryInformation.empty()
|
||||
? ""
|
||||
: extensionNamespace + supplementaryInformation)
|
||||
: supplementaryInformation));
|
||||
|
||||
// TODO: Assert against supplementaryInformation === "emsc" (when running with
|
||||
// Emscripten), and warn about a missing argument when calling addParameter.
|
||||
|
@@ -288,6 +288,8 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
ExpressionMetadata& SetIncludeFile(
|
||||
const gd::String& includeFile) override {
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
@@ -64,17 +65,14 @@ InstructionMetadata& InstructionMetadata::AddParameter(
|
||||
// For objects/behavior, the supplementary information
|
||||
// parameter is an object/behavior type...
|
||||
((gd::ParameterMetadata::IsObject(type) ||
|
||||
gd::ParameterMetadata::IsBehavior(type))
|
||||
// Prefix with the namespace if it's not already there.
|
||||
&& !(supplementaryInformation.rfind(extensionNamespace, 0) == 0))
|
||||
? (supplementaryInformation.empty()
|
||||
? ""
|
||||
: extensionNamespace +
|
||||
supplementaryInformation //... so prefix it with the
|
||||
// extension
|
||||
// namespace.
|
||||
)
|
||||
: supplementaryInformation); // Otherwise don't change anything
|
||||
gd::ParameterMetadata::IsBehavior(type))
|
||||
// Prefix with the namespace if it's not already there.
|
||||
&& (supplementaryInformation.find(
|
||||
PlatformExtension::GetNamespaceSeparator()) == gd::String::npos)
|
||||
? (supplementaryInformation.empty()
|
||||
? ""
|
||||
: extensionNamespace + supplementaryInformation)
|
||||
: supplementaryInformation));
|
||||
|
||||
// TODO: Assert against supplementaryInformation === "emsc" (when running with
|
||||
// Emscripten), and warn about a missing argument when calling addParameter.
|
||||
@@ -190,7 +188,7 @@ InstructionMetadata::UseStandardRelationalOperatorParameters(
|
||||
gd::String templateSentence = _("<subject> of _PARAM0_ <operator> <value>");
|
||||
|
||||
sentence =
|
||||
templateSentence.FindAndReplace("<subject>", sentence)
|
||||
templateSentence.FindAndReplace("<subject>", sentence.CapitalizeFirstLetter())
|
||||
.FindAndReplace(
|
||||
"<operator>",
|
||||
"_PARAM" + gd::String::From(operatorParamIndex) + "_")
|
||||
@@ -200,7 +198,7 @@ InstructionMetadata::UseStandardRelationalOperatorParameters(
|
||||
gd::String templateSentence = _("<subject> <operator> <value>");
|
||||
|
||||
sentence =
|
||||
templateSentence.FindAndReplace("<subject>", sentence)
|
||||
templateSentence.FindAndReplace("<subject>", sentence.CapitalizeFirstLetter())
|
||||
.FindAndReplace(
|
||||
"<operator>",
|
||||
"_PARAM" + gd::String::From(operatorParamIndex) + "_")
|
||||
|
@@ -456,6 +456,15 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the type manipulated in a standard way by the instruction.
|
||||
*
|
||||
* \param type "number" or "string"
|
||||
*/
|
||||
const gd::String &GetManipulatedType() const {
|
||||
return codeExtraInformation.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* If InstructionMetadata::ExtraInformation::SetManipulatedType was called
|
||||
* with "number" or "string", this function will tell the code generator the
|
||||
@@ -494,6 +503,8 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
InstructionMetadata &SetIncludeFile(const gd::String &includeFile) override {
|
||||
codeExtraInformation.includeFiles.clear();
|
||||
|
@@ -142,6 +142,8 @@ public:
|
||||
* \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.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
virtual InstructionOrExpressionContainerMetadata &
|
||||
SetIncludeFile(const gd::String &includeFile) = 0;
|
||||
|
@@ -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"
|
||||
|
||||
@@ -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:
|
||||
|
@@ -150,6 +150,10 @@ class GD_CORE_API MultipleInstructionMetadata : public AbstractFunctionMetadata
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
MultipleInstructionMetadata &SetIncludeFile(const gd::String &includeFile) override {
|
||||
if (expression)
|
||||
expression->SetIncludeFile(includeFile);
|
||||
@@ -191,6 +195,16 @@ class GD_CORE_API MultipleInstructionMetadata : public AbstractFunctionMetadata
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \see gd::InstructionMetadata::SetHelpPath
|
||||
*/
|
||||
MultipleInstructionMetadata &SetHelpPath(const gd::String &path) {
|
||||
if (expression) expression->SetHelpPath(path);
|
||||
if (condition) condition->SetHelpPath(path);
|
||||
if (action) action->SetHelpPath(path);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \see gd::InstructionMetadata::MarkAsSimple
|
||||
*/
|
||||
|
@@ -224,32 +224,28 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief The "capabilities" that are offered by the base object that are
|
||||
* *not* supported by this object, and should be hidden in the editor
|
||||
* interface.
|
||||
* \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 interface.
|
||||
* \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 interface.
|
||||
*/
|
||||
bool IsUnsupportedBaseObjectCapability(const gd::String& capability) const {
|
||||
return unsupportedBaseObjectCapabilities.find(capability) != unsupportedBaseObjectCapabilities.end();
|
||||
}
|
||||
|
||||
const gd::String& GetName() const override { return name; }
|
||||
const gd::String& GetFullName() const override { return fullname; }
|
||||
const gd::String& GetCategoryFullName() const { return categoryFullName; }
|
||||
@@ -268,6 +264,8 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
|
||||
* \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 object.
|
||||
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
|
||||
* error prone.
|
||||
*/
|
||||
ObjectMetadata& SetIncludeFile(const gd::String& includeFile) override;
|
||||
|
||||
@@ -307,12 +305,24 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
|
||||
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;
|
||||
@@ -331,8 +341,9 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
|
||||
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
|
||||
|
@@ -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.
|
||||
*/
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#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"
|
||||
@@ -15,6 +16,8 @@
|
||||
#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,
|
||||
@@ -57,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,
|
||||
@@ -105,8 +157,7 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
|
||||
void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &globalObjectsContainer,
|
||||
const gd::ObjectsContainer &objectsContainer, FunctionCallNode &node,
|
||||
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)>
|
||||
@@ -117,8 +168,7 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
const gd::ExpressionMetadata &metadata =
|
||||
isObjectFunction ? MetadataProvider::GetObjectAnyExpressionMetadata(
|
||||
platform,
|
||||
GetTypeOfObject(globalObjectsContainer,
|
||||
objectsContainer, node.objectName),
|
||||
objectsContainersList.GetTypeOfObject(node.objectName),
|
||||
node.functionName)
|
||||
: MetadataProvider::GetAnyExpressionMetadata(
|
||||
platform, node.functionName);
|
||||
|
@@ -3,9 +3,8 @@
|
||||
* 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"
|
||||
@@ -13,6 +12,7 @@ namespace gd {
|
||||
class Platform;
|
||||
class Project;
|
||||
class ObjectsContainer;
|
||||
class ObjectsContainersList;
|
||||
class ParameterMetadata;
|
||||
class Expression;
|
||||
struct FunctionCallNode;
|
||||
@@ -27,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
|
||||
@@ -59,8 +72,7 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
*/
|
||||
static void IterateOverParametersWithIndex(
|
||||
const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &globalObjectsContainer,
|
||||
const gd::ObjectsContainer &objectsContainer, FunctionCallNode &node,
|
||||
const gd::ObjectsContainersList &objectsContainersList, FunctionCallNode &node,
|
||||
std::function<void(const gd::ParameterMetadata ¶meterMetadata,
|
||||
std::unique_ptr<gd::ExpressionNode> ¶meterNode,
|
||||
size_t parameterIndex,
|
||||
@@ -74,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
|
||||
|
@@ -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).
|
||||
@@ -175,8 +200,13 @@ 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" ||
|
||||
@@ -187,7 +217,9 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
parameterType == "jsonResource" ||
|
||||
parameterType == "tilemapResource" ||
|
||||
parameterType == "tilesetResource" ||
|
||||
parameterType == "model3DResource";
|
||||
parameterType == "model3DResource" ||
|
||||
parameterType == "atlasResource" ||
|
||||
parameterType == "spineResource";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -196,7 +228,7 @@ 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);
|
||||
@@ -205,7 +237,7 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
* \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);
|
||||
|
@@ -96,11 +96,11 @@ std::shared_ptr<gd::PlatformExtension> Platform::GetExtension(
|
||||
std::unique_ptr<gd::ObjectConfiguration> Platform::CreateObjectConfiguration(
|
||||
gd::String type) const {
|
||||
if (creationFunctionTable.find(type) == creationFunctionTable.end()) {
|
||||
gd::LogWarning("Tried to create an object with an unknown type: " + type
|
||||
gd::LogWarning("Tried to create an object configuration with an unknown type: " + type
|
||||
+ " for platform " + GetName() + "!");
|
||||
type = "";
|
||||
if (creationFunctionTable.find("") == creationFunctionTable.end()) {
|
||||
gd::LogError("Unable to create a Base object!");
|
||||
gd::LogFatalError("Unable to create a base object configuration!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -264,8 +264,11 @@ class GD_CORE_API PlatformExtension {
|
||||
*
|
||||
* \param name The name of the behavior
|
||||
* \param fullname The user friendly name of the behavior
|
||||
* \param defaultName The default name of behavior instances
|
||||
* \param description The user friendly description of the behavior
|
||||
* \param group The behavior category label
|
||||
* \param icon The icon of the behavior.
|
||||
* \param className The name of the class implementing the behavior
|
||||
* \param instance An instance of the behavior that
|
||||
* will be used to create the behavior
|
||||
* \param sharedDatasInstance Optional
|
||||
@@ -282,21 +285,6 @@ class GD_CORE_API PlatformExtension {
|
||||
std::shared_ptr<gd::Behavior> instance,
|
||||
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance);
|
||||
|
||||
/**
|
||||
* \brief Declare a new events based behavior as being part of the extension.
|
||||
*
|
||||
* \param name The name of the behavior
|
||||
* \param fullname The user friendly name of the behavior
|
||||
* \param description The user friendly description of the behavior
|
||||
* \param icon The icon of the behavior.
|
||||
*/
|
||||
gd::BehaviorMetadata& AddEventsBasedBehavior(
|
||||
const gd::String& name_,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_);
|
||||
|
||||
/**
|
||||
* \brief Declare a new effect as being part of the extension.
|
||||
* \param name The internal name of the effect (also called effect type).
|
||||
|
@@ -4,7 +4,6 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "DependenciesAnalyzer.h"
|
||||
#include <algorithm>
|
||||
#include "GDCore/Events/Builtin/LinkEvent.h"
|
||||
@@ -29,9 +28,9 @@ DependenciesAnalyzer::DependenciesAnalyzer(const gd::Project& project_,
|
||||
|
||||
bool DependenciesAnalyzer::Analyze() {
|
||||
if (layout)
|
||||
return Analyze(layout->GetEvents(), true);
|
||||
return Analyze(layout->GetEvents());
|
||||
else if (externalEvents)
|
||||
return Analyze(externalEvents->GetEvents(), true);
|
||||
return Analyze(externalEvents->GetEvents());
|
||||
|
||||
std::cout << "ERROR: DependenciesAnalyzer called without any layout or "
|
||||
"external events.";
|
||||
@@ -40,63 +39,38 @@ bool DependenciesAnalyzer::Analyze() {
|
||||
|
||||
DependenciesAnalyzer::~DependenciesAnalyzer() {}
|
||||
|
||||
bool DependenciesAnalyzer::Analyze(const gd::EventsList& events, bool isOnTopLevel) {
|
||||
bool DependenciesAnalyzer::Analyze(const gd::EventsList& events) {
|
||||
for (unsigned int i = 0; i < events.size(); ++i) {
|
||||
const gd::LinkEvent* linkEvent = dynamic_cast<const gd::LinkEvent*>(&events[i]);
|
||||
if (linkEvent) {
|
||||
DependenciesAnalyzer analyzer(*this);
|
||||
|
||||
gd::String linked = linkEvent->GetTarget();
|
||||
if (project.HasExternalEventsNamed(linked)) {
|
||||
if (std::find(parentExternalEvents.begin(),
|
||||
parentExternalEvents.end(),
|
||||
linked) != parentExternalEvents.end())
|
||||
return false; // Circular dependency!
|
||||
|
||||
externalEventsDependencies.insert(
|
||||
linked); // There is a direct dependency
|
||||
if (!isOnTopLevel) notTopLevelExternalEventsDependencies.insert(linked);
|
||||
analyzer.AddParentExternalEvents(linked);
|
||||
if (!analyzer.Analyze(project.GetExternalEvents(linked).GetEvents(),
|
||||
isOnTopLevel))
|
||||
linked) != parentExternalEvents.end()) {
|
||||
// Circular dependency!
|
||||
return false;
|
||||
|
||||
}
|
||||
bool wasDependencyJustAdded = externalEventsDependencies.insert(linked).second;
|
||||
if (wasDependencyJustAdded) {
|
||||
parentExternalEvents.push_back(linked);
|
||||
if (!Analyze(project.GetExternalEvents(linked).GetEvents()))
|
||||
return false;
|
||||
parentExternalEvents.pop_back();
|
||||
}
|
||||
} else if (project.HasLayoutNamed(linked)) {
|
||||
if (std::find(parentScenes.begin(), parentScenes.end(), linked) !=
|
||||
parentScenes.end())
|
||||
return false; // Circular dependency!
|
||||
|
||||
scenesDependencies.insert(linked); // There is a direct dependency
|
||||
if (!isOnTopLevel) notTopLevelScenesDependencies.insert(linked);
|
||||
analyzer.AddParentScene(linked);
|
||||
if (!analyzer.Analyze(project.GetLayout(linked).GetEvents(),
|
||||
isOnTopLevel))
|
||||
parentScenes.end()) {
|
||||
// Circular dependency!
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update with indirect dependencies.
|
||||
scenesDependencies.insert(analyzer.GetScenesDependencies().begin(),
|
||||
analyzer.GetScenesDependencies().end());
|
||||
externalEventsDependencies.insert(
|
||||
analyzer.GetExternalEventsDependencies().begin(),
|
||||
analyzer.GetExternalEventsDependencies().end());
|
||||
sourceFilesDependencies.insert(
|
||||
analyzer.GetSourceFilesDependencies().begin(),
|
||||
analyzer.GetSourceFilesDependencies().end());
|
||||
notTopLevelScenesDependencies.insert(
|
||||
analyzer.GetNotTopLevelScenesDependencies().begin(),
|
||||
analyzer.GetNotTopLevelScenesDependencies().end());
|
||||
notTopLevelExternalEventsDependencies.insert(
|
||||
analyzer.GetNotTopLevelExternalEventsDependencies().begin(),
|
||||
analyzer.GetNotTopLevelExternalEventsDependencies().end());
|
||||
|
||||
if (!isOnTopLevel) {
|
||||
notTopLevelScenesDependencies.insert(
|
||||
analyzer.GetScenesDependencies().begin(),
|
||||
analyzer.GetScenesDependencies().end());
|
||||
notTopLevelExternalEventsDependencies.insert(
|
||||
analyzer.GetExternalEventsDependencies().begin(),
|
||||
analyzer.GetExternalEventsDependencies().end());
|
||||
}
|
||||
bool wasDependencyJustAdded = scenesDependencies.insert(linked).second;
|
||||
if (wasDependencyJustAdded) {
|
||||
parentScenes.push_back(linked);
|
||||
if (!Analyze(project.GetLayout(linked).GetEvents()))
|
||||
return false;
|
||||
parentScenes.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,45 +86,9 @@ bool DependenciesAnalyzer::Analyze(const gd::EventsList& events, bool isOnTopLev
|
||||
|
||||
// Analyze sub events dependencies
|
||||
if (events[i].CanHaveSubEvents()) {
|
||||
if (!Analyze(events[i].GetSubEvents(), false)) return false;
|
||||
if (!Analyze(events[i].GetSubEvents())) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gd::String DependenciesAnalyzer::ExternalEventsCanBeCompiledForAScene() {
|
||||
if (!externalEvents) {
|
||||
std::cout << "ERROR: ExternalEventsCanBeCompiledForAScene called without "
|
||||
"external events set!"
|
||||
<< std::endl;
|
||||
return "";
|
||||
}
|
||||
|
||||
gd::String sceneName;
|
||||
for (unsigned int i = 0; i < project.GetLayoutsCount(); ++i) {
|
||||
// For each layout, compute the dependencies and the dependencies which are
|
||||
// not coming from a top level event.
|
||||
DependenciesAnalyzer analyzer(project, project.GetLayout(i));
|
||||
if (!analyzer.Analyze()) continue; // Analyze failed -> Cyclic dependencies
|
||||
const std::set<gd::String>& dependencies =
|
||||
analyzer.GetExternalEventsDependencies();
|
||||
const std::set<gd::String>& notTopLevelDependencies =
|
||||
analyzer.GetNotTopLevelExternalEventsDependencies();
|
||||
|
||||
// Check if the external events is a dependency, and that is is only present
|
||||
// as a link on the top level.
|
||||
if (dependencies.find(externalEvents->GetName()) != dependencies.end() &&
|
||||
notTopLevelDependencies.find(externalEvents->GetName()) ==
|
||||
notTopLevelDependencies.end()) {
|
||||
if (!sceneName.empty())
|
||||
return ""; // External events can be compiled only if one scene is
|
||||
// including them.
|
||||
else
|
||||
sceneName = project.GetLayout(i).GetName();
|
||||
}
|
||||
}
|
||||
|
||||
return sceneName; // External events can be compiled and used for the scene.
|
||||
}
|
||||
#endif
|
||||
|
@@ -39,11 +39,6 @@ class GD_CORE_API DependenciesAnalyzer {
|
||||
|
||||
/**
|
||||
* \brief Constructor for analyzing the dependencies of external events.
|
||||
*
|
||||
* You can also call then
|
||||
* DependenciesAnalyzer::ExternalEventsCanBeCompiledForAScene to check if the
|
||||
* external events can be compiled separately and called by a scene. \see
|
||||
* DependenciesAnalyzer::ExternalEventsCanBeCompiledForAScene
|
||||
*/
|
||||
DependenciesAnalyzer(const gd::Project& project_,
|
||||
const gd::ExternalEvents& externalEvents);
|
||||
@@ -60,18 +55,6 @@ class GD_CORE_API DependenciesAnalyzer {
|
||||
*/
|
||||
bool Analyze();
|
||||
|
||||
/**
|
||||
* Check if the external events (passed in the constructor) can be compiled
|
||||
* and called by a single scene:<br> This is possible when the link calling
|
||||
* the external events does not have any parent event and when this situation
|
||||
* occurs only in a single scene and not in another.
|
||||
*
|
||||
* \return The name of the scene which is able to call the compiled external
|
||||
* events. If empty, no scene is able to call them. (So external events have
|
||||
* to be included directly by links).
|
||||
*/
|
||||
gd::String ExternalEventsCanBeCompiledForAScene();
|
||||
|
||||
/**
|
||||
* \brief Return the scenes being dependencies of the scene or external events
|
||||
* passed in the constructor.
|
||||
@@ -96,25 +79,6 @@ class GD_CORE_API DependenciesAnalyzer {
|
||||
return sourceFilesDependencies;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return the scenes being dependencies of the scene or external events
|
||||
* passed in the constructor, but being not top level dependencies: The links
|
||||
* including them are not a top level events (i.e: They have a parent event).
|
||||
*/
|
||||
const std::set<gd::String>& GetNotTopLevelScenesDependencies() const {
|
||||
return notTopLevelScenesDependencies;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return the external events being dependencies of the scene or
|
||||
* external events passed in the constructor, but being not top level
|
||||
* dependencies: The links including them are not a top level events (i.e:
|
||||
* They have a parent event).
|
||||
*/
|
||||
const std::set<gd::String>& GetNotTopLevelExternalEventsDependencies() const {
|
||||
return notTopLevelExternalEventsDependencies;
|
||||
};
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Analyze the dependencies of the events.
|
||||
@@ -124,32 +88,11 @@ class GD_CORE_API DependenciesAnalyzer {
|
||||
* (they have no parents). \return false if a circular dependency exists, true
|
||||
* otherwise.
|
||||
*/
|
||||
bool Analyze(const gd::EventsList& events, bool isOnTopLevel);
|
||||
|
||||
void AddParentScene(gd::String parentScene) {
|
||||
parentScenes.push_back(parentScene);
|
||||
};
|
||||
void AddParentExternalEvents(gd::String parentExternalEvents_) {
|
||||
parentExternalEvents.push_back(parentExternalEvents_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return true if all links pointing to external events called \a
|
||||
* externalEventsName are only at the top level of \a events. The function
|
||||
* return false as soon as it discover a link to external events which is not
|
||||
* at the top level ( i.e: It has a parent event ).
|
||||
*
|
||||
* \warning The function assumes that there are not cyclic dependencies.
|
||||
*/
|
||||
bool CheckIfExternalEventsIsLinkedOnlyAtTopLevel(
|
||||
const gd::String& externalEventsName,
|
||||
std::vector<std::shared_ptr<gd::BaseEvent> >& events);
|
||||
bool Analyze(const gd::EventsList& events);
|
||||
|
||||
std::set<gd::String> scenesDependencies;
|
||||
std::set<gd::String> externalEventsDependencies;
|
||||
std::set<gd::String> sourceFilesDependencies;
|
||||
std::set<gd::String> notTopLevelScenesDependencies;
|
||||
std::set<gd::String> notTopLevelExternalEventsDependencies;
|
||||
std::vector<gd::String>
|
||||
parentScenes; ///< Used to check for circular dependencies.
|
||||
std::vector<gd::String>
|
||||
|
@@ -26,7 +26,7 @@ void EventBasedBehaviorBrowser::ExposeEvents(
|
||||
void EventBasedBehaviorBrowser::ExposeEvents(
|
||||
gd::Project &project, gd::ArbitraryEventsWorkerWithContext &worker) const {
|
||||
gd::ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
|
||||
project, eventsBasedBehavior, worker);
|
||||
project, eventsFunctionsExtension, eventsBasedBehavior, worker);
|
||||
}
|
||||
|
||||
void EventBasedBehaviorBrowser::ExposeObjects(
|
||||
|
@@ -29,8 +29,11 @@ namespace gd {
|
||||
*/
|
||||
class GD_CORE_API EventBasedBehaviorBrowser : public ProjectBrowser {
|
||||
public:
|
||||
EventBasedBehaviorBrowser(gd::EventsBasedBehavior &eventsBasedBehavior_)
|
||||
: eventsBasedBehavior(eventsBasedBehavior_) {}
|
||||
EventBasedBehaviorBrowser(
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension_,
|
||||
gd::EventsBasedBehavior &eventsBasedBehavior_)
|
||||
: eventsFunctionsExtension(eventsFunctionsExtension_),
|
||||
eventsBasedBehavior(eventsBasedBehavior_) {}
|
||||
|
||||
/**
|
||||
* \brief Call the specified worker on all events of the event-based
|
||||
@@ -48,7 +51,7 @@ public:
|
||||
* This should be the preferred way to traverse all the events of an event-based behavior.
|
||||
*/
|
||||
void
|
||||
ExposeEvents(gd::Project &project,
|
||||
ExposeEvents(gd::Project &project,
|
||||
gd::ArbitraryEventsWorkerWithContext &worker) const override;
|
||||
|
||||
/**
|
||||
@@ -80,6 +83,7 @@ public:
|
||||
gd::ArbitraryBehaviorSharedDataWorker &worker) const override;
|
||||
|
||||
private:
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension;
|
||||
gd::EventsBasedBehavior &eventsBasedBehavior;
|
||||
};
|
||||
|
||||
|
@@ -11,30 +11,30 @@
|
||||
#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"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
ArbitraryEventsWorker::~ArbitraryEventsWorker() {}
|
||||
AbstractArbitraryEventsWorker::~AbstractArbitraryEventsWorker() {}
|
||||
|
||||
void ArbitraryEventsWorker::VisitEventList(gd::EventsList& events) {
|
||||
void AbstractArbitraryEventsWorker::VisitEventList(gd::EventsList& events) {
|
||||
DoVisitEventList(events);
|
||||
|
||||
for (std::size_t i = 0; i < events.size();) {
|
||||
if (events[i].AcceptVisitor(*this))
|
||||
events.RemoveEvent(i);
|
||||
else {
|
||||
if (events[i].CanHaveSubEvents())
|
||||
VisitEventList(events[i].GetSubEvents());
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ArbitraryEventsWorker::VisitEvent(gd::BaseEvent& event) {
|
||||
bool AbstractArbitraryEventsWorker::VisitEvent(gd::BaseEvent& event) {
|
||||
bool shouldDelete = DoVisitEvent(event);
|
||||
if (shouldDelete) return true;
|
||||
|
||||
@@ -47,14 +47,23 @@ 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);
|
||||
}
|
||||
|
||||
if (!shouldDelete && event.CanHaveSubEvents()) {
|
||||
VisitEventList(event.GetSubEvents());
|
||||
}
|
||||
return shouldDelete;
|
||||
}
|
||||
|
||||
bool ArbitraryEventsWorker::VisitLinkEvent(gd::LinkEvent& linkEvent) {
|
||||
bool AbstractArbitraryEventsWorker::VisitLinkEvent(gd::LinkEvent& linkEvent) {
|
||||
return DoVisitLinkEvent(linkEvent);
|
||||
}
|
||||
|
||||
void ArbitraryEventsWorker::VisitInstructionList(
|
||||
void AbstractArbitraryEventsWorker::VisitInstructionList(
|
||||
gd::InstructionsList& instructions, bool areConditions) {
|
||||
DoVisitInstructionList(instructions, areConditions);
|
||||
|
||||
@@ -70,17 +79,19 @@ void ArbitraryEventsWorker::VisitInstructionList(
|
||||
}
|
||||
}
|
||||
|
||||
bool ArbitraryEventsWorker::VisitInstruction(gd::Instruction& instruction,
|
||||
bool AbstractArbitraryEventsWorker::VisitInstruction(gd::Instruction& instruction,
|
||||
bool isCondition) {
|
||||
return DoVisitInstruction(instruction, isCondition);
|
||||
}
|
||||
|
||||
ArbitraryEventsWorkerWithContext::~ArbitraryEventsWorkerWithContext() {}
|
||||
bool AbstractArbitraryEventsWorker::VisitEventExpression(gd::Expression& expression,
|
||||
const gd::ParameterMetadata& metadata) {
|
||||
return DoVisitEventExpression(expression, metadata);
|
||||
}
|
||||
|
||||
AbstractReadOnlyArbitraryEventsWorker::~AbstractReadOnlyArbitraryEventsWorker() {}
|
||||
|
||||
ReadOnlyArbitraryEventsWorker::~ReadOnlyArbitraryEventsWorker() {}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::VisitEventList(const gd::EventsList& events) {
|
||||
void AbstractReadOnlyArbitraryEventsWorker::VisitEventList(const gd::EventsList& events) {
|
||||
DoVisitEventList(events);
|
||||
|
||||
for (std::size_t i = 0; i < events.size(); ++i) {
|
||||
@@ -95,7 +106,7 @@ void ReadOnlyArbitraryEventsWorker::VisitEventList(const gd::EventsList& events)
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::VisitEvent(const gd::BaseEvent& event) {
|
||||
void AbstractReadOnlyArbitraryEventsWorker::VisitEvent(const gd::BaseEvent& event) {
|
||||
DoVisitEvent(event);
|
||||
|
||||
const vector<const gd::InstructionsList*> conditionsVectors =
|
||||
@@ -116,11 +127,11 @@ void ReadOnlyArbitraryEventsWorker::VisitEvent(const gd::BaseEvent& event) {
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::VisitLinkEvent(const gd::LinkEvent& linkEvent) {
|
||||
void AbstractReadOnlyArbitraryEventsWorker::VisitLinkEvent(const gd::LinkEvent& linkEvent) {
|
||||
DoVisitLinkEvent(linkEvent);
|
||||
}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::VisitInstructionList(
|
||||
void AbstractReadOnlyArbitraryEventsWorker::VisitInstructionList(
|
||||
const gd::InstructionsList& instructions, bool areConditions) {
|
||||
DoVisitInstructionList(instructions, areConditions);
|
||||
|
||||
@@ -136,15 +147,73 @@ void ReadOnlyArbitraryEventsWorker::VisitInstructionList(
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::VisitInstruction(const gd::Instruction& instruction,
|
||||
void AbstractReadOnlyArbitraryEventsWorker::VisitInstruction(const gd::Instruction& instruction,
|
||||
bool isCondition) {
|
||||
DoVisitInstruction(instruction, isCondition);
|
||||
}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::StopAnyEventIteration() {
|
||||
|
||||
void AbstractReadOnlyArbitraryEventsWorker::VisitEventExpression(const gd::Expression& expression,
|
||||
const gd::ParameterMetadata& metadata) {
|
||||
DoVisitEventExpression(expression, metadata);
|
||||
}
|
||||
|
||||
void AbstractReadOnlyArbitraryEventsWorker::StopAnyEventIteration() {
|
||||
shouldStopIteration = true;
|
||||
}
|
||||
|
||||
ArbitraryEventsWorker::~ArbitraryEventsWorker() {}
|
||||
|
||||
bool ArbitraryEventsWorker::VisitEvent(gd::BaseEvent &event) {
|
||||
return AbstractArbitraryEventsWorker::VisitEvent(event);
|
||||
}
|
||||
|
||||
ArbitraryEventsWorkerWithContext::~ArbitraryEventsWorkerWithContext() {}
|
||||
|
||||
bool ArbitraryEventsWorkerWithContext::VisitEvent(gd::BaseEvent &event) {
|
||||
if (!event.HasVariables()) {
|
||||
return AbstractArbitraryEventsWorker::VisitEvent(event);
|
||||
}
|
||||
// Push local variables
|
||||
auto newProjectScopedContainers =
|
||||
ProjectScopedContainers::MakeNewProjectScopedContainersWithLocalVariables(
|
||||
*currentProjectScopedContainers, event);
|
||||
auto *parentProjectScopedContainers = currentProjectScopedContainers;
|
||||
currentProjectScopedContainers = &newProjectScopedContainers;
|
||||
|
||||
bool shouldDelete = AbstractArbitraryEventsWorker::VisitEvent(event);
|
||||
|
||||
// Pop local variables
|
||||
currentProjectScopedContainers = parentProjectScopedContainers;
|
||||
return shouldDelete;
|
||||
}
|
||||
|
||||
ReadOnlyArbitraryEventsWorker::~ReadOnlyArbitraryEventsWorker() {}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::VisitEvent(
|
||||
const gd::BaseEvent &event) {
|
||||
AbstractReadOnlyArbitraryEventsWorker::VisitEvent(event);
|
||||
}
|
||||
|
||||
ReadOnlyArbitraryEventsWorkerWithContext::~ReadOnlyArbitraryEventsWorkerWithContext() {}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorkerWithContext::VisitEvent(
|
||||
const gd::BaseEvent &event) {
|
||||
if (!event.HasVariables()) {
|
||||
AbstractReadOnlyArbitraryEventsWorker::VisitEvent(event);
|
||||
return;
|
||||
}
|
||||
// Push local variables
|
||||
auto newProjectScopedContainers =
|
||||
ProjectScopedContainers::MakeNewProjectScopedContainersWithLocalVariables(
|
||||
*currentProjectScopedContainers, event);
|
||||
auto *parentProjectScopedContainers = currentProjectScopedContainers;
|
||||
currentProjectScopedContainers = &newProjectScopedContainers;
|
||||
|
||||
AbstractReadOnlyArbitraryEventsWorker::VisitEvent(event);
|
||||
|
||||
// Pop local variables
|
||||
currentProjectScopedContainers = parentProjectScopedContainers;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -3,50 +3,52 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_ARBITRARYEVENTSWORKER_H
|
||||
#define GDCORE_ARBITRARYEVENTSWORKER_H
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#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 {
|
||||
|
||||
/**
|
||||
* \brief ArbitraryEventsWorker is an abstract class used to browse events (and
|
||||
* instructions) and do some work on them. Can be used to implement refactoring
|
||||
* for example.
|
||||
* \brief AbstractArbitraryEventsWorker is a base abstract class used to browse events (and
|
||||
* instructions) and do some work on them. It must not be inherited directly.
|
||||
*
|
||||
* \see gd::ArbitraryEventsWorker
|
||||
* \see gd::ArbitraryEventsWorkerWithContext
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ArbitraryEventsWorker : private EventVisitor {
|
||||
class GD_CORE_API AbstractArbitraryEventsWorker : private EventVisitor {
|
||||
public:
|
||||
ArbitraryEventsWorker(){};
|
||||
virtual ~ArbitraryEventsWorker();
|
||||
AbstractArbitraryEventsWorker(){};
|
||||
virtual ~AbstractArbitraryEventsWorker();
|
||||
|
||||
/**
|
||||
* \brief Launch the worker on the specified events list.
|
||||
*/
|
||||
void Launch(gd::EventsList& events) { VisitEventList(events); };
|
||||
protected:
|
||||
virtual bool VisitEvent(gd::BaseEvent& event) override;
|
||||
void VisitEventList(gd::EventsList& events);
|
||||
|
||||
private:
|
||||
void VisitEventList(gd::EventsList& events);
|
||||
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.
|
||||
@@ -62,9 +64,9 @@ class GD_CORE_API ArbitraryEventsWorker : private EventVisitor {
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
@@ -85,6 +87,41 @@ class GD_CORE_API ArbitraryEventsWorker : private EventVisitor {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief ArbitraryEventsWorker is an abstract class used to browse events (and
|
||||
* instructions) and do some work on them. Can be used to implement refactoring
|
||||
* for example.
|
||||
*
|
||||
* \see gd::ArbitraryEventsWorkerWithContext
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ArbitraryEventsWorker : public AbstractArbitraryEventsWorker {
|
||||
public:
|
||||
ArbitraryEventsWorker(){};
|
||||
virtual ~ArbitraryEventsWorker();
|
||||
|
||||
/**
|
||||
* \brief Launch the worker on the specified events list.
|
||||
*/
|
||||
void Launch(gd::EventsList &events) {
|
||||
AbstractArbitraryEventsWorker::VisitEventList(events);
|
||||
};
|
||||
|
||||
private:
|
||||
bool VisitEvent(gd::BaseEvent &event) override;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -96,11 +133,10 @@ class GD_CORE_API ArbitraryEventsWorker : private EventVisitor {
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ArbitraryEventsWorkerWithContext
|
||||
: public ArbitraryEventsWorker {
|
||||
: public AbstractArbitraryEventsWorker {
|
||||
public:
|
||||
ArbitraryEventsWorkerWithContext()
|
||||
: currentGlobalObjectsContainer(nullptr),
|
||||
currentObjectsContainer(nullptr){};
|
||||
: currentProjectScopedContainers(nullptr){};
|
||||
virtual ~ArbitraryEventsWorkerWithContext();
|
||||
|
||||
/**
|
||||
@@ -108,60 +144,55 @@ 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_;
|
||||
ArbitraryEventsWorker::Launch(events);
|
||||
const gd::ProjectScopedContainers& projectScopedContainers) {
|
||||
currentProjectScopedContainers = &projectScopedContainers;
|
||||
AbstractArbitraryEventsWorker::VisitEventList(events);
|
||||
};
|
||||
|
||||
void Launch(gd::EventsList& events) = delete;
|
||||
|
||||
protected:
|
||||
const gd::ObjectsContainer& GetGlobalObjectsContainer() {
|
||||
protected:
|
||||
const gd::ProjectScopedContainers& GetProjectScopedContainers() {
|
||||
// Pointers are guaranteed to be not nullptr after
|
||||
// Launch was called.
|
||||
return *currentGlobalObjectsContainer;
|
||||
return *currentProjectScopedContainers;
|
||||
};
|
||||
const gd::ObjectsContainer& GetObjectsContainer() {
|
||||
const gd::ObjectsContainersList& GetObjectsContainersList() {
|
||||
// Pointers are guaranteed to be not nullptr after
|
||||
// Launch was called.
|
||||
return *currentObjectsContainer;
|
||||
return currentProjectScopedContainers->GetObjectsContainersList();
|
||||
};
|
||||
|
||||
private:
|
||||
const gd::ObjectsContainer* currentGlobalObjectsContainer;
|
||||
const gd::ObjectsContainer* currentObjectsContainer;
|
||||
bool VisitEvent(gd::BaseEvent& event) override;
|
||||
|
||||
const gd::ProjectScopedContainers* currentProjectScopedContainers;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief ReadOnlyArbitraryEventsWorker is an abstract class used to browse events (and
|
||||
* instructions). It can be used to implement autocompletion for example.
|
||||
* instructions). It must not be inherited directly.
|
||||
*
|
||||
* \see gd::ReadOnlyArbitraryEventsWorker
|
||||
* \see gd::ReadOnlyArbitraryEventsWorkerWithContext
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ReadOnlyArbitraryEventsWorker : private ReadOnlyEventVisitor {
|
||||
class GD_CORE_API AbstractReadOnlyArbitraryEventsWorker : private ReadOnlyEventVisitor {
|
||||
public:
|
||||
ReadOnlyArbitraryEventsWorker() : shouldStopIteration(false) {};
|
||||
virtual ~ReadOnlyArbitraryEventsWorker();
|
||||
|
||||
/**
|
||||
* \brief Launch the worker on the specified events list.
|
||||
*/
|
||||
void Launch(const gd::EventsList& events) { VisitEventList(events); };
|
||||
AbstractReadOnlyArbitraryEventsWorker() : shouldStopIteration(false) {};
|
||||
virtual ~AbstractReadOnlyArbitraryEventsWorker();
|
||||
|
||||
protected:
|
||||
void StopAnyEventIteration() override;
|
||||
virtual void VisitEvent(const gd::BaseEvent& event) override;
|
||||
|
||||
void VisitEventList(const gd::EventsList& events);
|
||||
|
||||
private:
|
||||
void VisitEventList(const gd::EventsList& events);
|
||||
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.
|
||||
@@ -175,7 +206,7 @@ protected:
|
||||
|
||||
/**
|
||||
* 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) {};
|
||||
@@ -192,9 +223,41 @@ protected:
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief ReadOnlyArbitraryEventsWorker is an abstract class used to browse events (and
|
||||
* instructions). It can be used to implement autocompletion for example.
|
||||
*
|
||||
* \see gd::ReadOnlyArbitraryEventsWorkerWithContext
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ReadOnlyArbitraryEventsWorker
|
||||
: public AbstractReadOnlyArbitraryEventsWorker {
|
||||
public:
|
||||
ReadOnlyArbitraryEventsWorker(){};
|
||||
virtual ~ReadOnlyArbitraryEventsWorker();
|
||||
|
||||
/**
|
||||
* \brief Launch the worker on the specified events list.
|
||||
*/
|
||||
void Launch(const gd::EventsList &events) {
|
||||
AbstractReadOnlyArbitraryEventsWorker::VisitEventList(events);
|
||||
};
|
||||
|
||||
private:
|
||||
void VisitEvent(const gd::BaseEvent &event) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief An events worker that will know about the context (the objects
|
||||
* container). Useful for workers working on expressions notably.
|
||||
@@ -204,11 +267,10 @@ protected:
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ReadOnlyArbitraryEventsWorkerWithContext
|
||||
: public ReadOnlyArbitraryEventsWorker {
|
||||
: public AbstractReadOnlyArbitraryEventsWorker {
|
||||
public:
|
||||
ReadOnlyArbitraryEventsWorkerWithContext()
|
||||
: currentGlobalObjectsContainer(nullptr),
|
||||
currentObjectsContainer(nullptr){};
|
||||
: currentProjectScopedContainers(nullptr){};
|
||||
virtual ~ReadOnlyArbitraryEventsWorkerWithContext();
|
||||
|
||||
/**
|
||||
@@ -216,32 +278,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_;
|
||||
ReadOnlyArbitraryEventsWorker::Launch(events);
|
||||
const gd::ProjectScopedContainers& projectScopedContainers) {
|
||||
currentProjectScopedContainers = &projectScopedContainers;
|
||||
AbstractReadOnlyArbitraryEventsWorker::VisitEventList(events);
|
||||
};
|
||||
|
||||
void Launch(gd::EventsList& events) = delete;
|
||||
|
||||
protected:
|
||||
const gd::ObjectsContainer& GetGlobalObjectsContainer() {
|
||||
protected:
|
||||
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 *currentProjectScopedContainers;
|
||||
};
|
||||
|
||||
private:
|
||||
const gd::ObjectsContainer* currentGlobalObjectsContainer;
|
||||
const gd::ObjectsContainer* currentObjectsContainer;
|
||||
void VisitEvent(const gd::BaseEvent& event) override;
|
||||
|
||||
const gd::ProjectScopedContainers* currentProjectScopedContainers;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_ARBITRARYEVENTSWORKER_H
|
||||
|
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
|
65
Core/GDCore/IDE/Events/BehaviorParametersFiller.cpp
Normal file
65
Core/GDCore/IDE/Events/BehaviorParametersFiller.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2024 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "BehaviorParametersFiller.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
bool BehaviorParametersFiller::DoVisitInstruction(gd::Instruction &instruction,
|
||||
bool isCondition) {
|
||||
const auto &metadata = isCondition
|
||||
? gd::MetadataProvider::GetConditionMetadata(
|
||||
platform, instruction.GetType())
|
||||
: gd::MetadataProvider::GetActionMetadata(
|
||||
platform, instruction.GetType());
|
||||
|
||||
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
instruction.GetParameters(), metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue, size_t parameterIndex,
|
||||
const gd::String &lastObjectName) {
|
||||
if (parameterMetadata.GetValueTypeMetadata().IsBehavior() &&
|
||||
parameterValue.GetPlainString().length() == 0) {
|
||||
|
||||
auto &expectedBehaviorTypeName =
|
||||
parameterMetadata.GetValueTypeMetadata().GetExtraInfo();
|
||||
|
||||
auto &objectsContainersList =
|
||||
projectScopedContainers.GetObjectsContainersList();
|
||||
auto behaviorNames =
|
||||
objectsContainersList.GetBehaviorsOfObject(lastObjectName, true);
|
||||
|
||||
gd::String foundBehaviorName = "";
|
||||
for (auto &behaviorName : behaviorNames) {
|
||||
auto behaviorTypeName =
|
||||
objectsContainersList.GetTypeOfBehavior(behaviorName, false);
|
||||
if (behaviorTypeName == expectedBehaviorTypeName) {
|
||||
foundBehaviorName = behaviorName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundBehaviorName.empty()) {
|
||||
instruction.SetParameter(parameterIndex,
|
||||
gd::Expression(foundBehaviorName));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BehaviorParametersFiller::~BehaviorParametersFiller() {}
|
||||
|
||||
} // namespace gd
|
45
Core/GDCore/IDE/Events/BehaviorParametersFiller.h
Normal file
45
Core/GDCore/IDE/Events/BehaviorParametersFiller.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2024 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
class Platform;
|
||||
class ProjectScopedContainers;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Fill empty behavior parameters with any behavior that matches the
|
||||
* required behavior type.
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API BehaviorParametersFiller : public ArbitraryEventsWorker {
|
||||
public:
|
||||
BehaviorParametersFiller(
|
||||
const gd::Platform &platform_,
|
||||
const gd::ProjectScopedContainers &projectScopedContainers_)
|
||||
: platform(platform_),
|
||||
projectScopedContainers(projectScopedContainers_){};
|
||||
virtual ~BehaviorParametersFiller();
|
||||
|
||||
private:
|
||||
bool DoVisitInstruction(gd::Instruction &instruction,
|
||||
bool isCondition) override;
|
||||
|
||||
const gd::Platform &platform;
|
||||
const gd::ProjectScopedContainers &projectScopedContainers;
|
||||
};
|
||||
|
||||
} // 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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user