I'll take a look at this in a couple of days.
Best,
Scuri
On Wed, Jan 4, 2017 at 8:49 PM, Eric Wing <ewmail...@gmail.com> wrote:
> As I said earlier, the way IUP does its startup sequence and main loop
> is incompatible with Android and iOS, and potentially other backends
> like Emscripten/asm.js/WebAssembly. So I have developed a new
> alternative sequence that I believe will work with all platforms.
>
> Android Background:
> The reason IUP’s current system doesn’t work on Android is two-fold.
> 1) All Android applications start in Java, and Android/Java completely
> control the event loop. It is not possible to access it or control it.
> 2) Android is event driven. Everything starts from a callback in Java.
> There is no C main function. We use callbacks to cross into C via JNI
> so we can run normal IUP user code. But because this is an event
> callback, the function must return. Calling IupMainLoop() is expected
> to not return which thus would block the event loop.
>
> iOS Background:
> iOS almost works, but not quite, so in the end, it is ultimately the
> same problem as Android. In iOS, to start the main event loop, we need
> to call UIApplicationMain(). I made this the implementation for
> IupMainLoop(), and this seems to fit. But the problem is that IUP APIs
> are expected to work before you call IupMainLoop(). If
> UIApplicationMain hasn’t been started yet, there are a bunch of
> implementation details in CocoaTouch I depend on to make the
> implementation work that have not created/initialized yet. These are
> things like the application delegate, and even the autorelease pool.
> So basically, UIApplicationMain is expected to be the first thing run
> in an iOS app. But once you run it, it doesn’t return and it takes
> control of the event loop. So now our problem looks the same as
> Android.
>
> Mac background:
> Mac’s startup sequence is a little different than iOS’s, so I was
> actually able to make Mac conform to the legacy startup sequence.
> However, Mac really wants to behave more like iOS/Android and what I
> did to implement this is not typical.
>
>
> Proposal:
> We introduce a new callback function, e.g. void IupEntryPoint(void)
> which gets invoked after the application gets started. This is where
> the user’s code officially begins.
>
>
> So for a typical cross-platform project, I expect something like:
>
>
> void IupEntryPoint(void);
> void IupExitCallback(void);
>
> // Remember that main is never run on Android.
> // This main function should be a template/copy-and-paste for all IUP
> projects.
> // Don't put any user code here. All user code should start in
> IupEntryPoint.
> // The main you see here is only to get the platform to eventually
> invoke IupEntryPoint() on platforms that need it.
> int main(int argc, char* argv[])
> {
> IupOpen(0, NULL);
> IupSetFunction("ENTRY_POINT", (Icallback)IupEntryPoint);
> // User can no longer assume that IupMainLoop blocks, and may
> return
> immediately.
> // You should probably not put code after this call.
> // On the pre-existing platforms, IupMainLoop will be
> implemented to lead to IupEntryPoint being invoked.
> IupMainLoop();
> return 0;
> }
>
> // This is where user code should start
> void IupEntryPoint()
> {
> // TODO: Proposed exit callback so the user can call IupClose()
> IupSetFunction("EXIT_CB", (Icallback)IupExitCallback);
>
> Ihandle* button = IupButton("Iup Button", "");
> IupSetCallback(button, "ACTION", (Icallback)OnButtonCallback);
> Ihandle* dialog = IupDialog(button);
> IupShow(dialog);
> }
>
> // TODO: Proposed exit callback which the user should setup in the
> IupEntryPoint() callback.
> void IupExitCallback()
> {
> IupClose();
> }
>
> So here are the major points:
>
> - Unchanged legacy code will continue to work as before (Windows, GTK,
> Motif).IupEntryPoint() will not exist nor IupSetFunction is never
> called for it, so it will never get invoked. IupMainLoop() will still
> behave exactly as before on those existing implementations. So nobody
> is forced to migrate until ready.
>
> - New code should adopt this new design. That way it will work on both
> the existing platforms (Windows, GTK, Motif), but also work on the new
> platforms (iOS, Android, Mac).
>
> - On Android, the main() function never gets run. But all the other
> platforms will run it. The callback entry point is where all platforms
> will start running the same code.
>
> - On Android, because main() is never run, there is no opportunity
> to
> call IupSetFunction() beforehand, IupEntryPoint() is a hardcoded
> fallback/default. Because of this, documentation/conventions should
> strongly encourage one standard function name, e.g. IupEntryPoint.
> However, I made it possible to specify a different function name in
> the AndroidManifest.xml.
>
>
> - Unix dlsym allows us to search for a symbol globally instead of a
> specific library. This allows me to hard code a fallback and
> explicitly look for a function called IupEntryPoint if the user did
> not call IupSetFunction("ENTRY_POINT", (Icallback)IupEntryPoint)
> without causing linking headaches. Windows is a harder to support
> this, though it looks like it can be done:
> https://john.nachtimwald.com/2012/07/15/calling-functions-
> in-exe-from-plugins-in-windows/
> But it looks clumsy enough that we probably shouldn’t for Windows. So
> always having IupSetFunction("ENTRY_POINT", (Icallback)IupEntryPoint);
> as above solves this problem.
>
>
> - On Android, nothing must block the event loop, so IupMainLoop() must
> return immediately if called. The contract for IupMainLoop needs to be
> relaxed the reflect this. If users need to distinguish, we could
> introduce a new return value that expresses it immediately returned.
>
> - Because IupMainLoop() may immediately return, shutdown code like
> IupClose() should no longer immediately follow IupMainLoop().
>
>
> - We should have an exit/shutdown callback that can be defined too so
> users have a place to call IupClose() and any special quit cleanup
> they may need to do. However, everybody also needs to keep in mind
> that Android and iOS apps don’t typically quit. Instead, they suspend
> and resume. (And they may be silently killed and never give a quit
> event.) So we will also need to introduce new callbacks for suspend
> and resume and developers need to start thinking about what is actual
> shutdown code vs. what is suspend code (e.g. save to disk).
>
> - Thus, we should probably introduce suspend/background and resume
> callbacks too. On legacy desktop implementations, they will never be
> needed/used so backwards compatibility will just work. (Modern Mac and
> WinRT seem to have introduced features that might be able to leverage
> these events.)
>
>
>
>
> I have implemented this prototype for Android, iOS, and Mac.
>
> https://github.com/ewmailing/IupAndroid
> https://github.com/ewmailing/IupCocoaTouch
> https://github.com/ewmailing/IupCocoa
>
> I’m reasonably convinced this can be made to work for all the existing
> platforms.
>
> Thanks,
> Eric
>
> P.S. I'm completely open to changing the names of the functions and
> attributes.
>
> ------------------------------------------------------------
> ------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
> _______________________________________________
> Iup-users mailing list
> Iup-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/iup-users
>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Iup-users mailing list
Iup-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/iup-users