Ok, like I said I may have missed something, but say I have something like this:

class MyThread extends Thread
{
    run()
    {
        while (something)
        {
           if (something_else) //perhaps input has changed, or we have
data in a socket
           {
               //do some work, not idle
           }
           else
           {
               //no work to do
           }
           Thread.sleep(x); //maybe needed, based on implementation
        }
    }
}

So, say I have the game loop logic in a thread like that, using the
render fps average as a counter, I've noticed that the fps drops when
using more than one thread, even if it's just running in an empty
loop.

Using a looper object forces me to communicate with the thread by
posting messages to its handler.  Say I have a network thread that
just got a message and wants to let the game loop of a new data
available, or the UI thread wants to let the game loop know that the
input state has changed.  It can be done using a handler, or using a
lock to protect a data buffer.

So say in the game logic loop we constantly check the state of some
variable and doing work accordingly, I have found it's much faster to
use a lock around an object than it is to post to a handler.  The way
I remember timing this was I would constantly send network data to the
network thread with a timestamp, then I would check how long it took
for that message to make it to the game loop by determining the time
difference.

I was working directly with bytes, as to avoid any sort of
serialization overhead.

The game loop I'm using is SUPPOSED to be 60fps but will undoubtedly
vary, I use the Timer class's scheduleAtFixedRate to automatically
take care of the timestep adjustments/wait time.

Since the timer class uses a thread pool, it doesn't have an overhead
of thread creation.  I don't have to handle calculating how long to
sleep to maintain a constant rate, and is quite efficient.

I've achieved a smooth display, and the physics progresses a step at
each game loop iteration.
This has worked well for me.


On Sat, Apr 10, 2010 at 12:57 PM, Bob Kerns <r...@acm.org> wrote:
> If a thread is hogging the CPU, it is *BY DEFINITION* not idle. And
> vice versa.
>
> An idle thread will be waiting on something. Either a synchronization
> lock, or an object using wait(), or some blocking IO call. This may be
> buried inside some other code, of course.
>
> I would suggest wondering why you thought this. How are you
> determining what threads are consuming what CPU? Either you have some
> sort of methodology error, or interpretation error.
>
> I would wonder about your statement about a Looper and Handler being
> slow. I haven't read the code, but the implementation I would expect
> would be very simple, and using wait/notify. In other words, they
> SHOULD be fast. If you find them slow, I'd again check your
> methodology -- and if you can confirm, I'd suggest filing a bug
> report, since that's something that could be improved and would
> improve things for the entire platform.
>
> Re 60 fps game logic -- some alternatives to consider that may be
> better choices in some circumstances. I'm only considering physics
> here; I'm not sure what the time constraints on other game logic might
> be:
>
> If you're doing your physics calculations correctly, you won't be
> constrained to a constant game logic rate. You may be able to vary
> your simulation time step to maintain a more steady render rate (at
> the cost of some accuracy), and even vary it between different parts
> of the model, e.g. critical portions (e.g. collisions) run a higher
> rate, while running a longer timestep for portions not subject to time-
> varying forces.
>
> If smooth display is more important than physical accuracy, running
> physics after each frame, driven by actual elapsed time, may be the
> way to go. You can trigger that as you're about to flip the scene, so
> it overlaps the GPU. You may prioritize your fast-moving stuff, and
> only update a portion of your model on each frame.
>
> Also, you may be able to apply Level of Detail (LOD) control to your
> scene -- including fewer polygons when the overall frame rate drops
> (due to either graphics or physics).
>
> All that is a lot more complex, of course, but may let you push the
> envelope a bit further.
>
> On Apr 9, 7:42 pm, Miguel Morales <therevolti...@gmail.com> wrote:
>> I may be completely wrong on this, but I've found that threads hog the
>> CPU even when idle.
>>
>> The way that has worked well for me is to have the render thread, and
>> the logic timer.
>>
>> (using a looper and communicating via a handler can be slow, from my
>> experience locks are faster)
>>
>> To keep things simply I use a TimerTask to simulate a 60fps game logic
>> rate (game_loop_timer.schedule(game_loop_task, 0, 17);).  The game
>> logic rate can vary based on what needs to be done.  (i.e pathfinding,
>> network syncing, etc.) and sets a scene to the buffer.
>>
>> The render thread stays constant by simply drawing what's on the scene
>> buffer at every onDraw.
>>
>> I use a single lock to keep the scene buffer safe between the two threads.
>>
>> It's actually pretty simple, and I only really need two classes.
>>
>> I highly recommend reading articles about this, here are some of my 
>> bookmarks:http://gafferongames.com/game-physics/fix-your-timestep/http://stackoverflow.com/questions/87304/calculating-frames-per-secon...
>>
>> For input, I use a lock for the state of the hardware.  (i.e. when the
>> screen is being touched, I set a boolean isTouched to true and use a
>> lock to safely read/write from the threads.  However, a queue/handler
>> is really the way to go when it comes to that since it's not as
>> time/latency sensitive.
>>
>>
>>
>> On Fri, Apr 9, 2010 at 6:29 PM, Lance Nanek <lna...@gmail.com> wrote:
>> > There are a lot of built in classes in Android and Java that you can
>> > use to avoid having to write any synchronization or lock code
>> > yourself. In my case GLSurfaceView sets up my render thread. I use
>> > HandlerThread for my game thread. The game thread sends an update
>> > object detailing all the draw commands needed for a frame to the
>> > render thread via a BlockingQueue. The render thread returns it via
>> > the game thread's Handler. The UI thread tells the game thread about
>> > input via the game thread's Handler as well. These classes are in the
>> > android.os and java.util.concurrent packages.
>>
>> > On Apr 9, 6:36 pm, Eddie Ringle <ed...@eringle.net> wrote:
>> >> Okay, I figured I could just pass the Activity through parameters, but
>> >> wanted to know if a better way was possible.
>> >> Thanks for all the help everyone.
>>
>> >> On Apr 9, 5:56 pm, Mario Zechner <badlogicga...@gmail.com> wrote:
>>
>> >> > That depends on what kind of input you need. If your game is happy
>> >> > with just checking the current state of the accelerometer/touch screen/
>> >> > keyboard/trackball simply polling will do the trick. This means that
>> >> > in the UI thread, where you have your event listeners installed, you
>> >> > simply save the last state reported to you. In your logic thread you
>> >> > can savely access this state even without synchronization as it will
>> >> > only be composed of plain old data types like booleans or ints (of
>> >> > course there are cases where you catch the x coordinate of the
>> >> > previous event and the y coordinate of the current event but i dare
>> >> > say that the differences are so tiny, it doesn't make a difference).
>>
>> >> > Other things might need event based input handling, like a GUI you
>> >> > implement yourself with say OpenGL. In that case you will need a queue
>> >> > that gets filled in the Android GUI thread by the listeners you have
>> >> > installed for the input devices. The logic thread acts as a consumer
>> >> > and takes the events from the queue. As you are working with a complex
>> >> > data structure you need to synchronize the adding and removing of
>> >> > events to and from the queue in both the Android GUI thread and your
>> >> > logic thread. This is a classical consumer/producer pattern which can
>> >> > be found frequently in multithreaded applications. Check out Robert's
>> >> > site athttp://www.rbgrn.net, i think he wrote an article on that sort
>> >> > of thing once.
>>
>> >> > it basicaly boils down to this (pseudo code, written from the top of
>> >> > my head, will not compile)
>>
>> >> > public class GameActivity extends Activity implements
>> >> > MotionEventListener
>> >> > {
>> >> >    Queue<Event> events = new Queue<Event>();
>>
>> >> >    public void onTouch( MotionEvent event )
>> >> >    {
>> >> >       synchronized( events )
>> >> >       {
>> >> >          events.add( new Event( event.getX(), event.getY() );
>> >> >       }
>> >> >    }
>>
>> >> > }
>>
>> >> > public class GameLogic
>> >> > {
>> >> >    GameActivity activity;
>>
>> >> >     public GameLogic( GameActivity activity )
>> >> >     {
>> >> >        this.activity = activity;
>> >> >     }
>>
>> >> >     public void handleInput( )
>> >> >     {
>> >> >         synchronized( gameActivity.events )
>> >> >         {
>> >> >             // proces events here
>> >> >         }
>> >> >     }
>>
>> >> > }
>>
>> >> > Now, a couple of comments: You don't want to instantiate a new Event
>> >> > everytime a listener method in the GameActivity is called. You will
>> >> > need to implement a simple object pool and reuse events. That way the
>> >> > garbage collector will stay calm. Also note that the design above is a
>> >> > bit nasty, i would directly pass the GameActivity to the GameLogic
>> >> > among other things. But that's up to you.
>>
>> >> > Polling input handling would work like above but without a queue and
>> >> > without the need for the synchronized blocks. All you do is set some
>> >> > members of GameActivity, say touchX and touchY in the onTouch method
>> >> > and read those values in the GameLogic class' handleInput method.
>>
>> >> > hth,
>> >> > Mario
>>
>> >> > On 9 Apr., 22:39, Eddie Ringle <ed...@eringle.net> wrote:
>>
>> >> > > Robert,
>>
>> >> > > Silly question, but how do you get input to the logic thread? I have
>> >> > > to get sensor and touch data from the main Activity class and somehow
>> >> > > get it to the logic thread.
>>
>> >> > > Current program flow is as follows:
>> >> > > onCreate() -> GameView() -> World() & Renderer() & GameLogic()
>>
>> >> > > On Apr 9, 3:24 pm, Robert Green <rbgrn....@gmail.com> wrote:
>>
>> >> > > > Eddie,
>>
>> >> > > > Yes, that'll do the trick.
>>
>> >> > > > As far as the multiple threads goes, sure you can drive your logic 
>> >> > > > off
>> >> > > > of the call to onDrawFrame but there is a situation in which having 
>> >> > > > a
>> >> > > > separate thread makes sense:
>>
>> >> > > > After onDrawFrame, the rendering thread is finishing/swapping.  That
>> >> > > > can actually take a decent amount of time to do in certain cases and
>> >> > > > most of it is happening on the GPU, especially on a device like the
>> >> > > > Droid which has a discrete CPU/GPU.  During that time, the CPU is
>> >> > > > available and can be used on the logic thread.  Properly 
>> >> > > > implemented,
>> >> > > > in a heavy scene you can get some or all of the logic processed 
>> >> > > > before
>> >> > > > the rendering thread is ready again, which is why I favor it.
>>
>> >> > > > My question is:  onDrawFrame is only called once the GPU is ready 
>> >> > > > for
>> >> > > > another draw.  Why waste those precious GPU idle moments just doing
>> >> > > > CPU stuff like physics and collisions?  You can maximize with 
>> >> > > > another
>> >> > > > thread.
>>
>> >> > > > Also - 2 (game and UI) or 3 threads (game logic, rendering and UI)
>> >> > > > does make sense because you never want to block the UI thread in
>> >> > > > Android.  Get out of its way as fast as possible!  :)
>>
>> >> > > > On Apr 9, 1:58 pm, Eddie Ringle <ed...@eringle.net> wrote:
>>
>> >> > > > > Is it as simple as:
>>
>> >> > > > > In GameView.java (my custom GLSurfaceView class):
>> >> > > > > World _world = new World();
>>
>> >> > > > > GameRenderer _renderer = new GameRenderer(_world);
>>
>> >> > > > > In GameRenderer.java:
>> >> > > > > public World _world;
>>
>> >> > > > > public GameRenderer(World world)
>> >> > > > > {
>> >> > > > >     _world = world;
>>
>> >> > > > > }
>>
>> >> > > > > In GameRenderer.java, _world would now have the address of world,
>> >> > > > > which is the address of GameView.java's _world, right?
>>
>> >> > > > > On Apr 9, 2:49 pm, Eddie Ringle <ed...@eringle.net> wrote:
>>
>> >> > > > > > One more thing question and I think I will be set. Coming from 
>> >> > > > > > a C/C++
>> >> > > > > > background, I enjoyed the use of references. I know that there 
>> >> > > > > > is a
>> >> > > > > > way to pass the reference by value in Java, but am not quite 
>> >> > > > > > clear on
>> >> > > > > > how. Could I, for example, create my World object, then pass 
>> >> > > > > > that
>> >> > > > > > object to the renderer and logic objects when I create them? I 
>> >> > > > > > did a
>> >> > > > > > small bit of reading on this topic, but still am not quite sure.
>>
>> >> > > > > > On Apr 9, 1:55 pm, Robert Green <rbgrn....@gmail.com> wrote:
>>
>> >> > > > > > > Yeah, you're going to want to model your game like you would 
>> >> > > > > > > model the
>> >> > > > > > > real world:
>>
>> >> > > > > > > class World {
>> >> > > > > > >   public Player player;
>> >> > > > > > >   public Enemy[] enemies;
>> >> > > > > > >   public int timeLeft;
>> >> > > > > > >   public int level;
>> >> > > > > > >   //etc..
>>
>> >> > > > > > > }
>>
>> >> > > > > > > Then you update the world (usually by calls to player.update,
>> >> > > > > > > enemy.update, etc) from your logic thread.
>>
>> >> > > > > > > Then what I like to do is separate the rendering stuff from 
>> >> > > > > > > the
>> >> > > > > > > simulation so that I have renderers for specific things:
>>
>> >> > > > > > > class PlayerRenderer extends BaseRenderer {
>> >> > > > > > >   // knows about player geometry, knows how to draw the 
>> >> > > > > > > player and
>> >> > > > > > > anything player-related..
>>
>> >> > > > > > > }
>>
>> >> > > > > > > Then in my main Renderer, I just call out to the individual 
>> >> > > > > > > component
>> >> > > > > > > renderers:
>>
>> >> > > > > > > class WorldRenderer implements Renderer {
>> >> > > > > > >   onDrawFrame(GL gl) {
>> >> > > > > > >     // clear, set up projection, etc
>> >> > > > > > >     playerRenderer.draw(gl, world.player);
>> >> > > > > > >     enemyRenderer.draw(gl, world.enemies);
>> >> > > > > > >     // etc..
>> >> > > > > > >   }
>>
>> >> > > > > > > }
>>
>> >> > > > > > > And that's how I do it.  I have just a little bit of 
>> >> > > > > > > initialization
>> >> > > > > > > communication from the Renderer side to the game logic so 
>> >> > > > > > > that we can
>> >> > > > > > > set up positioning of touchable UI components but otherwise 
>> >> > > > > > > it's
>> >> > > > > > > always GameThread updates World, WorldRenderer
>>
>> ...
>>
>> read more »
>
> --
> You received this message because you are subscribed to the Google
> Groups "Android Developers" group.
> To post to this group, send email to android-developers@googlegroups.com
> To unsubscribe from this group, send email to
> android-developers+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/android-developers?hl=en
>
> To unsubscribe, reply using "remove me" as the subject.
>



-- 
http://diastrofunk.com, http://developingthedream.blogspot.com/,
http://www.youtube.com/user/revoltingx, ~Isaiah 55:8-9

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to