New stuff now up!


I’ve had a few internet problems over the last week, so I didn’t end up doing anything (directly) on the ios target as I couldn’t face even attempting it without stackoverflow support – nevermind xcode docs! Internet is now back at full speed though so it’s back into ios tomorrow.

Without much in the way of internet, I instead got to work on a bunch of stuff that *I* have complete control over, which is always the most fun! I’ve just pushed the results to github, and there is some cool stuff in there IMO. But first…

Breaking Changes Alert!

The __TARGET__ preprocessor var now works differently with desktop targets. It is now set to one of the following values: “windows”, “macos”, “linux”, “emscripten”, “android” or “ios” – ie: the *precise* target. You can still pass ‘-target=desktop’ to mx2cc (and it’s still called “desktop” in ted2) but this now gets converted to one of “windows”, “macos” or “linux” before anything’s compiled.

I have also added the following boolean preprocessor vars: __DESKTOP_TARGET__ (true if __TARGET__ is “windows”, “macos” or “linux”), __MOBILE_TARGET__ (true if __TARGET__ is “android” or “ios”) and __WEB_TARGET__ (true if __TARGET__ is “emscripten” or, hopefully one day, “webasm”!).

Changing __TARGET__ like this is a semi-major change (and apologies if I’ve borked your code, but it should be easy to fix) but the way it used to work forced you to use __HOSTOS__ everywhere to find the real target, which is not correct if we eventually want to be able to support cross-compilation in future.

I considering adding a new var, but it’s already confusing enough and I think this simplifies things down to a very clear set of vars. I’ve also added a little fudge to the parser, so if you have code that compares __TARGET__ with “desktop” you should get an error.

__HOSTOS__ is still there, but don’t use it. It will probably change to plain __HOST__ with the same potential values as __TARGET__.

Next up, I have moved the Timer and Process classes from mojo to std. If you are ‘Using std…’ and ‘Using mojo…’ this should have no effect on your code, but if not you will need to make changes if you use these.

I did this mainly because I never really wanted these to be in mojo in the first place, and other stuff is starting to ‘leak’ into mojo too! The main problem here is that mojo is currently the only bit of mx2 that manages an event queue, and both Timer and Process depend(ed) on being able to post messages (via internal c++ code in mojo) from a separate thread to the main ‘app’ thread.

Things started getting ugly here when I wanted to add Fiber.Sleep, which needed to do the same thing, but I didn’t really want to have to move Fiber to mojo too (and I definitely don’t want to make std dependant on mojo) – it’s getting crowded in there! And I can see a lot of future cases like this too, eg: synchronous TcpStreams that politely block the current fiber etc.

So I ended up adding a simple ‘pseudo’ queue system to std (in std.async – it’s mostly extern code) that can be used to post messages from threads. However, it currently does nothing on its own – it depends on mojo to ‘hook’ it to provide a real event queue. But it should be pretty easy for std.async to provide a real/default queue, which means you’d be able to use all the async stuff from plain console apps…one day.

The upshot of all this is that Timer and Process are now in std, but you still need to be building a mojo app for them to work!

Class Fiber now has a Sleep( seconds:Double) function to pause the current fiber, and I added a Now:Double() to std.time (which uses an arbitrary time base). I’ve gone with doubles here because it makes a LOT of timing logic much easier. For example, the old Timer code used to do some nasty bresenham stuff to produce correct millisecond delays (eg: 16,17,17,16,17,17…for 16.66666 period). This is a whole lot simpler with doubles (although, yes, the result is not 10000% accurate) and means you can now create a Timer with hertz<1. Woohoo!

Fiber.Sleep has also meant I’ve been able to implement Timer in 100% mx2, which is nice.

New Language Features!

These are are currently still very WIP, but I’ve added preliminary ‘Operator To’ and class extension support to mx2cc.

Operator To allows you to add an implicit conversion operator to a class or struct (not interface). The basic idea is:

While I’m not generally a huge fan of implicit conversion operators like this, there are some situations where they can be very useful.

For example, up until now there’s been no easy way to convert Vec2<Int> to Vec2<Float>, and I ended up adding a few special case functions to let you do things like multiplying a Vec2<Int> by an AffineMat3<Float> etc. But by adding this to Vec2<T>…

…you can now pass a Vec2 of any type to something that wants a Vec2 of any other type.

You can’t ‘chain’ operator To yet (I think – and maybe never) and I’m not totally sold on the name yet (IMO it looks very clear/obvious, but does ‘borrow’ a keyword and I haven’t thought through parser issues yet) but I like it so far!

There is no ‘Object.ToString()’ yet (this is a bit complex, as I don’t want to force To:String() to be virtual for all objects) but for debugging this would of course be very nice.

I also do not plan to also allow ‘constructor based’ conversion. IMO, this is where things in c++ start to get really wacky (which conversion is being used?!? I still have to google it…) (also, I don’t really like it when the compiler calls ‘New’ for you…) and with the next feature I don’t think it’s really necessary…

Class extensions allow you to add non-virtual methods (and other members except fields) to an existing class, ie:

You can’t yet add extensions to built-in types, and there are several issues with ‘search order’, but as far as I can tell this is working pretty well, even with generic types, eg:

Where things get really interesting is combining both of these. For example, I was working on some c++ a while back that used both the ‘glm’ math library, and the ‘bullet’ physics library. Both these libs had their own ‘vec3’ etc types, but of course they were incompatible.

As far as I know, there is no way to add an implicit conversion operator ‘outside’ of a type in c++, so unless you were willing to tweak either the bullet or glm source code, you were stuck with having to wrap a bunch of stuff in to_glm() or to_bt() functions.

But with extensons and operator to, you can do it this way:

Which, according to my calculations, should allow you to freely pass to glm_vec3’s to bullet and vice versa!

New Build Stuff!

Building an app in Ted2 now builds the app in a separate ‘blah.products/TARGET’ dir, eg: if you build ‘commanche.monkey2’ for the desktop target on windows, you end up with the exe/assets/dlls etc in a “commanche.products/Windows/” dir. By default, mx2cc on the command line works the same as it used to, ie: the product is placed in the ‘.buildvblah’ folder. There is a new mx2cc ‘-product’ option that ted2 uses, but leave it alone! Also note that none of this affects makemods, only makeapp.

Yes, this is another ‘junk’ dir, but I think it’s the best solution (until I can think of a better one) as the build products now get their own ‘clean’ dir that contains only what you need to run (or build in android studio/xcode etc) the app. The ‘.buildv’ dirs are temporary and contain all sorts of junk, so it all ends up a bit of a mess cramming more in there.

And Ted2 now offers simple per-target ‘product settings’ options (pretty much only App Name right now) and these are stored in a blah.products/products.json file that you generally don’t want to accidentally trash, as it’s effectively the ‘project’ file for all targets.

This is all very tentative stuff right now, but I like where it’s heading.



9 thoughts to “New stuff now up!”

  1. Like it! Operator “To” and “Extension” looks like cool additions.

    Float timer seems like a good idea.

    Is input touch/mouse/keyboard timing seperate from main loop/screen refresh rate? E.g. if I wanted to make a virtual musical instrument, can the time the users tap on the screen, be registered super precisely?


  2. > Is input touch/mouse/keyboard timing seperate from main loop/screen refresh rate,?

    No, everything runs on a single thread so you’re stuck with the ‘vsync’ delay. You can try to disable it, but as I understand it the driver/user can override this.

    One thing I have been considering though is trying to move SwapBuffers (which is where vsync happens)  alone to a different thread (although I’m not sure how happy GL would be with that). The app code could then theoretically continue to process IO, events, audio stuff etc. on the main thread while it’s waiting for vsync to finish. Rendering code itself would still have to happen on the main thread though – it would just be ‘delayed’ for longer, ie: until previous vsync finished.



  3. It seems a very big update! MX2 seems to have the ‘magic’ to glue together (ref to the different libs) many things in a easy way (well, at least for people that understand different codes, not my case!).
    It could be – literally – the ‘killer feature’ of the language.


  4. 1.

    monkey.types.Object contains

    Is this ‘void ptr’ useful? Why not ‘string’?

    Can you replace return type or add another method ‘typeNameStr :String ()’

    It’s useful to store objects in hashmap via string type.


    What about extending base array type with methods Contains and Find.


  5. Clever stuff!

    As for the question asked on patreon, I think users would benefit from pre compiled in development versions. For some reason, it feels like compiling from source that’s posted to github is a commitment with no guarantee of a working experience. Even automatic builds may provide a level of peace of mind to a random user who isn’t yet committed to the MX2 ecosystem.


  6. Is this ‘void ptr’ useful?

    Not really, is mainly there for dev/debugging the guts of mx2.

    Ultimately, this is likely to be replaced by something like TypeInfo() that returns an object containing typename etc.

    What about extending base array type with methods Contains and Find.

    Maybe, but it’s a little tricky as c++ can’t search for ‘operator<=>’ etc the way mx2cc can. But once extensions are going properly for builtin types, it could be doable.





  7. Mark, do you plan to extend properties? Possibility to

    make it Global
    make setter Private

    Hm, ‘make private’ not need because we should to use inner variable to store prop value, so we can change it directly.