Implement support for enum/callback arguments.
This commit is contained in:
parent
4ecd4936bd
commit
75421d4c95
@ -47,10 +47,10 @@ public class ProgramakerBridgeService extends Service {
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
setBridgeStatusNotification(getString(R.string.bridge_service_not_started), ServiceState.LOADING);
|
||||
setBridgeStatusNotification(getString(R.string.bridge_service_not_started), ServiceState.LOADING, null);
|
||||
}
|
||||
|
||||
private void setBridgeStatusNotification(String title, ServiceState state) {
|
||||
private void setBridgeStatusNotification(String title, ServiceState state, String description) {
|
||||
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
assert notificationManager != null;
|
||||
|
||||
@ -94,6 +94,10 @@ public class ProgramakerBridgeService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
if (description != null) {
|
||||
builder.setContentText(description);
|
||||
}
|
||||
|
||||
Notification notification = builder.build();
|
||||
|
||||
if (stopped) {
|
||||
@ -164,7 +168,7 @@ public class ProgramakerBridgeService extends Service {
|
||||
bridgeId);
|
||||
ProgramakerBridgeService.this.bridge.start(
|
||||
() -> { // On ready
|
||||
setBridgeStatusNotification(getString(R.string.bridge_service_online), ServiceState.RUNNING);
|
||||
setBridgeStatusNotification(getString(R.string.bridge_service_online), ServiceState.RUNNING, null);
|
||||
if (config.getBridgeConnectionId() == null) {
|
||||
new DoAsync().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
|
||||
new Tuple2<>(
|
||||
@ -183,25 +187,29 @@ public class ProgramakerBridgeService extends Service {
|
||||
}
|
||||
},
|
||||
() -> { // On completed
|
||||
ProgramakerBridgeService.this.bridge = null;
|
||||
onBridgeFailedAfterConnected();
|
||||
});
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
Log.e(LogTag, "Error on bridge", ex);
|
||||
ProgramakerBridgeService.this.bridge = null;
|
||||
setBridgeStatusNotification(getString(R.string.bridge_service_starting),
|
||||
ServiceState.STOPPED,
|
||||
getString(R.string.error_establishing_connection));
|
||||
}
|
||||
}, "ServiceStartArguments");
|
||||
thread.setPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
||||
|
||||
setBridgeStatusNotification(getString(R.string.bridge_service_starting), ServiceState.LOADING);
|
||||
setBridgeStatusNotification(getString(R.string.bridge_service_starting), ServiceState.LOADING, null);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
private void onBridgeFailedAfterConnected() {
|
||||
ProgramakerBridgeService.this.bridge = null;
|
||||
|
||||
if (!stopped) {
|
||||
Log.e(LogTag, "Bridge stopped after connected. Waiting 10s then restarting");
|
||||
setBridgeStatusNotification(getString(R.string.bridge_service_failed_restarting), ServiceState.LOADING);
|
||||
setBridgeStatusNotification(getString(R.string.bridge_service_failed_restarting), ServiceState.LOADING, null);
|
||||
try {
|
||||
Thread.sleep(WAIT_TIME_BEFORE_RESTART_MILLIS);
|
||||
} catch (InterruptedException e) {
|
||||
@ -224,6 +232,6 @@ public class ProgramakerBridgeService extends Service {
|
||||
if (bridge != null) {
|
||||
bridge.stop();
|
||||
}
|
||||
setBridgeStatusNotification(getString(R.string.bridge_service_failed_stopping), ServiceState.STOPPED);
|
||||
setBridgeStatusNotification(getString(R.string.bridge_service_failed_stopping), ServiceState.STOPPED, null);
|
||||
}
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ public class ProgramakerCustomBlockPart implements Part, ProgramakerSignalListen
|
||||
savedTo = arg;
|
||||
}
|
||||
else {
|
||||
ConnectorTypeInfo typeInfo = ConnectorTypeInfo.FromTypeName(arg.getType());
|
||||
ConnectorTypeInfo typeInfo = ConnectorTypeInfo.FromArgument(arg);
|
||||
inputs.add(new Tuple2<>(typeInfo,
|
||||
new ProgramakerCustomBlockInputConnector(this, _partGrid,
|
||||
0, 0,
|
||||
@ -199,7 +199,7 @@ public class ProgramakerCustomBlockPart implements Part, ProgramakerSignalListen
|
||||
Tuple2<ConnectorTypeInfo, AnyRoundOutputConnector> saveToOutput = null;
|
||||
|
||||
if (savedTo != null) {
|
||||
saveToOutput = new Tuple2<>(ConnectorTypeInfo.FromTypeName(savedTo.getType()),
|
||||
saveToOutput = new Tuple2<>(ConnectorTypeInfo.FromTypeName(savedTo.getComputedType()),
|
||||
new AnyRoundOutputConnector(this, this._partGrid, 0, 0, IO_RADIUS));
|
||||
outputs.add(new Tuple2<>(saveToOutput.item1, saveToOutput.item2));
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.codigoparallevar.minicards.parts.connectors;
|
||||
|
||||
import com.codigoparallevar.minicards.parts.style.CardTheme;
|
||||
import com.programaker.api.data.ProgramakerCustomBlockArgument;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@ -8,6 +9,9 @@ import org.json.JSONObject;
|
||||
public class ConnectorTypeInfo {
|
||||
private final Type _type;
|
||||
private static final String SERIALIZED_TYPE_KEY = "type";
|
||||
private static final String SERIALIZED_ARGUMENT_KEY = "argument";
|
||||
|
||||
private ProgramakerCustomBlockArgument _blockArgument = null;
|
||||
|
||||
public static ConnectorTypeInfo FromTypeName(String type) {
|
||||
if (type == null) {
|
||||
@ -66,7 +70,20 @@ public class ConnectorTypeInfo {
|
||||
}
|
||||
|
||||
public static ConnectorTypeInfo deserialize(JSONObject jsonTypeInfo) {
|
||||
return ConnectorTypeInfo.FromTypeName(jsonTypeInfo.optString(SERIALIZED_TYPE_KEY));
|
||||
ConnectorTypeInfo type = ConnectorTypeInfo.FromTypeName(jsonTypeInfo.optString(SERIALIZED_TYPE_KEY));
|
||||
|
||||
JSONObject arg = jsonTypeInfo.optJSONObject(SERIALIZED_ARGUMENT_KEY);
|
||||
if (arg != null) {
|
||||
type._blockArgument = ProgramakerCustomBlockArgument.deserialize(arg);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
public static ConnectorTypeInfo FromArgument(ProgramakerCustomBlockArgument arg) {
|
||||
ConnectorTypeInfo type = ConnectorTypeInfo.FromTypeName(arg.getComputedType());
|
||||
type._blockArgument = arg;
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getOuterColor() {
|
||||
@ -120,12 +137,20 @@ public class ConnectorTypeInfo {
|
||||
JSONObject obj = new JSONObject();
|
||||
try {
|
||||
obj.put(SERIALIZED_TYPE_KEY, ConnectorTypeInfo.typeToString(this._type));
|
||||
|
||||
if (_blockArgument != null) {
|
||||
obj.put(SERIALIZED_ARGUMENT_KEY, _blockArgument.serialize());
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
public ProgramakerCustomBlockArgument getBlockArgument() {
|
||||
return _blockArgument;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
PULSE,
|
||||
BOOLEAN,
|
||||
|
@ -1,14 +1,18 @@
|
||||
package com.codigoparallevar.minicards.parts.values;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.codigoparallevar.minicards.R;
|
||||
import com.codigoparallevar.minicards.ScrolledCanvas;
|
||||
@ -21,8 +25,14 @@ import com.codigoparallevar.minicards.types.PartGrid;
|
||||
import com.codigoparallevar.minicards.types.connectors.Wiring.AnyWire;
|
||||
import com.codigoparallevar.minicards.types.connectors.input.InputConnector;
|
||||
import com.codigoparallevar.minicards.types.connectors.output.OutputConnector;
|
||||
import com.codigoparallevar.minicards.types.functional.Consumer;
|
||||
import com.codigoparallevar.minicards.types.functional.Tuple2;
|
||||
import com.codigoparallevar.minicards.types.functional.Tuple3;
|
||||
import com.codigoparallevar.minicards.types.wireData.WireDataType;
|
||||
import com.codigoparallevar.minicards.ui_helpers.GetAsync;
|
||||
import com.codigoparallevar.minicards.utils.Serializations;
|
||||
import com.programaker.api.data.ProgramakerCustomBlockArgument;
|
||||
import com.programaker.api.data.ProgramakerCustomBlockArgumentValue;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
@ -51,12 +61,14 @@ public class StaticValuePart implements Part {
|
||||
private int _left;
|
||||
private int _top;
|
||||
private String _value = null;
|
||||
private String _valueId = null;
|
||||
|
||||
public StaticValuePart(String id, PartGrid grid, int centerx, int centery, ConnectorTypeInfo typeInfo, String value) {
|
||||
public StaticValuePart(String id, PartGrid grid, int centerx, int centery, ConnectorTypeInfo typeInfo, String value, String valueId) {
|
||||
this._id = id;
|
||||
this._typeInfo = typeInfo;
|
||||
this._grid = grid;
|
||||
this._value = value;
|
||||
this._valueId = valueId;
|
||||
|
||||
this.updateWidthHeight();
|
||||
|
||||
@ -66,6 +78,9 @@ public class StaticValuePart implements Part {
|
||||
this._left + _width / 2,
|
||||
this._top + _height, IO_RADIUS);
|
||||
}
|
||||
public StaticValuePart(String id, PartGrid grid, int centerx, int centery, ConnectorTypeInfo typeInfo, String value) {
|
||||
this(id, grid, centerx, centery, typeInfo, value, null);
|
||||
}
|
||||
|
||||
public StaticValuePart(String id, PartGrid grid, int centerx, int centery, ConnectorTypeInfo typeInfo) {
|
||||
this(id, grid, centerx, centery, typeInfo, null);
|
||||
@ -80,9 +95,10 @@ public class StaticValuePart implements Part {
|
||||
JSONObject serialized = new JSONObject();
|
||||
|
||||
serialized.put("id", _id);
|
||||
serialized.put("left", _left);
|
||||
serialized.put("top", _top);
|
||||
serialized.put("center_x", _left + _width / 2);
|
||||
serialized.put("center_y", _top + _height / 2);
|
||||
serialized.put("value", _value == null ? JSONObject.NULL : _value);
|
||||
serialized.put("value_id", _valueId == null ? JSONObject.NULL : _valueId);
|
||||
|
||||
JSONObject jsonTypeInfo = _typeInfo.serialize();
|
||||
serialized.put("type_info", jsonTypeInfo);
|
||||
@ -109,13 +125,14 @@ public class StaticValuePart implements Part {
|
||||
|
||||
public static Tuple2<Part, List<PartConnection>> deserialize(PartGrid grid, JSONObject data) throws JSONException {
|
||||
String id = data.getString("id");
|
||||
int left = data.getInt("left");
|
||||
int top = data.getInt("top");
|
||||
String value = data.optString("value");
|
||||
int centerx = data.getInt("center_x");
|
||||
int centery = data.getInt("center_y");
|
||||
String value = Serializations.getString(data, "value");
|
||||
String valueId = Serializations.getString(data, "value_id");
|
||||
|
||||
JSONObject jsonTypeInfo = data.getJSONObject("type_info");
|
||||
ConnectorTypeInfo typeInfo = ConnectorTypeInfo.deserialize(jsonTypeInfo);
|
||||
StaticValuePart part = new StaticValuePart(id, grid, left, top, typeInfo, value);
|
||||
StaticValuePart part = new StaticValuePart(id, grid, centerx, centery, typeInfo, value, valueId);
|
||||
|
||||
List<PartConnection> connections = new LinkedList<>();
|
||||
|
||||
@ -177,6 +194,14 @@ public class StaticValuePart implements Part {
|
||||
}
|
||||
|
||||
private String getMessage() {
|
||||
if (_value == null) {
|
||||
return "-";
|
||||
} else {
|
||||
return _value;
|
||||
}
|
||||
}
|
||||
|
||||
private String getMessageForEdit() {
|
||||
ConnectorTypeInfo.Type type = _typeInfo.get_type();
|
||||
if (type == ConnectorTypeInfo.Type.INTEGER || type == ConnectorTypeInfo.Type.FLOAT) {
|
||||
if (_value == null) {
|
||||
@ -192,10 +217,9 @@ public class StaticValuePart implements Part {
|
||||
}
|
||||
else {
|
||||
if (_value == null) {
|
||||
return "-";
|
||||
} else {
|
||||
return _value;
|
||||
return "";
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,52 +236,131 @@ public class StaticValuePart implements Part {
|
||||
return; // Can't show dialog if can't retrieve context
|
||||
}
|
||||
|
||||
final Context ctx = ((View) this._grid).getContext();
|
||||
ConnectorTypeInfo.Type type = this._typeInfo.get_type();
|
||||
if (type == ConnectorTypeInfo.Type.PULSE) {
|
||||
return; // Nothing to do here
|
||||
}
|
||||
|
||||
Context ctx = ((View) this._grid).getContext();
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
||||
|
||||
builder.setTitle(R.string.set_value);
|
||||
Runnable prepareOnAccept = () -> {};
|
||||
switch (type) {
|
||||
case BOOLEAN:
|
||||
break;
|
||||
case INTEGER:
|
||||
case FLOAT:
|
||||
{
|
||||
case FLOAT: {
|
||||
final EditText input = new EditText(ctx);
|
||||
|
||||
input.setText(getMessage());
|
||||
input.setText(getMessageForEdit());
|
||||
input.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
builder.setView(input);
|
||||
prepareOnAccept = () -> {
|
||||
_value = input.getText().toString();
|
||||
};
|
||||
|
||||
dialogAskUserForValue(ctx, input,
|
||||
() -> {
|
||||
_value = input.getText().toString();
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case ENUM:
|
||||
// TODO: Show enumerated values
|
||||
case ANY:
|
||||
case UNKNOWN:
|
||||
case STRING:
|
||||
{
|
||||
case STRING: {
|
||||
final EditText input = new EditText(ctx);
|
||||
|
||||
input.setText(getMessage());
|
||||
input.setText(getMessageForEdit());
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
builder.setView(input);
|
||||
prepareOnAccept = () -> {
|
||||
_value = input.getText().toString();
|
||||
};
|
||||
dialogAskUserForValue(ctx, input,
|
||||
() -> {
|
||||
_value = input.getText().toString();
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
case ENUM:
|
||||
ProgramakerCustomBlockArgument blockArg = _typeInfo.getBlockArgument();
|
||||
String callback = null;
|
||||
if (blockArg != null) {
|
||||
callback = blockArg.getCallback();
|
||||
if (callback.equals("null")) { // TODO: Fix this on server
|
||||
callback = null;
|
||||
}
|
||||
}
|
||||
|
||||
final Runnable onAccept = prepareOnAccept;
|
||||
if (callback == null) {
|
||||
new AlertDialog.Builder(ctx)
|
||||
.setMessage(R.string.error_recovering_allowed_values)
|
||||
.create()
|
||||
.show();
|
||||
break;
|
||||
}
|
||||
|
||||
Dialog loadingDialog = createLoadingDialog(ctx);
|
||||
loadingDialog.show();
|
||||
|
||||
new GetAsync<List<ProgramakerCustomBlockArgumentValue>>().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
|
||||
new Tuple3<>(
|
||||
() -> _grid.getApi().fetchAllowedValues(blockArg),
|
||||
results -> {
|
||||
Log.i(LogTag, "Result: " + results);
|
||||
loadingDialog.cancel();
|
||||
|
||||
String[] names = new String[results.size()];
|
||||
int i = 0;
|
||||
for (ProgramakerCustomBlockArgumentValue value : results) {
|
||||
names[i] = value.getName();
|
||||
i++;
|
||||
}
|
||||
|
||||
Dialog d = createItemDialog(ctx, names, idx -> {
|
||||
StaticValuePart.this._value = results.get(idx).getName();
|
||||
StaticValuePart.this._valueId = results.get(idx).getId();
|
||||
StaticValuePart.this._grid.update();
|
||||
});
|
||||
d.show();
|
||||
},
|
||||
ex -> {
|
||||
Log.e(LogTag, "Error retrieving values: " + ex, ex);
|
||||
new AlertDialog.Builder(ctx)
|
||||
.setMessage(R.string.error_recovering_allowed_values)
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private Dialog createItemDialog(Context ctx, CharSequence[] itemNames, Consumer<Integer> onSelected) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
||||
|
||||
builder.setTitle(R.string.loading_available_values);
|
||||
|
||||
final ProgressBar progressBar = new ProgressBar(ctx);
|
||||
progressBar.setIndeterminate(true);
|
||||
builder.setItems(itemNames, (DialogInterface.OnClickListener) (dialog, which) -> {
|
||||
try {
|
||||
onSelected.apply(which);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private Dialog createLoadingDialog(Context ctx) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
||||
|
||||
builder.setTitle(R.string.loading_available_values);
|
||||
|
||||
final ProgressBar progressBar = new ProgressBar(ctx);
|
||||
progressBar.setIndeterminate(true);
|
||||
builder.setView(progressBar);
|
||||
AlertDialog dialog = builder.create();
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private void dialogAskUserForValue(Context ctx, EditText input, Runnable onAccept) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
||||
|
||||
builder.setTitle(R.string.set_value);
|
||||
builder
|
||||
.setPositiveButton(R.string.ok_accept_changes, (dialog, which) -> {
|
||||
onAccept.run();
|
||||
@ -266,10 +369,12 @@ public class StaticValuePart implements Part {
|
||||
})
|
||||
.setNegativeButton(R.string.cancel_discard_changes, (dialog, which) -> {
|
||||
// No change
|
||||
} );
|
||||
})
|
||||
.setView(input);
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -321,6 +426,10 @@ public class StaticValuePart implements Part {
|
||||
|
||||
@Override
|
||||
public Object query(Object lastValue) {
|
||||
if (this._valueId != null) {
|
||||
return this._valueId;
|
||||
}
|
||||
|
||||
return this._value;
|
||||
}
|
||||
|
||||
|
@ -72,4 +72,18 @@ public class Serializations {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getString(JSONObject map, String key) {
|
||||
if (!map.has(key)) {
|
||||
return null;
|
||||
}
|
||||
if (map.opt(key) == JSONObject.NULL) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return map.getString(key);
|
||||
} catch (JSONException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,7 @@ import android.os.Build
|
||||
import android.util.Log
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.programaker.api.data.ProgramakerBridgeInfo
|
||||
import com.programaker.api.data.ProgramakerCustomBlock
|
||||
import com.programaker.api.data.ProgramakerFunctionCallResult
|
||||
import com.programaker.api.data.*
|
||||
import com.programaker.api.data.api_results.*
|
||||
import com.programaker.api.exceptions.ProgramakerLoginRequiredException
|
||||
import com.programaker.api.exceptions.ProgramakerProtocolException
|
||||
@ -138,6 +136,29 @@ class ProgramakerApi(private val ApiRoot: String="https://programaker.com/api")
|
||||
return result.result
|
||||
}
|
||||
|
||||
fun fetchAllowedValues(blockArg: ProgramakerCustomBlockArgument): List<ProgramakerCustomBlockArgumentValue>? {
|
||||
val conn = URL(getArgumentValuesUrl(blockArg)).openConnection() as HttpURLConnection
|
||||
|
||||
addAuthHeader(conn)
|
||||
|
||||
var results: List<ProgramakerCustomBlockArgumentValue>? = null
|
||||
try {
|
||||
val serialized: HashMap<String,*> = parseJson(conn.inputStream, HashMap::class.java)
|
||||
val returnInfo = ProgramakerCustomBlockArgumentValuesReturnInfo.deserialize(serialized)
|
||||
if (!returnInfo.success) {
|
||||
return null
|
||||
}
|
||||
results = returnInfo.values
|
||||
} catch (ex: FileNotFoundException) {
|
||||
ex.logError(LogTag)
|
||||
return null
|
||||
} catch(ex: Exception) {
|
||||
Log.e(LogTag, ex.toString(), ex)
|
||||
return null
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
fun callBlock(block: ProgramakerCustomBlock, arguments: List<String>): ProgramakerFunctionCallResult {
|
||||
val conn = URL(getBlockUrl(block)).openConnection() as HttpURLConnection
|
||||
conn.setRequestProperty("Content-Type", "application/json")
|
||||
@ -278,6 +299,11 @@ class ProgramakerApi(private val ApiRoot: String="https://programaker.com/api")
|
||||
return "$ApiRoot/v0/users/id/$userId/bridges/id/$bridgeId/signals/$key"
|
||||
}
|
||||
|
||||
private fun getArgumentValuesUrl(blockArg: ProgramakerCustomBlockArgument): String {
|
||||
this.withUserId()
|
||||
return "$ApiRoot/v0/users/id/$userId/bridges/id/${blockArg.bridge_id}/callback/${blockArg.callback}"
|
||||
}
|
||||
|
||||
fun getUserId(): String? {
|
||||
this.withUserId()
|
||||
return userId;
|
||||
|
@ -11,16 +11,28 @@ class ProgramakerCustomBlockArgument(
|
||||
// val class: String,
|
||||
val callback: String?
|
||||
) {
|
||||
var bridge_id: String? = null
|
||||
|
||||
fun serialize(): JSONObject {
|
||||
val serialized = hashMapOf<String, String?>(
|
||||
"type" to type,
|
||||
"default_value" to default_value,
|
||||
"callback" to callback
|
||||
"callback" to callback,
|
||||
"bridge_id" to bridge_id
|
||||
)
|
||||
|
||||
return JSONObject(serialized as Map<*, *>)
|
||||
}
|
||||
|
||||
fun getComputedType(): String? {
|
||||
if (callback != null && callback != "null") {
|
||||
return "ENUM";
|
||||
}
|
||||
else {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun deserialize(arguments: JSONArray?): List<ProgramakerCustomBlockArgument> {
|
||||
@ -45,12 +57,16 @@ class ProgramakerCustomBlockArgument(
|
||||
return results
|
||||
}
|
||||
|
||||
private fun deserialize(arguments: JSONObject): ProgramakerCustomBlockArgument {
|
||||
@JvmStatic
|
||||
fun deserialize(arguments: JSONObject): ProgramakerCustomBlockArgument {
|
||||
val type: String? = arguments.optString("type")
|
||||
val default_value: String? = arguments.optString("default_value")
|
||||
val callback: String? = arguments.optString("callback")
|
||||
val bridge_id: String? = arguments.optString("bridge_id")
|
||||
|
||||
return ProgramakerCustomBlockArgument(type, default_value, callback)
|
||||
val arg = ProgramakerCustomBlockArgument(type, default_value, callback)
|
||||
arg.bridge_id = bridge_id
|
||||
return arg
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,67 @@
|
||||
package com.programaker.api.data
|
||||
|
||||
import com.programaker.api.optGet
|
||||
import java.util.*
|
||||
|
||||
class ProgramakerCustomBlockArgumentValue (
|
||||
val id: String,
|
||||
val name: String
|
||||
) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun deserializeList(value: Object): List<ProgramakerCustomBlockArgumentValue> {
|
||||
if (value is Map<*, *>) {
|
||||
return deserialize(value as Map<*, *>)
|
||||
} else if (value is List<*>) {
|
||||
return deserialize(value as List<*>)
|
||||
} else {
|
||||
throw IllegalArgumentException("Error deserializing: $value")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deserialize(value: Map<*, *>): List<ProgramakerCustomBlockArgumentValue> {
|
||||
val results = LinkedList<ProgramakerCustomBlockArgumentValue>()
|
||||
for (entry in value.asIterable()) {
|
||||
var value = entry.value.toString()
|
||||
if (entry.value is Map<*, *>) {
|
||||
if ((entry.value as Map<String, *>).containsKey("name")) {
|
||||
value = (entry.value as Map<*, *>)["name"].toString()
|
||||
}
|
||||
}
|
||||
|
||||
results.add(ProgramakerCustomBlockArgumentValue(entry.key.toString(), value))
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deserialize(value: List<*>): List<ProgramakerCustomBlockArgumentValue> {
|
||||
val results = LinkedList<ProgramakerCustomBlockArgumentValue>()
|
||||
for (entry in value) {
|
||||
if (entry is Map<*,*>) {
|
||||
var name = (entry as Map<String, *>).optGet("name")
|
||||
var id = (entry as Map<String, *>).optGet("id")
|
||||
|
||||
if (name == null && id == null) {
|
||||
throw IllegalArgumentException("Error deserializing: $entry")
|
||||
}
|
||||
else if (name == null) {
|
||||
name = id
|
||||
}
|
||||
else if (id == null) {
|
||||
id = name
|
||||
}
|
||||
|
||||
results.add(ProgramakerCustomBlockArgumentValue(id.toString(), name.toString()))
|
||||
}
|
||||
else {
|
||||
throw IllegalArgumentException("Error deserializing: $entry")
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.programaker.api.data
|
||||
|
||||
import com.programaker.api.optGet
|
||||
import java.util.*
|
||||
|
||||
class ProgramakerCustomBlockArgumentValuesReturnInfo(
|
||||
val success: Boolean,
|
||||
val values: List<ProgramakerCustomBlockArgumentValue>
|
||||
) {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun deserialize(value: HashMap<String,*>): ProgramakerCustomBlockArgumentValuesReturnInfo {
|
||||
val _success: Boolean? = value.optGet("success") as Boolean?
|
||||
val _result: Object? = value.optGet("result") as Object
|
||||
|
||||
var success = false
|
||||
if (_success != null) {
|
||||
success = _success
|
||||
}
|
||||
|
||||
var result: List<ProgramakerCustomBlockArgumentValue> = Collections.emptyList<ProgramakerCustomBlockArgumentValue>()
|
||||
if (_result != null) {
|
||||
result = ProgramakerCustomBlockArgumentValue.deserializeList(_result)
|
||||
}
|
||||
|
||||
return ProgramakerCustomBlockArgumentValuesReturnInfo(success, result)
|
||||
}
|
||||
}
|
||||
}
|
@ -23,6 +23,11 @@ internal class ProgramakerGetCustomBlocksResultTypeAdapter : JsonSerializer<Prog
|
||||
for (value in value1.asJsonArray) {
|
||||
val block = gson.fromJson(value, ProgramakerCustomBlock::class.java)
|
||||
block.bridge_id = bridgeId
|
||||
if (block.arguments != null) {
|
||||
for (arg in block.arguments) {
|
||||
arg.bridge_id = bridgeId
|
||||
}
|
||||
}
|
||||
blocks.add(block)
|
||||
}
|
||||
|
||||
|
19
app/src/main/java/com/programaker/api/utils.kt
Normal file
19
app/src/main/java/com/programaker/api/utils.kt
Normal file
@ -0,0 +1,19 @@
|
||||
package com.programaker.api
|
||||
|
||||
internal fun <K, V> java.util.HashMap<K, V>.optGet(key: K): V? {
|
||||
if (this.containsKey(key)) {
|
||||
return this.get(key)
|
||||
}
|
||||
else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
internal fun <K, V> Map<K, V>.optGet(key: K): V? {
|
||||
if (this.containsKey(key)) {
|
||||
return this.get(key)
|
||||
}
|
||||
else {
|
||||
return null
|
||||
}
|
||||
}
|
@ -29,4 +29,7 @@
|
||||
<string name="set_value">Set block value</string>
|
||||
<string name="ok_accept_changes">OK</string>
|
||||
<string name="cancel_discard_changes">Cancel</string>
|
||||
<string name="error_establishing_connection">Error establishing connection</string>
|
||||
<string name="error_recovering_allowed_values">Error recovering allowed values</string>
|
||||
<string name="loading_available_values">Loading available values...</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user