Why is _tick exposed to Java?

While working on the port. Mr. Palmer and I ran across Java_org.lwjgl_Window_tick(). Why is this exposed to a Java program? I can’t imagine why such a platform specific function would be exposed to a Java program. There isn’t anything a Java programmer can do with it except forget to call it and end up with a queue full of windowing messages. Why isn’t this encapsulated within the LWJGL framework? (like in swap or something).

Next up, shouldn’t this only show up in programs that run in windowed mode? If an application requests to only ever run in fullscreen - shouldn’t this function just go away altogether?

Well generally, I thinkg Cas would like to take this one :wink:

The problem is that there are no methods that are guarenteed to be called at any one time, there was therefore no other place to stick it. At least thats what I remember from the discussion.

[quote]Next up, shouldn’t this only show up in programs that run in windowed mode? If an application requests to only ever run in fullscreen
[/quote]
Theoretically, yes - however that too would also just introduce the posibility of bugs. Better to always just call tick()

[quote]Next up, shouldn’t this only show up in programs that run in windowed mode? If an application requests to only ever run in fullscreen
[/quote]
If it is possible, I would love for it to go away…

There are just Some Things That Need To Be Done to make the library work, cross-platformwise. Very much like you need to call paint() to get the display to swap buffers, you need to call tick() to take care of stuff. What the stuff actually is isn’t defined, except that it must be called every game tick and it’s therefore a great place for the aspiring LWJGL porter to process the underlying OS message loop.

We did have tick() hidden away in paint() at one point but this breaks in certain situations or wastes CPU cycles on those systems that prefer to share them. You don’t paint(), for example, when you are in isMinimized() state.

The proper way to do a main loop is this:


while (!finished) {

      gl.tick();

      if (gl.isMinimized()) {
            if (gl.isDirty())
                  gl.paint();
            Thread.sleep(200);
            continue;
      } else if (gl.isCloseRequested()) {
            finished = true;
      }

      // Poll devices, read buffers, tick, render

      // Paint the display and take care of all the
      // OS windowing functions
      gl.paint();

      // Cap frame rate

}


It’s so proper we nearly had a go at encapsulating it in the library but something felt wrong so we scrapped it.

Cas :slight_smile:

Why not put this loop in the library as a convenience method that calls through an interface to activate the game logic every ‘tick’? It could still be optional to actually use this loop or roll your own… but having it would help in most cases.

Is there any way that you could FORCE apps to fail that don’t call tick, so as to make it harder to forget?

The problem is that its just really bad practice to HAVE to do something all the time and then give you a function call to make sure its done. If it needs to be done all the time, there is no reason at all to expose it to the library. There are no user servicable parts inside so all it really done is add a breaking point IMHO.

Tick should be buried deep deep in the bowels of LWJGL because it really serves no purpose to the application developer. Its akin to having AWT or Swing require the developer to call something when their GUI is up. If its mandatory and the user can’t do anything with it - they need not know of its existence.

Since this is at the entry point in the rendering loop I remain unclear as to why it could not be encapsulated like many of the calls that the input or audio system encapsulates. Under what conditions does it break?

[quote] Is there any way that you could FORCE apps to fail that don’t call tick, so as to make it harder to forget?
[/quote]
Yes, we could have some flag which is set upon paint - and if it is still set on the next paint (or 5 paints) we could throw an exception.

[quote]The problem is that its just really bad practice to HAVE to do something all the time and then give you a function call to make sure its done.
[/quote]
Agreed. However you don’t HAVE to call it (at least in theory) - granted windowed mode would be completely f*cked.

In theory I dislike having to call a method, just because the subsystem requires it - but we all have to do that in some way with most api’s - take the win32 api, all apps have to have the following (in one way or another):

      // Main message loop:
      while (GetMessage(&msg, NULL, 0, 0)) 
      {
            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
            {
                  TranslateMessage(&msg);
                  DispatchMessage(&msg);
            }
      }

I don’t like that I need to do that - but such is life.

Since there are no methods that are guarenteed to be called at any time (except tick(), which we have defined as being a must call method), the only other way to implement it, is by spawning a thread to do this - which is just as evil.

So we’re left with the following solutions:
1 - mandetory tick() = allows the developer to control when the subsystem should be run.

2 - no tick - the developer does zilch, but has no control over when the subsystem is run.

Of the two, I think the former is the least evil.
That said, I am very open for suggestions…

Personally I’m for number 2.

Giving the developer control over when the wndproc or other event pump is called is a tragic mistake because at the Java layer it doesn’t matter. Outside of calling it at the point of paint() what more control would you want to have over it? Paint() is something that it makes perfect sense for the developer to have control over becuase when you process messages makes sense. It doesn’t however bring anything to the table to have the developer controlling when tick() is called (not to mention that the name is overloaded for rendering in most cases - processNativeEvents() would make more sense). Maybe I’m alone on that one, but tick crosses a system boundary for no discernable reason.