com.googlecode.gwtquake.client.GwtResourceLoaderImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.googlecode.gwtquake.client.GwtResourceLoaderImpl.java

Source

/*
Copyright (C) 2010 Copyright 2010 Google Inc.
    
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
See the GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package com.googlecode.gwtquake.client;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;

import com.google.gwt.core.client.Duration;
import com.google.gwt.user.client.Timer;
import com.google.gwt.xhr.client.ReadyStateChangeHandler;
import com.google.gwt.xhr.client.XMLHttpRequest;
import com.googlecode.gwtquake.shared.common.Com;
import com.googlecode.gwtquake.shared.common.Compatibility;
import com.googlecode.gwtquake.shared.common.ResourceLoader;
import com.googlecode.gwtquake.shared.util.StringToByteBuffer;

public class GwtResourceLoaderImpl implements ResourceLoader.Impl {

    private static final int RECEIVED_WAIT_TIME = 1;

    private int freeSequenceNumber;
    private int ignoreSequenceNumbersBelow;
    private int currentSequenceNumber;
    private ArrayList<ResponseHandler> readyList = new ArrayList<ResponseHandler>();

    static class ResponseHandler {
        int sequenceNumber;
        ResourceLoader.Callback callback;
        String response;

        ResponseHandler(int sequenceNumber, ResourceLoader.Callback callback, String response) {
            this.sequenceNumber = sequenceNumber;
            this.callback = callback;
            this.response = response;
        }
    }

    private static StringToByteBuffer sbb = (StringToByteBuffer) (Object) ByteBuffer.allocate(1);

    public boolean pump() {
        return currentSequenceNumber != freeSequenceNumber;
    }

    public void reset() {
        ignoreSequenceNumbersBelow = freeSequenceNumber;
        currentSequenceNumber = freeSequenceNumber;
    }

    public void loadResourceAsync(final String path, final ResourceLoader.Callback callback) {
        XMLHttpRequest req = XMLHttpRequest.create();

        final Exception e = new Exception();
        final int mySequenceNumber = freeSequenceNumber++;

        req.setOnReadyStateChange(new ReadyStateChangeHandler() {
            boolean receivingMsg;

            public void onReadyStateChange(final XMLHttpRequest xhr) {
                if (xhr.getReadyState() == 3 && !receivingMsg) {
                    Com.Printf("Receiving #" + mySequenceNumber + ": " + path + "\n");
                    receivingMsg = true;
                } else if (xhr.getReadyState() == 4) {
                    if (mySequenceNumber < ignoreSequenceNumbersBelow) {
                        Com.Printf("Ignoring outdated response #" + mySequenceNumber + ": " + path + "\n");
                    } else {
                        String response;
                        if (xhr.getStatus() != 200) {
                            Com.Printf("Failed to load file #" + mySequenceNumber + ": " + path + " status: "
                                    + xhr.getStatus() + "/" + xhr.getStatusText() + "\n");
                            ResourceLoader.fail(new IOException("status = " + xhr.getStatus()));
                            response = null;
                        } else {
                            response = xhr.getResponseText();
                            Com.Printf("Received response #" + mySequenceNumber + ": " + path + "\r");
                        }
                        readyList.add(0, new ResponseHandler(mySequenceNumber, callback, response));
                        if (mySequenceNumber == currentSequenceNumber) {
                            processReadyList();
                        }
                    }
                }
            }
        });

        Com.Printf("Requesting: " + path + "\n");

        overrideMimeType(req, "text/plain; charset=x-user-defined");
        req.open("GET", "/baseq2/" + path);
        req.send();
    }

    private native void overrideMimeType(XMLHttpRequest req, String mimeType) /*-{
                                                                              req.overrideMimeType(mimeType);
                                                                              }-*/;

    private void processReadyList() {
        new Timer() {
            @Override
            public void run() {
                for (int i = readyList.size() - 1; i >= 0; i--) {
                    ResponseHandler handler = readyList.get(i);
                    if (handler.sequenceNumber == currentSequenceNumber) {
                        if (handler.response != null) {
                            double t0 = Duration.currentTimeMillis();
                            handler.callback.onSuccess(sbb.stringToByteBuffer(handler.response));
                            Com.Printf("Processed #" + currentSequenceNumber + " in "
                                    + (Duration.currentTimeMillis() - t0) / 1000.0 + "s\r");
                        }
                        readyList.remove(i);
                        currentSequenceNumber++;
                        processReadyList();
                        return;
                    }
                }
            }
        }.schedule(RECEIVED_WAIT_TIME);
    }
}