[ACS] #libdefine limitations

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
User avatar
difficultoldstuff
Posts: 27
Joined: Fri Jul 17, 2020 5:38 am
Graphics Processor: nVidia with Vulkan support

[ACS] #libdefine limitations

Post by difficultoldstuff »

Hello guys!

This is a theoretical question about ACS's #libdefine limitations. I have mine all nicely shared with various scripts via a ACS library - they really help me keep things under control and tidy. Before I go too far into my project I have a question about any possible limitations (mainly #libdefine maximum count, it's a BIG project) aside from what I've discovered so far:

- #libdefine value cannot be a string or a float / fixed, only integers
- #libdefine constant names can only be up to 32 characters
- maximum #libdefine count can be... [?]

Thank you for your time any any insight!
User avatar
FelesNoctis
Posts: 62
Joined: Sat Apr 18, 2020 8:36 pm
Graphics Processor: nVidia with Vulkan support

Re: [ACS] #libdefine limitations

Post by FelesNoctis »

difficultoldstuff wrote: Tue Feb 08, 2022 1:05 pm - #libdefine value cannot be a string or a float / fixed, only integers
Oh is THAT why my project blew up? I've been pulling my hair out over this for hours. Hit the map-scope variable limit for strings in a generic library script, so I took the plunge to turn them into defines. Can't access defines when importing, apparently. Ok, libdefine it is. Or not, if the above is the reason for everything suddenly breaking.

Some additional clarification on #libdefine would be lovely!
User avatar
randi
Site Admin
Posts: 7731
Joined: Wed Jul 09, 2003 10:30 pm

Re: [ACS] #libdefine limitations

Post by randi »

difficultoldstuff wrote: Tue Feb 08, 2022 1:05 pm- #libdefine value cannot be a string or a float / fixed, only integers
Fixed is fine. (Or should be, anyway, assuming the compiler isn't complaining at you when you try to use them.) It's just a special integer format. 56.0 in fixed point is completely identical to and indistinguishable from the integer (56 << 16).
- #libdefine constant names can only be up to 32 characters
Same as all other identifiers for ACC.
- maximum #libdefine count can be... [?]
Limited by your memory. These are only visible to the compiler and are not included in the compiled script. When you #import a script, it's mostly treated the same as #include with some extra bookkeeping to record the library you imported and to suppress code generation. Any #defines in the #imported script are removed from scope for code after the #import. #libdefine functions otherwise identically to #define, but those definitions live on outside the #import.
FelesNoctis wrote: Sat Nov 12, 2022 10:49 pmHit the map-scope variable limit for strings in a generic library script, so I took the plunge to turn them into defines.
Unfortunately, when the definition is created, ACC has already changed it from a string into an integer representing its would-be position in the string table. This would have to be changed on the ACC side to not turn the string into an integer until it's been inserted into code.

But that still wouldn't help you share strings across library boundaries. Each file that #imported it would have their own copy of the string instead of sharing it. One thing you could do is have a GetMyString(int strnum) function. You'd #libdefine different numbers for each string you want, then pass those to the function, and it can return the string. Example:

Code: Select all

...
#libdefine MYSTR_COOKIE 1
#libdefine MYSTR_MONSTER 2

function string GetMyString(int strnum)
{
    switch (strnum) {
    case MYSTR_COOKIE:  return "Cookie";
    case MYSTR_MONSTER: return "Monster!";
    default: return "";
}
...
User avatar
FelesNoctis
Posts: 62
Joined: Sat Apr 18, 2020 8:36 pm
Graphics Processor: nVidia with Vulkan support

Re: [ACS] #libdefine limitations

Post by FelesNoctis »

randi wrote: Mon Nov 14, 2022 6:04 pm
FelesNoctis wrote: Sat Nov 12, 2022 10:49 pmHit the map-scope variable limit for strings in a generic library script, so I took the plunge to turn them into defines.
Unfortunately, when the definition is created, ACC has already changed it from a string into an integer representing its would-be position in the string table. This would have to be changed on the ACC side to not turn the string into an integer until it's been inserted into code.

But that still wouldn't help you share strings across library boundaries. Each file that #imported it would have their own copy of the string instead of sharing it. One thing you could do is have a GetMyString(int strnum) function. You'd #libdefine different numbers for each string you want, then pass those to the function, and it can return the string. Example:
I'd started adding #defines to all scripts, but this is a much better idea that would function nearly the same way as I'd had it prior to hitting this wall. Thank you very much!


EDIT:
Note for future people finding this. ACC has a limit to how many entries can be in a Switch statement. BCC appears to have increased it dramatically. If you're like me and and up needing to make a massive Switch block, it's worth getting. It does still compile ACC, just make sure you read the documentation.

Return to “Scripting”