[android] #5610 - Initial Runtime Style Bindings
[android] #5610 - Adjusted public api after discussion [android] #5610 - added jni binding for NativeMapView#getLayer [android] #5610 - Added initial test Activity [android] #5610 - Started on NativePeer implementation for Layer [android] #5610 - replaced low-level jni code with high-level for native getLayer [android] 5610 - completed basic layer peer class - constructible from java and c++ [android] #5610 - removed reference that was redundant and causing the finalizer exception [android] #5610 - Added a property peer [android] #5610 - added value type to do type conversions - wip [android] #5610 - simplified property conversion approach - wrapped value with jenv [android] #5610 - added some more value conversions [android] #5610 - Finished conversion for basic types [android] #5610 - allow color's to be set as either an android color int or a String to support all formats in the spec [android] #5610 - encode color ints as rgba to retain alpha channel [android] #5610 - recalculate classes after paint property [android] #5610 - more examples [android] #5610 - fixed the example [android] #5610 - cleaned up example code before continueing [android] #5610 - added layout property example [android] #5610 - set visibility on layer [android] #5610 - added removeLayer and example [android] #5610 - added more type conversions [android] #5610 - Started on peer classes for layer implementations - WIP [android] #5610 - First complete layer subclass peer implementation [android] #5610 - added a little bit of structure before adding the other layer types [android] #5610 - generate the c++ headers from the style spec [android] #5610 - make sure the visibility is set as a string [android] #5610 - Generate c++ layer peer class implementations from the style spec [android] #5610 - generate java layer peer classes [android] #5610 - cleanup comments [android] #5610 - register all c++ peer classes with jni [android] #5610 - addLayer [android] #5610 - comment out broken case [android] #5610 - Sources api - very much WIP [android] 5610 - GeoJson source implementation and geojson conversion [android] #5610 - cleanup add source/layer example a bit [android] #5610 - initial filter api [android] #5610 - Added filter api on the relevant Layer classes [android] #5610 - raster layer is not filterable [android] #5610 - actually make it compile [android] #5610 - completed filter implementation [android] #5610 - Vector and Raster Source + examples [android] #5610 - removed superfluous interface, moved filters to the correct package [android] #5610 - fixed comments [android] #5610 - moved tests to the right package [android] #5610 - hide difference between paint and layout properties in public api, make more performant set method for proeprties [android] #5610 - fix rebase issue
This commit is contained in:
114
platform/android/scripts/generate-style-code.js
Normal file
114
platform/android/scripts/generate-style-code.js
Normal file
@@ -0,0 +1,114 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const ejs = require('ejs');
|
||||
const spec = require('mapbox-gl-style-spec').latest;
|
||||
const _ = require('lodash');
|
||||
|
||||
global.iff = function (condition, val) {
|
||||
return condition() ? val : "";
|
||||
}
|
||||
|
||||
|
||||
global.camelize = function (str) {
|
||||
return str.replace(/(?:^|-)(.)/g, function (_, x) {
|
||||
return x.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
global.camelizeWithLeadingLowercase = function (str) {
|
||||
return str.replace(/-(.)/g, function (_, x) {
|
||||
return x.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
global.snakeCaseUpper = function (str) {
|
||||
return str.replace(/-/g, "_").toUpperCase();
|
||||
}
|
||||
|
||||
global.propertyType = function propertyType(property) {
|
||||
//TODO: Doe we want these exceptions?
|
||||
// if (/-translate-anchor$/.test(property.name)) {
|
||||
// return 'TranslateAnchorType';
|
||||
// }
|
||||
// if (/-(rotation|pitch)-alignment$/.test(property.name)) {
|
||||
// return 'AlignmentType';
|
||||
// }
|
||||
switch (property.type) {
|
||||
case 'boolean':
|
||||
return 'Boolean';
|
||||
case 'number':
|
||||
return 'Float';
|
||||
case 'string':
|
||||
return 'String';
|
||||
case 'enum':
|
||||
return `String`;
|
||||
case 'color':
|
||||
return `String`;
|
||||
case 'array':
|
||||
return `${propertyType({type:property.value})}[]`;
|
||||
default:
|
||||
throw new Error(`unknown type for ${property.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
global.propertyTypeAnnotation = function propertyTypeAnnotation(property) {
|
||||
switch (property.type) {
|
||||
case 'enum':
|
||||
return `@Property.${snakeCaseUpper(property.name)}`;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
//Process Layers
|
||||
const layers = spec.layer.type.values.map((type) => {
|
||||
const layoutProperties = Object.keys(spec[`layout_${type}`]).reduce((memo, name) => {
|
||||
if (name !== 'visibility') {
|
||||
spec[`layout_${type}`][name].name = name;
|
||||
memo.push(spec[`layout_${type}`][name]);
|
||||
}
|
||||
return memo;
|
||||
}, []);
|
||||
|
||||
const paintProperties = Object.keys(spec[`paint_${type}`]).reduce((memo, name) => {
|
||||
spec[`paint_${type}`][name].name = name;
|
||||
memo.push(spec[`paint_${type}`][name]);
|
||||
return memo;
|
||||
}, []);
|
||||
|
||||
return {
|
||||
type: type,
|
||||
layoutProperties: layoutProperties,
|
||||
paintProperties: paintProperties,
|
||||
};
|
||||
});
|
||||
|
||||
const layerHpp = ejs.compile(fs.readFileSync('platform/android/scripts/layer.hpp.ejs', 'utf8'), {strict: true});
|
||||
const layerCpp = ejs.compile(fs.readFileSync('platform/android/scripts/layer.cpp.ejs', 'utf8'), {strict: true});
|
||||
const layerJava = ejs.compile(fs.readFileSync('platform/android/scripts/layer.java.ejs', 'utf8'), {strict: true});
|
||||
|
||||
for (const layer of layers) {
|
||||
fs.writeFileSync(`platform/android/src/style/layers/${layer.type}_layer.hpp`, layerHpp(layer));
|
||||
fs.writeFileSync(`platform/android/src/style/layers/${layer.type}_layer.cpp`, layerCpp(layer));
|
||||
fs.writeFileSync(`platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/${camelize(layer.type)}Layer.java`, layerJava(layer));
|
||||
}
|
||||
|
||||
//Process all layer properties
|
||||
const layoutProperties = _(layers).map('layoutProperties').flatten().value();
|
||||
const paintProperties = _(layers).map('paintProperties').flatten().value();
|
||||
|
||||
const propertiesTemplate = ejs.compile(fs.readFileSync('platform/android/scripts/layer_property_factory.java.ejs', 'utf8'), {strict: true});
|
||||
fs.writeFileSync(
|
||||
`platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java`,
|
||||
propertiesTemplate({layoutProperties: layoutProperties, paintProperties: paintProperties})
|
||||
);
|
||||
|
||||
//Create types for the enum properties
|
||||
const enumProperties = _(layoutProperties).union(paintProperties).filter({'type': 'enum'}).value();
|
||||
const enumPropertyTemplate = ejs.compile(fs.readFileSync('platform/android/scripts/layer_property.java.ejs', 'utf8'), {strict: true});
|
||||
fs.writeFileSync(
|
||||
`platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java`,
|
||||
enumPropertyTemplate({properties: enumProperties})
|
||||
);
|
||||
|
||||
64
platform/android/scripts/layer.cpp.ejs
Normal file
64
platform/android/scripts/layer.cpp.ejs
Normal file
@@ -0,0 +1,64 @@
|
||||
<%
|
||||
const type = locals.type;
|
||||
-%>
|
||||
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
|
||||
|
||||
#include "<%- type %>_layer.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
//XXX
|
||||
#include <mbgl/platform/log.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
<% if (type === 'background') { -%>
|
||||
<%- camelize(type) %>Layer::<%- camelize(type) %>Layer(jni::JNIEnv& env, jni::String layerId)
|
||||
: Layer(env, std::make_unique<mbgl::style::<%- camelize(type) %>Layer>(jni::Make<std::string>(env, layerId))) {
|
||||
<% } else { -%>
|
||||
<%- camelize(type) %>Layer::<%- camelize(type) %>Layer(jni::JNIEnv& env, jni::String layerId, jni::String sourceId)
|
||||
: Layer(env, std::make_unique<mbgl::style::<%- camelize(type) %>Layer>(jni::Make<std::string>(env, layerId), jni::Make<std::string>(env, sourceId))) {
|
||||
<% } -%>
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "<%- camelize(type) %>Layer constructed, owning reference");
|
||||
}
|
||||
|
||||
<%- camelize(type) %>Layer::<%- camelize(type) %>Layer(mbgl::Map& map, mbgl::style::<%- camelize(type) %>Layer& coreLayer)
|
||||
: Layer(map, coreLayer) {
|
||||
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "<%- camelize(type) %>Layer Non-owning reference constructor");
|
||||
}
|
||||
|
||||
<%- camelize(type) %>Layer::~<%- camelize(type) %>Layer() = default;
|
||||
|
||||
jni::Class<<%- camelize(type) %>Layer> <%- camelize(type) %>Layer::javaClass;
|
||||
|
||||
jni::jobject* <%- camelize(type) %>Layer::createJavaPeer(jni::JNIEnv& env) {
|
||||
static auto constructor = <%- camelize(type) %>Layer::javaClass.template GetConstructor<jni::jlong>(env);
|
||||
return <%- camelize(type) %>Layer::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
|
||||
}
|
||||
|
||||
void <%- camelize(type) %>Layer::registerNative(jni::JNIEnv& env) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "Registering native background layer");
|
||||
|
||||
//Lookup the class
|
||||
<%- camelize(type) %>Layer::javaClass = *jni::Class<<%- camelize(type) %>Layer>::Find(env).NewGlobalRef(env).release();
|
||||
|
||||
#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name)
|
||||
|
||||
//Register the peer
|
||||
jni::RegisterNativePeer<<%- camelize(type) %>Layer>(
|
||||
env, <%- camelize(type) %>Layer::javaClass, "nativePtr",
|
||||
<% if (type === 'background') { -%>
|
||||
std::make_unique<<%- camelize(type) %>Layer, JNIEnv&, jni::String>,
|
||||
<% } else { -%>
|
||||
std::make_unique<<%- camelize(type) %>Layer, JNIEnv&, jni::String, jni::String>,
|
||||
<% } -%>
|
||||
"initialize",
|
||||
"finalize"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
38
platform/android/scripts/layer.hpp.ejs
Normal file
38
platform/android/scripts/layer.hpp.ejs
Normal file
@@ -0,0 +1,38 @@
|
||||
<%
|
||||
const type = locals.type;
|
||||
-%>
|
||||
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "layer.hpp"
|
||||
#include <mbgl/style/layers/<%- type %>_layer.hpp>
|
||||
#include <jni/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
class <%- camelize(type) %>Layer : public Layer {
|
||||
public:
|
||||
|
||||
static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/layers/<%- camelize(type) %>Layer"; };
|
||||
|
||||
static jni::Class<<%- camelize(type) %>Layer> javaClass;
|
||||
|
||||
static void registerNative(jni::JNIEnv&);
|
||||
|
||||
<% if (type === 'background') { -%>
|
||||
<%- camelize(type) %>Layer(jni::JNIEnv&, jni::String);
|
||||
<% } else { -%>
|
||||
<%- camelize(type) %>Layer(jni::JNIEnv&, jni::String, jni::String);
|
||||
<% } -%>
|
||||
|
||||
<%- camelize(type) %>Layer(mbgl::Map&, mbgl::style::<%- camelize(type) %>Layer&);
|
||||
|
||||
~<%- camelize(type) %>Layer();
|
||||
|
||||
jni::jobject* createJavaPeer(jni::JNIEnv&);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
} // namespace mbgl
|
||||
44
platform/android/scripts/layer.java.ejs
Normal file
44
platform/android/scripts/layer.java.ejs
Normal file
@@ -0,0 +1,44 @@
|
||||
<%
|
||||
const type = locals.type;
|
||||
-%>
|
||||
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
|
||||
package com.mapbox.mapboxsdk.style.layers;
|
||||
|
||||
/**
|
||||
* <%- camelize(type) %> Layer
|
||||
*/
|
||||
public class <%- camelize(type) %>Layer extends Layer {
|
||||
|
||||
public <%- camelize(type) %>Layer(long nativePtr) {
|
||||
super(nativePtr);
|
||||
}
|
||||
|
||||
<% if (type === 'background') { -%>
|
||||
public <%- camelize(type) %>Layer(String layerId) {
|
||||
initialize(layerId);
|
||||
}
|
||||
|
||||
protected native void initialize(String layerId);
|
||||
<% } else { -%>
|
||||
public <%- camelize(type) %>Layer(String layerId, String sourceId) {
|
||||
initialize(layerId, sourceId);
|
||||
}
|
||||
|
||||
protected native void initialize(String layerId, String sourceId);
|
||||
|
||||
public void setSourceLayer(String sourceLayer) {
|
||||
nativeSetSourceLayer(sourceLayer);
|
||||
}
|
||||
<% } -%>
|
||||
|
||||
<% if (type !== 'background' && type !== 'raster') { -%>
|
||||
public void setFilter(Filter.Statement filter) {
|
||||
this.setFilter(filter.toArray());
|
||||
}
|
||||
|
||||
public void setFilter(Object[] filter) {
|
||||
nativeSetFilter(filter);
|
||||
}
|
||||
|
||||
<% } -%>
|
||||
}
|
||||
42
platform/android/scripts/layer_property.java.ejs
Normal file
42
platform/android/scripts/layer_property.java.ejs
Normal file
@@ -0,0 +1,42 @@
|
||||
<%
|
||||
const properties = locals.properties;
|
||||
-%>
|
||||
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
|
||||
package com.mapbox.mapboxsdk.style.layers;
|
||||
|
||||
import android.support.annotation.StringDef;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Paint/Layout properties for Layer
|
||||
*/
|
||||
public abstract class Property<T> {
|
||||
|
||||
<% for (const property of properties) { -%>
|
||||
//<%- property.name %>
|
||||
<% for (const value of property.values) { -%>
|
||||
public static final String <%- snakeCaseUpper(property.name) %>_<%- snakeCaseUpper(value) %> = "<%- value %>";
|
||||
<% } -%>
|
||||
|
||||
@StringDef({
|
||||
<% for (const value of property.values) { -%>
|
||||
<%- snakeCaseUpper(property.name) %>_<%- snakeCaseUpper(value) %>,
|
||||
<% } -%>
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface <%- snakeCaseUpper(property.name) %> {}
|
||||
|
||||
<% } -%>
|
||||
|
||||
//Class definition
|
||||
public final String name;
|
||||
public final T value;
|
||||
|
||||
/* package */ Property(String name, T value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
45
platform/android/scripts/layer_property_factory.java.ejs
Normal file
45
platform/android/scripts/layer_property_factory.java.ejs
Normal file
@@ -0,0 +1,45 @@
|
||||
<%
|
||||
const paintProperties = locals.paintProperties;
|
||||
const layoutProperties = locals.layoutProperties;
|
||||
-%>
|
||||
// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
|
||||
package com.mapbox.mapboxsdk.style.layers;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.support.annotation.ColorInt;
|
||||
|
||||
/**
|
||||
* Constructs paint/layout properties for Layers
|
||||
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#layers>Layer style documentation</a>
|
||||
*
|
||||
*/
|
||||
public class PropertyFactory {
|
||||
|
||||
public static Property<String> visibility(Boolean visible) {
|
||||
return new LayoutProperty<>("visibility", visible? "visible": "none");
|
||||
}
|
||||
|
||||
<% for (const property of paintProperties) { -%>
|
||||
<% if (property.type == 'color') { -%>
|
||||
public static Property<String> <%- camelizeWithLeadingLowercase(property.name) %>(@ColorInt int value) {
|
||||
return new PaintProperty<>("<%- property.name %>", colorToRgbaString(value));
|
||||
}
|
||||
|
||||
<% } -%>
|
||||
public static Property<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) {
|
||||
return new PaintProperty<>("<%- property.name %>", value);
|
||||
}
|
||||
|
||||
<% } -%>
|
||||
<% for (const property of layoutProperties) { -%>
|
||||
public static Property<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) {
|
||||
return new LayoutProperty<>("<%- property.name %>", value);
|
||||
}
|
||||
|
||||
<% } -%>
|
||||
@SuppressLint("DefaultLocale")
|
||||
static String colorToRgbaString(@ColorInt int value) {
|
||||
return String.format("rgba(%d, %d, %d, %d)", (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, (value >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user