summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjetil Ørbekk <kjetil.orbekk@gmail.com>2012-02-27 18:16:37 +0100
committerKjetil Ørbekk <kjetil.orbekk@gmail.com>2012-02-27 18:16:37 +0100
commitbc2d8fa1da02037d0b9a2361f394f19e494c8cec (patch)
tree3ac5f8f2af6f528e6c0cab51b95837ecffb8fc2d
parentf7d27ef6204bd7ea96c657fa5399db8e16cb8705 (diff)
Use DelayedOperation on Android.
BUGZ
-rw-r--r--same-android/src/main/java/com/orbekk/same/GameView.java13
-rw-r--r--same-android/src/main/java/com/orbekk/same/SameService.java58
-rw-r--r--same-android/src/main/java/com/orbekk/same/VariableTestActivity.java12
-rw-r--r--same-android/src/main/java/com/orbekk/same/android/ClientInterfaceBridge.java76
4 files changed, 110 insertions, 49 deletions
diff --git a/same-android/src/main/java/com/orbekk/same/GameView.java b/same-android/src/main/java/com/orbekk/same/GameView.java
index 527d3da..d9a8052 100644
--- a/same-android/src/main/java/com/orbekk/same/GameView.java
+++ b/same-android/src/main/java/com/orbekk/same/GameView.java
@@ -51,11 +51,7 @@ public class GameView extends SurfaceView implements SurfaceHolder.Callback {
player_.posX = 0.5f;
player_.posY = 0.5f;
player.setOnChangeListener(this);
- try {
- player.set(player_);
- } catch (UpdateConflict e) {
- e.printStackTrace();
- }
+ player.set(player_);
}
public void setSize(int width, int height) {
@@ -91,12 +87,7 @@ public class GameView extends SurfaceView implements SurfaceHolder.Callback {
Player newPlayer = new Player();
newPlayer.posX = x / width;
newPlayer.posY = y / width;
- try {
- player.set(newPlayer);
- } catch (UpdateConflict e) {
- Toast.makeText(context, "Failed to update position.",
- Toast.LENGTH_SHORT).show();
- }
+ player.set(newPlayer);
}
@Override
diff --git a/same-android/src/main/java/com/orbekk/same/SameService.java b/same-android/src/main/java/com/orbekk/same/SameService.java
index 66406bd..3a487d0 100644
--- a/same-android/src/main/java/com/orbekk/same/SameService.java
+++ b/same-android/src/main/java/com/orbekk/same/SameService.java
@@ -20,16 +20,28 @@ import com.orbekk.same.State.Component;
import com.orbekk.same.android.net.AndroidBroadcasterFactory;
import com.orbekk.same.android.net.Broadcaster;
import com.orbekk.same.config.Configuration;
+import com.orbekk.util.DelayedOperation;
public class SameService extends Service {
public final static int DISPLAY_MESSAGE = 1;
public final static int SEARCH_NETWORKS = 2;
public final static int CREATE_NETWORK = 3;
public final static int JOIN_NETWORK = 4;
- public final static int UPDATED_STATE_MESSAGE = 5;
- public final static int ADD_STATE_RECEIVER = 6;
- public final static int REMOVE_STATE_RECEIVER = 7;
- public final static int SET_STATE = 8;
+ public final static int ADD_STATE_RECEIVER = 5;
+ public final static int REMOVE_STATE_RECEIVER = 6;
+
+ /**
+ * arg1: Operation number.
+ * obj: Updated component.
+ */
+ public final static int SET_STATE = 7;
+ public final static int UPDATED_STATE_CALLBACK = 8;
+
+ /**
+ * arg1: Operation number.
+ * obj: Operation status.
+ */
+ public final static int OPERATION_STATUS_CALLBACK = 9;
// TODO: Remove these and use messengers instead of broadcast intents.
public final static String AVAILABLE_NETWORKS_UPDATE =
@@ -113,19 +125,21 @@ public class SameService extends Service {
stateReceivers.remove(droppedMessenger);
break;
case SET_STATE:
- // TODO: We may get errors here and we need to inform the
- // caller. Perhaps combine with some sort of callback.
+ logger.info("SET_STATE: oId: {}, comp: {}", message.arg1, message.obj);
State.Component updatedComponent =
(State.Component)message.obj;
- try {
- sameController.getClient().getInterface().set(
- updatedComponent);
- } catch (UpdateConflict e) {
- logger.info("Update failed: {}", updatedComponent);
- }
+ int id = message.arg1;
+ logger.info("Running operation.");
+ DelayedOperation op = sameController.getClient().getInterface()
+ .set(updatedComponent);
+ logger.info("Operation finished. Sending callback.");
+ operationStatusCallback(op, id, message.replyTo);
+ logger.info("Callback sent.");
+ break;
default:
super.handleMessage(message);
}
+ logger.info("Finished handling message.");
}
}
@@ -137,7 +151,7 @@ public class SameService extends Service {
synchronized (stateReceivers) {
ArrayList<Messenger> dropped = new ArrayList<Messenger>();
for (Messenger messenger : stateReceivers) {
- Message message = Message.obtain(null, UPDATED_STATE_MESSAGE);
+ Message message = Message.obtain(null, UPDATED_STATE_CALLBACK);
message.obj = component;
try {
messenger.send(message);
@@ -152,10 +166,26 @@ public class SameService extends Service {
}
};
+ private void operationStatusCallback(DelayedOperation op, int id, Messenger replyTo) {
+ op.waitFor();
+ synchronized (stateReceivers) {
+ Message message = Message.obtain(null,
+ OPERATION_STATUS_CALLBACK, id);
+ message.obj = op.getStatus();
+ try {
+ messenger.send(message);
+ } catch (RemoteException e) {
+ logger.warn("Unable to send update result: " +
+ op.getStatus());
+ e.printStackTrace();
+ }
+ }
+ }
+
private void sendAllState(Messenger messenger) {
State state = sameController.getClient().getInterface().getState();
for (Component c : state.getComponents()) {
- Message message = Message.obtain(null, UPDATED_STATE_MESSAGE);
+ Message message = Message.obtain(null, UPDATED_STATE_CALLBACK);
message.obj = c;
try {
messenger.send(message);
diff --git a/same-android/src/main/java/com/orbekk/same/VariableTestActivity.java b/same-android/src/main/java/com/orbekk/same/VariableTestActivity.java
index ba33058..1fffbad 100644
--- a/same-android/src/main/java/com/orbekk/same/VariableTestActivity.java
+++ b/same-android/src/main/java/com/orbekk/same/VariableTestActivity.java
@@ -11,6 +11,7 @@ import android.widget.TextView;
import android.widget.Toast;
import com.orbekk.same.android.ClientInterfaceBridge;
+import com.orbekk.util.DelayedOperation;
public class VariableTestActivity extends Activity {
private Logger logger = LoggerFactory.getLogger(getClass());
@@ -36,12 +37,13 @@ public class VariableTestActivity extends Activity {
public void setVariable(View unused) {
EditText et = (EditText)findViewById(R.id.set_variable_text);
String newValue = et.getText().toString();
- try {
- variable.set(newValue);
- } catch (UpdateConflict e) {
- Toast.makeText(this, "Failed to update.", Toast.LENGTH_SHORT)
+ logger.info("Setting variable.");
+ DelayedOperation op = variable.set(newValue);
+ logger.info("Waiting for delayed operation.");
+ if (!op.getStatus().isOk()) {
+ Toast.makeText(this, "Failed to update: " + op.getStatus(),
+ Toast.LENGTH_SHORT)
.show();
- e.printStackTrace();
}
}
diff --git a/same-android/src/main/java/com/orbekk/same/android/ClientInterfaceBridge.java b/same-android/src/main/java/com/orbekk/same/android/ClientInterfaceBridge.java
index 4dde60c..3b490bc 100644
--- a/same-android/src/main/java/com/orbekk/same/android/ClientInterfaceBridge.java
+++ b/same-android/src/main/java/com/orbekk/same/android/ClientInterfaceBridge.java
@@ -1,6 +1,8 @@
package com.orbekk.same.android;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -22,11 +24,15 @@ import com.orbekk.same.State.Component;
import com.orbekk.same.StateChangedListener;
import com.orbekk.same.UpdateConflict;
import com.orbekk.same.VariableFactory;
+import com.orbekk.util.DelayedOperation;
public class ClientInterfaceBridge implements ClientInterface {
private State state;
private ArrayList<StateChangedListener> listeners =
new ArrayList<StateChangedListener>();
+ private Map<Integer, DelayedOperation> ongoingOperations =
+ new HashMap<Integer, DelayedOperation>();
+ private int nextOperationNumber = 0;
class ResponseHandler extends Handler {
@Override public void handleMessage(Message message) {
@@ -35,10 +41,16 @@ public class ClientInterfaceBridge implements ClientInterface {
return;
}
switch (message.what) {
- case SameService.UPDATED_STATE_MESSAGE:
+ case SameService.UPDATED_STATE_CALLBACK:
State.Component component = (State.Component)message.obj;
updateState(component);
break;
+ case SameService.OPERATION_STATUS_CALLBACK:
+ int operationNumber = message.arg1;
+ DelayedOperation.Status status =
+ (DelayedOperation.Status)message.obj;
+ completeOperation(operationNumber, status);
+ break;
default:
logger.warn("Received unknown message from service: {}",
message);
@@ -54,14 +66,16 @@ public class ClientInterfaceBridge implements ClientInterface {
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
- serviceMessenger = new Messenger(service);
- Message message = Message.obtain(null,
- SameService.ADD_STATE_RECEIVER);
- message.replyTo = responseMessenger;
- try {
- serviceMessenger.send(message);
- } catch (RemoteException e) {
- e.printStackTrace();
+ synchronized (ClientInterfaceBridge.this) {
+ serviceMessenger = new Messenger(service);
+ Message message = Message.obtain(null,
+ SameService.ADD_STATE_RECEIVER);
+ message.replyTo = responseMessenger;
+ try {
+ serviceMessenger.send(message);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
}
}
@@ -79,6 +93,22 @@ public class ClientInterfaceBridge implements ClientInterface {
}
}
+ private synchronized DelayedOperation createOperation() {
+ DelayedOperation op = new DelayedOperation();
+ op.setIdentifier(nextOperationNumber);
+ nextOperationNumber += 1;
+ ongoingOperations.put(op.getIdentifier(), op);
+ return op;
+ }
+
+ private synchronized void completeOperation(int operationNumber,
+ DelayedOperation.Status status) {
+ DelayedOperation op = ongoingOperations.remove(operationNumber);
+ if (op != null) {
+ op.complete(status);
+ }
+ }
+
public ClientInterfaceBridge(Context context) {
this.context = context;
}
@@ -113,24 +143,32 @@ public class ClientInterfaceBridge implements ClientInterface {
}
@Override
- public void set(String name, String data, long revision) throws UpdateConflict {
- set(new Component(name, revision, data));
- }
-
- @Override
- public void set(Component component) throws UpdateConflict {
- Message message = Message.obtain(null, SameService.SET_STATE);
- message.obj = component;
+ public DelayedOperation set(Component component) {
+ DelayedOperation op = createOperation();
if (serviceMessenger == null) {
logger.warn("Not connected to service. Ignore update: {}", component);
- return;
+ completeOperation(op.getIdentifier(),
+ DelayedOperation.Status.createError(
+ "Not connected to service."));
+ return op;
}
+
+ Message message = Message.obtain(null, SameService.SET_STATE,
+ op.getIdentifier());
+ // this has to be Parcelable.
+// message.obj = component;
+ message.replyTo = responseMessenger;
try {
+ logger.info("Sending update to service.");
serviceMessenger.send(message);
+ logger.info("Service finished update.");
} catch (RemoteException e) {
e.printStackTrace();
- throw new UpdateConflict(e.getMessage());
+ completeOperation(op.getIdentifier(),
+ DelayedOperation.Status.createError(
+ "Error contacting service: " + e.getMessage()));
}
+ return op;
}
@Override