Preprocessor Enhancement

Monkey Forums/Monkey Programming/Preprocessor Enhancement

Samah(Posted 2011) [#1]
Since we have the #If preprocessor stuff that can read from the pre-assigned TARGET/LANG/etc. variables, would it be possible to be able to make our own?

This would be a lovely enhancement if you could do something like this:
#define APP_LABEL="My Game"
#define SCREEN_ORIENTATION="portrait"

...and have it automatically update the Android CONFIG.TXT when you compile.

Being able to just arbitrarily make any variable name would be great too, since you could pass it in to trans with a command line variable (which would make build configurations really useful in IDEs).
trans -D FOO="bar" ...

...being the same as having this at the top of your monkey source:
#define FOO="bar"

Having everything in one source file means that you don't need to change your CONFIG.TXT or any other configuration files every time you do a clean build, and it keeps your entire application within Monkey source (apart from data).

And of course you would be able to use these variables within your preprocessor logic too.


AdamRedwoods(Posted 2011) [#2]
+1


MikeHart(Posted 2011) [#3]
+1


Raz(Posted 2011) [#4]
+1 from me, it makes way more sense than trawling through generated code.


matt(Posted 2011) [#5]
+1


Gerry Quinn(Posted 2011) [#6]
I like this too


TheRedFox(Posted 2011) [#7]
+1 as well.


Aman(Posted 2011) [#8]
+1


Samah(Posted 2011) [#9]
Bumpity bump.


gregbug(Posted 2011) [#10]
+1


Samah(Posted 2011) [#11]
Can we get some sort of official response on this?
<3 Mark

Nudge nudge, wink wink, say no more.


Zwer99(Posted 2011) [#12]
Yeah, would be very nice!

+1


pantson(Posted 2011) [#13]
As its gone a bit quiet.. I'll bump it as its a feature I would like see too


Samah(Posted 2011) [#14]
Bump again, pending a response from Mark.


Dabz(Posted 2011) [#15]

#define APP_LABEL="My Game"
#define SCREEN_ORIENTATION="portrait"



GLBasic has a little "project properties" bit in the IDE where you can tinker with this stuff then forget about it.

Maybe they should add something to monk, and/or ziggy could implement something to Jungle.

Simplest way IMO.

Dabz


Shinkiro1(Posted 2011) [#16]
Thats a great idea Dabz, maybe monkey apps should have their own kind of plist(like ios & osx apps).


slenkar(Posted 2011) [#17]
if this doesnt get done , someone could hack it into trans pretty easily

it would be mildly annoying to modify trans on every new release i spose


Soap(Posted 2011) [#18]
+1


xlsior(Posted 2011) [#19]
+1


Samah(Posted 2011) [#20]
@Dabz: Simplest way IMO.

For those particular properties, yes, but I want this enhancement for more than just pushing values to config.txt.


marksibly(Posted 2011) [#21]
Hi,

> #define APP_LABEL="My Game"
> #define SCREEN_ORIENTATION="portrait"

How does this differ from:

Const APP_LABEL$="My Game"
Const SCREEN_ORIENTATION$="portrait"

?


invaderJim(Posted 2011) [#22]
Is that supposed to work? :(


slenkar(Posted 2011) [#23]
no


Samah(Posted 2011) [#24]
Mark:
Because the whole point is to be able to use these constants in preprocessor directives. If you can also pass these constants into the trans command line it means you can set up custom build configurations.


Fred(Posted 2011) [#25]
+1


marksibly(Posted 2011) [#26]
Hi,

> Because the whole point is to be able to use these constants in preprocessor directives.

Why? In what situation would you need to use '#If' with, say, APP_LABEL...

#If APP_LABEL="MyApp"
'what goes here? Why not just use an 'If'?
#End

I'm not saying it's necessarily a bad idea, but your examples of APP_LABEL and FOO are pretty vague, and given that it's a potentially major change, I'd like more than just a few fuzzy examples to go by.

Also, I did have my own plans for a 'better' preprocessor, something like:

#Const APP_LABEL$="Hello"
#If APP_LABEL="Hello"
blah...
#Endif

...in other words, there would be a whole 'meta' pass that took place inside an interpreter - but of course I need to do/start the interpreter first. Just bunging in #define now would likely complicate this at a later date - but perhaps it's worth it?

I did indeed have something like this going at one point, but it was using the parse tree to interpret, which didn't work well. Interpreter really needs to be it's own target.

> ...and have it automatically update the Android CONFIG.TXT when you compile.

Now this is something quite different IMO - again, not necessarily a bad idea, but perhaps better off in a unified/per-target config file somewhere?

It would definitely be nice to be able to edit such config files visually in a consistent way - at the moment, each target sort of has it's own ad-hoc config system.


marksibly(Posted 2011) [#27]
Hi,

> Thats a great idea Dabz, maybe monkey apps should have their own kind of plist(like ios & osx apps).

I'd be keen on doing something like this - there are already config files in there for some of the targets, but there's not a consistent system as yet so it'd be nice to clean this up. I guess I'm just not wild about adding #define at the moment - it's not as easy as it sounds with multiple/cyclic imports, and I'd prefer the 'interpreter-as-preprocessor' approach in the long run.

One option would be to add a 'monkey.cfg' file to each target dir, and possibly even the .build dir.

For example, you could have 3 levels of config file:

1) bin/monkey.cfg (renamed!)
2) .build/monkey.cfg
3) .build/target/monkey.cfg

Config files at lower levels could override those at higher levels, and the contained 'defines' could be made visible to the current pre-processor.

So you could stick APP_TITLE= in .build/monkey.cfg and it'd be shared by all targets, unless you overrode it in a target config file. Perhaps that's overkill though - maybe just have separate .build/target config files?

I don't think this'd be a silver bullet though - there's only so much you can do with textual replacement (ie: it doesn't work well with xcode project files) but I guess it's a start...?

Also, I'm kind of dubious about adding stuff like SCREEN_ORIENTATION to one config file that eventually just ends up replacing a ${SCREEN_ORIENTATION} tag in another config file! To me, it sounds a bit like unnecessary complexity - learning to modify, say, manifest.xml may just be simpler in the first place. It's certainly more flexible, unless you want to add tags for every possible manifest setting.


Samah(Posted 2011) [#28]
Why? In what situation would you need to use '#If' with, say, APP_LABEL...

You wouldn't. But it should be smart enough that you can use a $APP_LABEL or something in your configuration files and it will take it from the main compilation unit. This is really the biggest use for the enhancement.

Another example of using custom preprocessor logic:
#if TARGET="android" or TARGET="ios"
DoMobile()
#else
DoNotMobile()
#end
If these aren't called anywhere else, the current trans will only compile one of them (yay).

#if TARGET="android" or TARGET="ios"
Const mobile? = True
#else
Const mobile? = False
#end
If mobile
  DoMobile()
Else
  DoNotMobile()
End
This will still generate the unused function (not yay).

#if TARGET="android" or TARGET="ios"
  #define MOBILE_TARGET=True
#else
  #define MOBILE_TARGET=False
#end

#if MOBILE_TARGET
  DoMobile()
#else
  DoNotMobile()
#end
This should work the same as the first example, where the unused function is not generated. In this particular example it would save you checking multiple targets every time, and would allow you to test mobile code in another target just by adding TARGET="html5" to that first #if.

#Const APP_LABEL$="Hello"

Same thing really, just less C-like and more Blitz-like (that's fine).


slenkar(Posted 2011) [#29]
Now this is something quite different IMO - again, not necessarily a bad idea, but perhaps better off in a unified/per-target config file somewhere?


This would be good, it would solve several problems,

-Turn anti-aliasing on or off on multiple targets without having to edit mojo source files each time

could possibly be used for:

-Turn off including media in flash?

-Changing C++ compilation options to get faster compilation OR faster game logic depending on the situation the developer is in.


therevills(Posted 2011) [#30]
Turn anti-aliasing on or off on multiple targets without having to edit mojo source files each time


Would this be better if it was an actual command in mojo?


Samah(Posted 2011) [#31]
@slenkar: -Changing C++ compilation options to get faster compilation OR faster game logic depending on the situation the developer is in.
And if these were in preprocessor logic, you could set up multiple build configurations for testing.

@therevills: Would this be better if it was an actual command in mojo?
Yes.


FlameDuck(Posted 2011) [#32]
If you can also pass these constants into the trans command line it means you can set up custom build configurations.
If you want custom build configurations, might I suggest using a build tool? Ant is already a prerequisite for many Monkey users, so you could work with that. Failing that Maven will do the trick for you. You can even have profiles set up to do different things for different targets and different lifecycle phases (process-resources, compile, test, package, integration-test, install, deploy, etc.).

And if these were in preprocessor logic, you could set up multiple build configurations for testing.
The thing I don't understand (maybe because I'm a Java programmer and not a C programmer) is "Why would you want to clutter your source code, with your build configuration?" Wouldn't it be better to keep your source code and your build configuration separate? So that if (for instance) someone adds a new target to Monkey you could include/exclude it, without having to modify the source code, and just modify the build configuration instead? More importantly it doesn't require any involvement from BRL.

-Turn anti-aliasing on or off on multiple targets without having to edit mojo source files each time
-Turn off including media in flash?
-Changing C++ compilation options to get faster compilation OR faster game logic depending on the situation the developer is in.
All of these could (and should IMHO) be part of the build configuration, and should most certainly not be part of the source code. Why would you even want to litter your code with things that have nothing to do with the program logic?


ziggy(Posted 2011) [#33]
I do really like the cascade approach for cfg fileas that Mark is suggesting (ala CSS). It looks like the most sensible thing to do IMHO. Allowing scripted building would also be very nice, but I would not considere a main priority if a simple cfg (ini like) system in a cascade way is implemented.


Playniax(Posted 2011) [#34]
@Mark:

I really love the #Const idea!

#Const APP_LABEL$="Hello"
#If APP_LABEL="Hello"
blah...
#Endif

That's what I need! ;)


Samah(Posted 2011) [#35]
@Playniax:
It would be nice to be able to pass these constants into trans at the command line too.


Gerry Quinn(Posted 2011) [#36]
I agree with Playniax above - a simple preprocessor like that is all I want. I don't want to be messing with build tools and such.


Grover(Posted 2012) [#37]
Hi, Id also like to add to this as a request to be added. To help with use case understanding I'll explain why we need it.

We are developing a game that has a builtin builder, but we dont want to publish the builder so we need a way to "compile out" the builder. At the moment we are doing this manually with a couple of
#If True.. 'Build with builder

We change the true to change the build, but its messy and not very explanatory. The other use case is where we need to have two style of build types - one which uses external files in glfw mode, and the other which uses glfw with embedded data (auto generated). Again, at the moment we manually change imports and such, which is quite dangerous and its easy to incorrectly deploy the wrong release type.

Hope this helps. The #Const idea seems the simplest/nicest implementation.


charlie(Posted 2012) [#38]
#if App_label would likely be useful for thing like lite/not lite or demo/full/steam/whatever. It's a pain not being able to do this in Blitzmax.

Cheers
Charlie