Merge branch 'master' into pattern-functions
Conflicts: src/mbgl/renderer/painter.cpp src/mbgl/renderer/painter.hpp src/mbgl/renderer/painter_fill.cpp src/mbgl/renderer/painter_line.cpp src/mbgl/style/style_layer.cpp src/mbgl/style/style_layer.hpp src/mbgl/style/style_layer_group.cpp src/mbgl/style/style_layer_group.hpp
This commit is contained in:
@@ -2,9 +2,11 @@ Standard: Cpp11
|
||||
IndentWidth: 4
|
||||
AccessModifierOffset: -4
|
||||
UseTab: Never
|
||||
BinPackParameters: true
|
||||
BinPackParameters: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
NamespaceIndentation: None
|
||||
@@ -12,5 +14,5 @@ PointerBindsToType: false
|
||||
SpacesInParentheses: false
|
||||
BreakBeforeBraces: Attach
|
||||
ColumnLimit: 100
|
||||
Cpp11BracedListStyle: true
|
||||
Cpp11BracedListStyle: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -3,11 +3,14 @@
|
||||
*.o
|
||||
*.actual.png
|
||||
*.diff.png
|
||||
*.pyc
|
||||
/mason_packages
|
||||
/config.gypi
|
||||
/config-ios.gypi
|
||||
/config-android.gypi
|
||||
/config/*.gypi
|
||||
/build
|
||||
/macosx/build
|
||||
/linux/build
|
||||
/test/build
|
||||
/test/node_modules
|
||||
/include/mbgl/shader/shaders.hpp
|
||||
/src/shader/shaders_gl.cpp
|
||||
/src/shader/shaders_gles2.cpp
|
||||
|
||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -13,3 +13,7 @@
|
||||
[submodule "styles"]
|
||||
path = styles
|
||||
url = https://github.com/mapbox/mapbox-gl-styles.git
|
||||
|
||||
[submodule "app/ios"]
|
||||
path = app/ios
|
||||
url = https://github.com/mapbox/mapbox-gl-cocoa.git
|
||||
2
.mason
2
.mason
Submodule .mason updated: 3833ddbd71...03869fd11e
@@ -53,13 +53,13 @@ before_install:
|
||||
- if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then sudo service postgresql stop; fi
|
||||
- source ./scripts/local_mason.sh
|
||||
- source ./scripts/travis_helper.sh
|
||||
- source ./scripts/install_node.sh
|
||||
- source ./scripts/flags.sh
|
||||
- ./scripts/travis_before_install.sh
|
||||
- if [[ ${TRAVIS_OS_NAME} == "linux" && ${MASON_PLATFORM} != "android" ]]; then export LD_LIBRARY_PATH=`mason prefix mesa 10.4.3`/lib; fi
|
||||
- if [[ ${TRAVIS_OS_NAME} == "linux" && ${MASON_PLATFORM} != "android" ]]; then glxinfo; fi
|
||||
|
||||
install:
|
||||
- if [[ ${MASON_PLATFORM} != "android" ]]; then make config.gypi; fi
|
||||
- ulimit -c
|
||||
|
||||
before_script:
|
||||
|
||||
287
Makefile
287
Makefile
@@ -1,143 +1,174 @@
|
||||
BUILDTYPE ?= Release
|
||||
PYTHON ?= python
|
||||
V ?= 1
|
||||
PREFIX ?= /usr/local
|
||||
ANDROID_ABI ?= arm-v7
|
||||
JOBS ?= 1
|
||||
|
||||
ifeq ($(shell uname -s), Darwin)
|
||||
PLATFORM ?= osx
|
||||
HOST ?= osx
|
||||
endif
|
||||
PLATFORM ?= linux
|
||||
HOST ?= linux
|
||||
|
||||
.PHONY: all
|
||||
all: mbgl-core mbgl-platform mbgl-headless
|
||||
all: mbgl
|
||||
|
||||
config.gypi: configure
|
||||
./configure
|
||||
include config/defaults.mk
|
||||
|
||||
config-ios.gypi: configure
|
||||
MASON_PLATFORM=ios ./configure config-ios.gypi
|
||||
#### Dependencies ##############################################################
|
||||
|
||||
# Wildcard targets get removed after build by default, but we want to preserve the config.
|
||||
.PRECIOUS: config/%.gypi
|
||||
config/%.gypi: CMD = ./configure config/$*.gypi
|
||||
config/%.gypi: configure
|
||||
@$(ENV_$*) ./scripts/flock.py build/Configure.lock ./configure config/$*.gypi
|
||||
|
||||
#### Library builds ############################################################
|
||||
|
||||
.PHONY: mbgl-core
|
||||
mbgl-core: build/mbgl/Makefile
|
||||
$(MAKE) -C build/mbgl BUILDTYPE=$(BUILDTYPE) V=$(V) mbgl-core
|
||||
.PRECOIUS: Makefile/mbgl
|
||||
Makefile/mbgl: config/$(HOST).gypi
|
||||
deps/run_gyp mbgl.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make
|
||||
|
||||
.PHONY: mbgl-platform
|
||||
mbgl-platform: build/mbgl/Makefile
|
||||
$(MAKE) -C build/mbgl BUILDTYPE=$(BUILDTYPE) V=$(V) mbgl-$(PLATFORM)
|
||||
mbgl: Makefile/mbgl
|
||||
$(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) everything
|
||||
|
||||
.PHONY: mbgl-headless
|
||||
mbgl-headless: build/mbgl/Makefile
|
||||
$(MAKE) -C build/mbgl BUILDTYPE=$(BUILDTYPE) V=$(V) mbgl-headless
|
||||
standalone: Makefile/mbgl
|
||||
LINK=`pwd`/gyp/link.py $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) standalone
|
||||
|
||||
.PHONY: install
|
||||
install: build/mbgl/Makefile
|
||||
$(MAKE) -C build/mbgl BUILDTYPE=$(BUILDTYPE) V=$(V) install
|
||||
|
||||
#### Build scripts #############################################################
|
||||
|
||||
.PHONY: build/mbgl/Makefile
|
||||
build/mbgl/Makefile: mapboxgl.gyp config.gypi
|
||||
deps/run_gyp mapboxgl.gyp -Iconfig.gypi -Dplatform=$(PLATFORM) -Dinstall_prefix=$(PREFIX) --depth=. -Goutput_dir=.. --generator-output=./build/mbgl -f make
|
||||
|
||||
.PHONY: build/test/Makefile
|
||||
build/test/Makefile: test/test.gyp config.gypi
|
||||
deps/run_gyp test/test.gyp -Iconfig.gypi -Dplatform=$(PLATFORM) --depth=. -Goutput_dir=.. --generator-output=./build/test -f make
|
||||
|
||||
.PHONY: build/linux/Makefile
|
||||
build/linux/Makefile: linux/mapboxgl-app.gyp config.gypi
|
||||
deps/run_gyp linux/mapboxgl-app.gyp -Iconfig.gypi -Dplatform=linux --depth=. -Goutput_dir=.. --generator-output=./build/linux -f make
|
||||
|
||||
.PHONY: build/macosx/Makefile
|
||||
build/macosx/Makefile: macosx/mapboxgl-app.gyp config.gypi
|
||||
deps/run_gyp macosx/mapboxgl-app.gyp -Iconfig.gypi -Dplatform=osx --depth=. -Goutput_dir=.. --generator-output=./build/macosx -f make
|
||||
|
||||
.PHONY: build/render/Makefile
|
||||
build/render/Makefile: bin/render.gyp config.gypi
|
||||
deps/run_gyp bin/render.gyp -Iconfig.gypi -Dplatform=$(PLATFORM) --depth=. -Goutput_dir=.. --generator-output=./build/render -f make
|
||||
|
||||
.PHONY: build/test/test.xcodeproj
|
||||
build/test/test.xcodeproj: test/test.gyp config.gypi
|
||||
deps/run_gyp test/test.gyp -Iconfig.gypi -Dplatform=$(PLATFORM) --depth=. -Goutput_dir=.. --generator-output=./build -f xcode
|
||||
|
||||
.PHONY: build/macosx/mapboxgl-app.xcodeproj
|
||||
build/macosx/mapboxgl-app.xcodeproj: macosx/mapboxgl-app.gyp config.gypi
|
||||
deps/run_gyp macosx/mapboxgl-app.gyp -Iconfig.gypi -Dplatform=osx --depth=. --generator-output=./build -f xcode
|
||||
|
||||
.PHONY: build/ios/mapbox-gl-cocoa/app/mapboxgl-app.xcodeproj
|
||||
build/ios/mapbox-gl-cocoa/app/mapboxgl-app.xcodeproj: ios/mapbox-gl-cocoa/app/mapboxgl-app.gyp config-ios.gypi
|
||||
deps/run_gyp ios/mapbox-gl-cocoa/app/mapboxgl-app.gyp -Iconfig-ios.gypi -Dplatform=ios --depth=. --generator-output=./build -f xcode
|
||||
|
||||
.PHONY: build/linux/mapboxgl-app.xcodeproj
|
||||
build/linux/mapboxgl-app.xcodeproj: linux/mapboxgl-app.gyp config.gypi
|
||||
deps/run_gyp linux/mapboxgl-app.gyp -Iconfig.gypi -Dplatform=linux --depth=. --generator-output=./build -f xcode
|
||||
|
||||
.PHONY: build/bin/render.xcodeproj
|
||||
build/bin/render.xcodeproj: bin/render.gyp config.gypi
|
||||
deps/run_gyp bin/render.gyp -Iconfig.gypi -Dplatform=$(PLATFORM) --depth=. --generator-output=./build -f xcode
|
||||
|
||||
.PHONY: android
|
||||
android:
|
||||
./scripts/local_mason.sh && \
|
||||
MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=$(MASON_ANDROID_ABI) ./.mason/mason env PATH && \
|
||||
export CXX="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env CXX`" && \
|
||||
export CC="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env CC`" && \
|
||||
export LD="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env LD`" && \
|
||||
export LINK="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env CXX`" && \
|
||||
export AR="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env AR`" && \
|
||||
export RANLIB="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env RANLIB`" && \
|
||||
export STRIP="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env STRIP`" && \
|
||||
export LDFLAGS="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env LDFLAGS` ${LDFLAGS}" && \
|
||||
export CFLAGS="`MASON_DIR=./.mason MASON_PLATFORM= MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env CFLAGS` ${CFLAGS}" && \
|
||||
export CPPFLAGS="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env CPPFLAGS` ${CPPFLAGS}" && \
|
||||
export PATH="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env PATH`:${PATH}" && \
|
||||
export JNIDIR="`MASON_DIR=./.mason MASON_PLATFORM=android MASON_ANDROID_ABI=${MASON_ANDROID_ABI} ./.mason/mason env JNIDIR`" && \
|
||||
MASON_PLATFORM=android MASON_ANDROID_ABI=$(MASON_ANDROID_ABI) ./configure config-android.gypi && \
|
||||
deps/run_gyp android/mapboxgl-app.gyp -Iconfig-android.gypi -Dplatform=android --depth=. --generator-output=./build/android/$(MASON_ANDROID_ABI) -f make-android && \
|
||||
$(MAKE) -C build/android/$(MASON_ANDROID_ABI) -j$(JOBS) BUILDTYPE=$(BUILDTYPE) V=$(V) androidapp && \
|
||||
BUILDTYPE=$(BUILDTYPE) MASON_ANDROID_ABI=$(MASON_ANDROID_ABI) ./android/scripts/copy-files.sh && \
|
||||
cd android/java && \
|
||||
./gradlew --parallel-threads=$(JOBS) build
|
||||
|
||||
##### Test cases ###############################################################
|
||||
|
||||
test: build/test/Makefile
|
||||
$(MAKE) -C build/test BUILDTYPE=$(BUILDTYPE) V=$(V) test
|
||||
|
||||
test_%: build/test/Makefile
|
||||
$(MAKE) -C build/test BUILDTYPE=$(BUILDTYPE) V=$(V) $*
|
||||
(cd build/$(BUILDTYPE) && exec ./test_$*)
|
||||
|
||||
# build Mac OS X project for Xcode
|
||||
xtest: build/test/test.xcodeproj
|
||||
open ./build/test/test.xcodeproj
|
||||
|
||||
##### Makefile builds ##########################################################
|
||||
install: Makefile/mbgl
|
||||
LINK=`pwd`/gyp/link.py $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) install
|
||||
|
||||
|
||||
# Builds the linux app with make.
|
||||
linux: build/linux/Makefile
|
||||
$(MAKE) -C build/linux BUILDTYPE=$(BUILDTYPE) V=$(V) linuxapp
|
||||
##### Test builds ##############################################################
|
||||
|
||||
# Executes the Linux binary
|
||||
run-linux: linux
|
||||
(cd build/$(BUILDTYPE) && ./mapbox-gl)
|
||||
.PRECIOUS: Makefile/test
|
||||
Makefile/test: test/test.gyp config/$(HOST).gypi
|
||||
deps/run_gyp test/test.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make
|
||||
|
||||
# Builds the OS X app with make.
|
||||
osx: build/macosx/Makefile
|
||||
$(MAKE) -C build/macosx BUILDTYPE=$(BUILDTYPE) V=$(V) osxapp
|
||||
test: Makefile/test
|
||||
$(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) test
|
||||
|
||||
test-%: test
|
||||
./scripts/run_tests.sh "build/$(HOST)/$(BUILDTYPE)/test" --gtest_filter=$*
|
||||
|
||||
|
||||
.PRECIOUS: Xcode/test
|
||||
Xcode/test: test/test.gyp config/osx.gypi
|
||||
deps/run_gyp test/test.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f xcode
|
||||
|
||||
.PHONY: lproj lbuild run-xlinux
|
||||
xtest-proj: Xcode/test
|
||||
open ./build/osx/test/test.xcodeproj
|
||||
|
||||
xtest: Xcode/test
|
||||
xcodebuild -project ./build/osx/test/test.xcodeproj -configuration $(BUILDTYPE) -target test -jobs `sysctl -n hw.ncpu`
|
||||
|
||||
xtest-%: xtest
|
||||
./scripts/run_tests.sh "build/osx/Build/Products/$(BUILDTYPE)/test" --gtest_filter=$*
|
||||
|
||||
|
||||
#### Mac OS X application builds ###############################################
|
||||
|
||||
.PRECIOUS: Makefile/osx
|
||||
Makefile/osx: macosx/mapboxgl-app.gyp config/osx.gypi
|
||||
deps/run_gyp macosx/mapboxgl-app.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f make
|
||||
|
||||
.PHONY: osx run-osx
|
||||
osx: Makefile/osx
|
||||
$(MAKE) -C build/osx BUILDTYPE=$(BUILDTYPE) osxapp
|
||||
|
||||
# Executes the OS X binary
|
||||
run-osx: osx
|
||||
build/$(BUILDTYPE)/Mapbox\ GL.app/Contents/MacOS/MAPBOX\ GL
|
||||
"build/osx/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL"
|
||||
|
||||
# Builds the CLI render app
|
||||
render: build/render/Makefile
|
||||
$(MAKE) -C build/render BUILDTYPE=$(BUILDTYPE) V=$(V) mbgl-render
|
||||
|
||||
##### Xcode projects ###########################################################
|
||||
.PRECIOUS: Xcode/osx
|
||||
Xcode/osx: macosx/mapboxgl-app.gyp config/osx.gypi
|
||||
deps/run_gyp macosx/mapboxgl-app.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f xcode
|
||||
|
||||
.PHONY: xosx-proj xosx run-xosx
|
||||
xosx-proj: Xcode/osx
|
||||
open ./build/osx/macosx/mapboxgl-app.xcodeproj
|
||||
|
||||
xosx: Xcode/osx
|
||||
xcodebuild -project ./build/osx/macosx/mapboxgl-app.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs `sysctl -n hw.ncpu`
|
||||
|
||||
run-xosx: xosx
|
||||
"build/osx/Build/Products/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL"
|
||||
|
||||
# Legacy name
|
||||
xproj: xosx-proj
|
||||
|
||||
|
||||
|
||||
#### iOS application builds ####################################################
|
||||
|
||||
.PRECIOUS: Xcode/ios
|
||||
Xcode/ios: ios/mapbox-gl-cocoa/app/mapboxgl-app.gyp config/ios.gypi
|
||||
deps/run_gyp ios/mapbox-gl-cocoa/app/mapboxgl-app.gyp $(CONFIG_ios) $(LIBS_ios) --generator-output=./build/ios -f xcode
|
||||
|
||||
.PHONY: ios-proj ios run-ios
|
||||
ios-proj: Xcode/ios
|
||||
open ./build/ios/ios/mapbox-gl-cocoa/app/mapboxgl-app.xcodeproj
|
||||
|
||||
ios: Xcode/ios
|
||||
xcodebuild -sdk iphonesimulator ARCHS=x86_64 -project ./build/ios/ios/mapbox-gl-cocoa/app/mapboxgl-app.xcodeproj -configuration $(BUILDTYPE) -target iosapp -jobs `sysctl -n hw.ncpu`
|
||||
|
||||
# Legacy name
|
||||
iproj: ios-proj
|
||||
|
||||
|
||||
#### Linux application builds ##################################################
|
||||
|
||||
.PRECIOUS: Makefile/linux
|
||||
Makefile/linux: linux/mapboxgl-app.gyp config/$(HOST).gypi
|
||||
deps/run_gyp linux/mapboxgl-app.gyp $(CONFIG_$(HOST)) $(LIBS_linux) --generator-output=./build/$(HOST) -f make
|
||||
|
||||
.PHONY: linux run-linux
|
||||
linux: Makefile/linux
|
||||
$(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) linuxapp
|
||||
|
||||
run-linux: linux
|
||||
(cd build/$(HOST)/$(BUILDTYPE) && ./mapbox-gl)
|
||||
|
||||
|
||||
.PRECIOUS: Xcode/linux
|
||||
Xcode/linux: linux/mapboxgl-app.gyp config/osx.gypi
|
||||
deps/run_gyp linux/mapboxgl-app.gyp $(CONFIG_osx) $(LIBS_linux) --generator-output=./build/osx -f xcode
|
||||
|
||||
.PHONY: lproj lbuild run-xlinux
|
||||
xlinux-proj: Xcode/linux
|
||||
open ./build/osx/linux/mapboxgl-app.xcodeproj
|
||||
|
||||
xlinux: Xcode/linux
|
||||
xcodebuild -project ./build/osx/linux/mapboxgl-app.xcodeproj -configuration $(BUILDTYPE) -target linuxapp
|
||||
|
||||
run-xlinux: xlinux
|
||||
"build/osx/Build/Products/$(BUILDTYPE)/mapbox-gl"
|
||||
|
||||
# Legacy name
|
||||
lproj: xlinux-proj
|
||||
|
||||
|
||||
#### Android libaries #########################################################
|
||||
|
||||
.PRECIOUS: Makefile/android-%
|
||||
Makefile/android-%: CMD = deps/run_gyp android/mapboxgl-app.gyp $(CONFIG_android-$*) $(LIBS_android) --generator-output=./build/android-$* -f make-android
|
||||
Makefile/android-%: config/android-%.gypi
|
||||
@echo $(CMD)
|
||||
@$(ENV_android-$*) $(CMD)
|
||||
|
||||
# Builds a particular android architecture.
|
||||
android-lib-%: Makefile/android-%
|
||||
@$(ENV_android-$*) ./scripts/flock.py -v build/Android.lock $(MAKE) -C build/android-$* BUILDTYPE=$(BUILDTYPE) androidapp
|
||||
|
||||
# Builds the selected/default Android library
|
||||
android: android-lib-$(ANDROID_ABI)
|
||||
cd android/java && ./gradlew --parallel-threads=$(JOBS) build
|
||||
|
||||
# Builds all android architectures.
|
||||
android-all: $(ANDROID_ABIS)
|
||||
cd android/java && ./gradlew --parallel-threads=$(JOBS) build
|
||||
|
||||
|
||||
##### Maintenace operations ####################################################
|
||||
|
||||
.PHONY: clear_xcode_cache
|
||||
clear_xcode_cache:
|
||||
@@ -153,22 +184,6 @@ ifeq ($(PLATFORM), osx)
|
||||
fi
|
||||
endif
|
||||
|
||||
xproj: build/macosx/mapboxgl-app.xcodeproj
|
||||
open ./build/macosx/mapboxgl-app.xcodeproj
|
||||
|
||||
iproj: build/ios/mapbox-gl-cocoa/app/mapboxgl-app.xcodeproj
|
||||
open ./build/ios/mapbox-gl-cocoa/app/mapboxgl-app.xcodeproj
|
||||
|
||||
rproj: build/bin/render.xcodeproj
|
||||
open ./build/bin/render.xcodeproj
|
||||
|
||||
# build Linux project for Xcode (Runs on Mac OS X too, but without platform-specific code)
|
||||
lproj: build/linux/mapboxgl-app.xcodeproj
|
||||
open ./build/linux/mapboxgl-app.xcodeproj
|
||||
|
||||
|
||||
##### Maintenace operations ####################################################
|
||||
|
||||
.PHONY: clear_sqlite_cache
|
||||
clear_sqlite_cache:
|
||||
ifeq ($(PLATFORM), osx)
|
||||
@@ -180,8 +195,12 @@ endif
|
||||
clean: clear_sqlite_cache clear_xcode_cache
|
||||
-find ./deps/gyp -name "*.pyc" -exec rm {} \;
|
||||
-rm -rf ./build/
|
||||
-rm -rf ./macosx/build/
|
||||
-rm -rf ./config.gypi ./config-ios.gypi ./config-android.gypi
|
||||
-rm -rf ./macosx/build
|
||||
-rm -rf ./linux/build
|
||||
-rm -rf ./ios/mapbox-gl-cocoa/build
|
||||
-rm -rf ./ios/mapbox-gl-cocoa/app/build
|
||||
-rm -rf ./test/build
|
||||
-rm -rf ./config/*.gypi
|
||||
-rm -rf ./android/java/build ./android/java/app/build ./android/java/lib/build
|
||||
-rm -rf ./android/java/lib/src/main/jniLibs ./android/java/lib/src/main/assets
|
||||
-rm -f ./android/test/features.zip
|
||||
|
||||
@@ -36,6 +36,7 @@ To create projects, you can run:
|
||||
- `make lproj`: Creates an Xcode project with platform-independent handlers for downloads and settings storage. This is what is also being built on Linux.
|
||||
- `make osx run-osx`: Builds and runs the OS X application on the command line with `xcodebuild`.
|
||||
- `make linux run-linux`: Builds and runs the Linux application with `make`.
|
||||
- `make test-*` Builds and runs all tests. You can specify individual tests by replacing * with their name.
|
||||
|
||||
Note that you can't have more than one project in Xcode open at a time since they the static library project is shared across the OS X, Linux and iOS project.
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <mbgl/platform/android/log_android.hpp>
|
||||
#include <mbgl/platform/event.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/storage/network_status.hpp>
|
||||
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
@@ -380,19 +381,19 @@ jobject JNICALL nativeGetClasses(JNIEnv *env, jobject obj, jlong nativeMapViewPt
|
||||
}
|
||||
|
||||
void JNICALL nativeSetDefaultTransitionDuration(JNIEnv *env, jobject obj, jlong nativeMapViewPtr,
|
||||
jlong milliseconds) {
|
||||
jlong duration) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetDefaultTransitionDuration");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
assert(milliseconds >= 0);
|
||||
assert(duration >= 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->getMap().setDefaultTransitionDuration(milliseconds);
|
||||
nativeMapView->getMap().setDefaultTransitionDuration(std::chrono::milliseconds(duration));
|
||||
}
|
||||
|
||||
jlong JNICALL nativeGetDefaultTransitionDuration(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetDefaultTransitionDuration");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
return nativeMapView->getMap().getDefaultTransitionDuration();
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(nativeMapView->getMap().getDefaultTransitionDuration()).count();
|
||||
}
|
||||
|
||||
void JNICALL nativeSetStyleURL(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring url) {
|
||||
@@ -423,14 +424,14 @@ nativeSetAccessToken(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring a
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetAccessToken");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->getFileSource().setAccessToken(std_string_from_jstring(env, accessToken));
|
||||
nativeMapView->getMap().setAccessToken(std_string_from_jstring(env, accessToken));
|
||||
}
|
||||
|
||||
jstring JNICALL nativeGetAccessToken(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetAccessToken");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
return std_string_to_jstring(env, nativeMapView->getFileSource().getAccessToken());
|
||||
return std_string_to_jstring(env, nativeMapView->getMap().getAccessToken());
|
||||
}
|
||||
|
||||
void JNICALL nativeCancelTransitions(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
|
||||
@@ -441,15 +442,15 @@ void JNICALL nativeCancelTransitions(JNIEnv *env, jobject obj, jlong nativeMapVi
|
||||
}
|
||||
|
||||
void JNICALL nativeMoveBy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble dx, jdouble dy,
|
||||
jdouble duration) {
|
||||
jlong duration) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeMoveBy");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->getMap().moveBy(dx, dy, duration);
|
||||
nativeMapView->getMap().moveBy(dx, dy, std::chrono::milliseconds(duration));
|
||||
}
|
||||
|
||||
void JNICALL nativeSetLonLat(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject lonLat,
|
||||
jdouble duration) {
|
||||
jlong duration) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetLonLat");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
@@ -466,7 +467,7 @@ void JNICALL nativeSetLonLat(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, j
|
||||
return;
|
||||
}
|
||||
|
||||
nativeMapView->getMap().setLonLat(lon, lat, duration);
|
||||
nativeMapView->getMap().setLonLat(lon, lat, std::chrono::milliseconds(duration));
|
||||
}
|
||||
|
||||
jobject JNICALL nativeGetLonLat(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
|
||||
@@ -507,19 +508,19 @@ void JNICALL nativeResetPosition(JNIEnv *env, jobject obj, jlong nativeMapViewPt
|
||||
}
|
||||
|
||||
void JNICALL nativeScaleBy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble ds, jdouble cx,
|
||||
jdouble cy, jdouble duration) {
|
||||
jdouble cy, jlong duration) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeScaleBy");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->getMap().scaleBy(ds, cx, cy, duration);
|
||||
nativeMapView->getMap().scaleBy(ds, cx, cy, std::chrono::milliseconds(duration));
|
||||
}
|
||||
|
||||
void JNICALL nativeSetScale(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble scale,
|
||||
jdouble cx, jdouble cy, jdouble duration) {
|
||||
jdouble cx, jdouble cy, jlong duration) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetScale");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->getMap().setScale(scale, cx, cy, duration);
|
||||
nativeMapView->getMap().setScale(scale, cx, cy, std::chrono::milliseconds(duration));
|
||||
}
|
||||
|
||||
jdouble JNICALL nativeGetScale(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
|
||||
@@ -530,11 +531,11 @@ jdouble JNICALL nativeGetScale(JNIEnv *env, jobject obj, jlong nativeMapViewPtr)
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
nativeSetZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble zoom, jdouble duration) {
|
||||
nativeSetZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble zoom, jlong duration) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetZoom");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->getMap().setZoom(zoom, duration);
|
||||
nativeMapView->getMap().setZoom(zoom, std::chrono::milliseconds(duration));
|
||||
}
|
||||
|
||||
jdouble JNICALL nativeGetZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
|
||||
@@ -545,7 +546,7 @@ jdouble JNICALL nativeGetZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr)
|
||||
}
|
||||
|
||||
void JNICALL nativeSetLonLatZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr,
|
||||
jobject lonLatZoom, jdouble duration) {
|
||||
jobject lonLatZoom, jlong duration) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetLonLatZoom");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
@@ -568,7 +569,7 @@ void JNICALL nativeSetLonLatZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPt
|
||||
return;
|
||||
}
|
||||
|
||||
nativeMapView->getMap().setLonLatZoom(lon, lat, zoom, duration);
|
||||
nativeMapView->getMap().setLonLatZoom(lon, lat, zoom, std::chrono::milliseconds(duration));
|
||||
}
|
||||
|
||||
jobject JNICALL nativeGetLonLatZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
|
||||
@@ -623,19 +624,19 @@ jdouble JNICALL nativeGetMaxZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPt
|
||||
}
|
||||
|
||||
void JNICALL nativeRotateBy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble sx,
|
||||
jdouble sy, jdouble ex, jdouble ey, jdouble duration) {
|
||||
jdouble sy, jdouble ex, jdouble ey, jlong duration) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeRotateBy");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->getMap().rotateBy(sx, sy, ex, ey, duration);
|
||||
nativeMapView->getMap().rotateBy(sx, sy, ex, ey, std::chrono::milliseconds(duration));
|
||||
}
|
||||
|
||||
void JNICALL nativeSetBearing(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble degrees,
|
||||
jdouble duration) {
|
||||
jlong duration) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetBearing");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->getMap().setBearing(degrees, duration);
|
||||
nativeMapView->getMap().setBearing(degrees, std::chrono::milliseconds(duration));
|
||||
}
|
||||
|
||||
void JNICALL nativeSetBearing(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble degrees,
|
||||
@@ -701,8 +702,9 @@ void JNICALL
|
||||
nativeSetReachability(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean status) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetReachability");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->getFileSource().setReachability(status);
|
||||
if (status) {
|
||||
mbgl::NetworkStatus::Reachable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -889,20 +891,20 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||
{"nativeGetAccessToken", "(J)Ljava/lang/String;",
|
||||
reinterpret_cast<void *>(&nativeGetAccessToken)},
|
||||
{"nativeCancelTransitions", "(J)V", reinterpret_cast<void *>(&nativeCancelTransitions)},
|
||||
{"nativeMoveBy", "(JDDD)V", reinterpret_cast<void *>(&nativeMoveBy)},
|
||||
{"nativeSetLonLat", "(JLcom/mapbox/mapboxgl/lib/LonLat;D)V",
|
||||
{"nativeMoveBy", "(JDDJ)V", reinterpret_cast<void *>(&nativeMoveBy)},
|
||||
{"nativeSetLonLat", "(JLcom/mapbox/mapboxgl/lib/LonLat;J)V",
|
||||
reinterpret_cast<void *>(&nativeSetLonLat)},
|
||||
{"nativeGetLonLat", "(J)Lcom/mapbox/mapboxgl/lib/LonLat;",
|
||||
reinterpret_cast<void *>(&nativeGetLonLat)},
|
||||
{"nativeStartPanning", "(J)V", reinterpret_cast<void *>(&nativeStartPanning)},
|
||||
{"nativeStopPanning", "(J)V", reinterpret_cast<void *>(&nativeStopPanning)},
|
||||
{"nativeResetPosition", "(J)V", reinterpret_cast<void *>(&nativeResetPosition)},
|
||||
{"nativeScaleBy", "(JDDDD)V", reinterpret_cast<void *>(&nativeScaleBy)},
|
||||
{"nativeSetScale", "(JDDDD)V", reinterpret_cast<void *>(&nativeSetScale)},
|
||||
{"nativeScaleBy", "(JDDDJ)V", reinterpret_cast<void *>(&nativeScaleBy)},
|
||||
{"nativeSetScale", "(JDDDJ)V", reinterpret_cast<void *>(&nativeSetScale)},
|
||||
{"nativeGetScale", "(J)D", reinterpret_cast<void *>(&nativeGetScale)},
|
||||
{"nativeSetZoom", "(JDD)V", reinterpret_cast<void *>(&nativeSetZoom)},
|
||||
{"nativeSetZoom", "(JDJ)V", reinterpret_cast<void *>(&nativeSetZoom)},
|
||||
{"nativeGetZoom", "(J)D", reinterpret_cast<void *>(&nativeGetZoom)},
|
||||
{"nativeSetLonLatZoom", "(JLcom/mapbox/mapboxgl/lib/LonLatZoom;D)V",
|
||||
{"nativeSetLonLatZoom", "(JLcom/mapbox/mapboxgl/lib/LonLatZoom;J)V",
|
||||
reinterpret_cast<void *>(&nativeSetLonLatZoom)},
|
||||
{"nativeGetLonLatZoom", "(J)Lcom/mapbox/mapboxgl/lib/LonLatZoom;",
|
||||
reinterpret_cast<void *>(&nativeGetLonLatZoom)},
|
||||
@@ -911,10 +913,10 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||
{"nativeStopPanning", "(J)V", reinterpret_cast<void *>(&nativeStopScaling)},
|
||||
{"nativeGetMinZoom", "(J)D", reinterpret_cast<void *>(&nativeGetMinZoom)},
|
||||
{"nativeGetMaxZoom", "(J)D", reinterpret_cast<void *>(&nativeGetMaxZoom)},
|
||||
{"nativeRotateBy", "(JDDDDD)V", reinterpret_cast<void *>(&nativeRotateBy)},
|
||||
{"nativeSetBearing", "(JDD)V",
|
||||
{"nativeRotateBy", "(JDDDDJ)V", reinterpret_cast<void *>(&nativeRotateBy)},
|
||||
{"nativeSetBearing", "(JDJ)V",
|
||||
reinterpret_cast<void *>(
|
||||
static_cast<void JNICALL (*)(JNIEnv *, jobject, jlong, jdouble, jdouble)>(
|
||||
static_cast<void JNICALL (*)(JNIEnv *, jobject, jlong, jdouble, jlong)>(
|
||||
&nativeSetBearing))},
|
||||
{"nativeSetBearing", "(JDDD)V",
|
||||
reinterpret_cast<void *>(
|
||||
|
||||
@@ -54,7 +54,8 @@ void log_gl_string(GLenum name, const char *label) {
|
||||
|
||||
NativeMapView::NativeMapView(JNIEnv *env, jobject obj_)
|
||||
: mbgl::View(*this),
|
||||
fileSource(mbgl::platform::defaultCacheDatabase()),
|
||||
fileCache(mbgl::android::cachePath + "/mbgl-cache.db"),
|
||||
fileSource(&fileCache),
|
||||
map(*this, fileSource) {
|
||||
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::NativeMapView");
|
||||
|
||||
@@ -140,7 +141,7 @@ void NativeMapView::notify() {
|
||||
|
||||
mbgl::Map &NativeMapView::getMap() { return map; }
|
||||
|
||||
mbgl::CachingHTTPFileSource &NativeMapView::getFileSource() { return fileSource; }
|
||||
mbgl::DefaultFileSource &NativeMapView::getFileSource() { return fileSource; }
|
||||
|
||||
bool NativeMapView::inEmulator() {
|
||||
// Detect if we are in emulator
|
||||
@@ -718,7 +719,7 @@ void NativeMapView::resume() {
|
||||
}
|
||||
}
|
||||
|
||||
void NativeMapView::notifyMapChange(mbgl::MapChange, mbgl::timestamp) {
|
||||
void NativeMapView::notifyMapChange(mbgl::MapChange, std::chrono::steady_clock::duration) {
|
||||
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::notifyMapChange()");
|
||||
|
||||
assert(vm != nullptr);
|
||||
|
||||
@@ -46,6 +46,9 @@ public class MapView extends SurfaceView {
|
||||
// Tag used for logging
|
||||
private static final String TAG = "MapView";
|
||||
|
||||
// Used for animation
|
||||
private static final long ANIMATION_DURATION = 300;
|
||||
|
||||
// Used for saving instance state
|
||||
private static final String STATE_CENTER_COORDINATE = "centerCoordinate";
|
||||
private static final String STATE_CENTER_DIRECTION = "centerDirection";
|
||||
@@ -188,7 +191,7 @@ public class MapView extends SurfaceView {
|
||||
if (!isInEditMode()) {
|
||||
if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH)) {
|
||||
mZoomButtonsController = new ZoomButtonsController(this);
|
||||
mZoomButtonsController.setZoomSpeed(300);
|
||||
mZoomButtonsController.setZoomSpeed(ANIMATION_DURATION);
|
||||
mZoomButtonsController.setOnZoomListener(new OnZoomListener());
|
||||
}
|
||||
|
||||
@@ -213,7 +216,7 @@ public class MapView extends SurfaceView {
|
||||
}
|
||||
|
||||
public void setCenterCoordinate(LonLat centerCoordinate, boolean animated) {
|
||||
double duration = animated ? 0.3 : 0.0;
|
||||
long duration = animated ? ANIMATION_DURATION : 0;
|
||||
mNativeMapView.setLonLat(centerCoordinate, duration);
|
||||
}
|
||||
|
||||
@@ -223,7 +226,7 @@ public class MapView extends SurfaceView {
|
||||
|
||||
public void setCenterCoordinate(LonLatZoom centerCoordinate,
|
||||
boolean animated) {
|
||||
double duration = animated ? 0.3 : 0.0;
|
||||
long duration = animated ? ANIMATION_DURATION : 0;
|
||||
mNativeMapView.setLonLatZoom(centerCoordinate, duration);
|
||||
}
|
||||
|
||||
@@ -243,8 +246,7 @@ public class MapView extends SurfaceView {
|
||||
}
|
||||
|
||||
public void setDirection(double direction, boolean animated) {
|
||||
double duration = animated ? 0.3 : 0.0;
|
||||
|
||||
long duration = animated ? ANIMATION_DURATION : 0;
|
||||
mNativeMapView.setBearing(-direction, duration);
|
||||
}
|
||||
|
||||
@@ -265,7 +267,7 @@ public class MapView extends SurfaceView {
|
||||
}
|
||||
|
||||
public void setZoomLevel(double zoomLevel, boolean animated) {
|
||||
double duration = animated ? 0.3 : 0.0;
|
||||
long duration = animated ? ANIMATION_DURATION : 0;
|
||||
mNativeMapView.setZoom(zoomLevel, duration);
|
||||
}
|
||||
|
||||
@@ -565,10 +567,10 @@ public class MapView extends SurfaceView {
|
||||
mNativeMapView.cancelTransitions();
|
||||
|
||||
if (zoomIn) {
|
||||
mNativeMapView.scaleBy(2.0, x / mScreenDensity, y / mScreenDensity, 0.3);
|
||||
mNativeMapView.scaleBy(2.0, x / mScreenDensity, y / mScreenDensity, ANIMATION_DURATION);
|
||||
} else {
|
||||
// TODO two finger tap zoom out
|
||||
mNativeMapView.scaleBy(0.5, x / mScreenDensity, y / mScreenDensity, 0.3);
|
||||
mNativeMapView.scaleBy(0.5, x / mScreenDensity, y / mScreenDensity, ANIMATION_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -695,7 +697,7 @@ public class MapView extends SurfaceView {
|
||||
// Cancel any animation
|
||||
mNativeMapView.cancelTransitions();
|
||||
|
||||
mNativeMapView.moveBy(velocityX * duration / 2.0 / mScreenDensity, velocityY * duration / 2.0 / mScreenDensity, duration);
|
||||
mNativeMapView.moveBy(velocityX * duration / 2.0 / mScreenDensity, velocityY * duration / 2.0 / mScreenDensity, (long)(duration * 1000.0f));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -234,18 +234,18 @@ class NativeMapView {
|
||||
}
|
||||
|
||||
public void moveBy(double dx, double dy) {
|
||||
moveBy(dx, dy, 0.0);
|
||||
moveBy(dx, dy, 0);
|
||||
}
|
||||
|
||||
public void moveBy(double dx, double dy, double duration) {
|
||||
public void moveBy(double dx, double dy, long duration) {
|
||||
nativeMoveBy(mNativeMapViewPtr, dx, dy, duration);
|
||||
}
|
||||
|
||||
public void setLonLat(LonLat lonLat) {
|
||||
setLonLat(lonLat, 0.0);
|
||||
setLonLat(lonLat, 0);
|
||||
}
|
||||
|
||||
public void setLonLat(LonLat lonLat, double duration) {
|
||||
public void setLonLat(LonLat lonLat, long duration) {
|
||||
nativeSetLonLat(mNativeMapViewPtr, lonLat, duration);
|
||||
}
|
||||
|
||||
@@ -270,10 +270,10 @@ class NativeMapView {
|
||||
}
|
||||
|
||||
public void scaleBy(double ds, double cx, double cy) {
|
||||
scaleBy(ds, cx, cy, 0.0);
|
||||
scaleBy(ds, cx, cy, 0);
|
||||
}
|
||||
|
||||
public void scaleBy(double ds, double cx, double cy, double duration) {
|
||||
public void scaleBy(double ds, double cx, double cy, long duration) {
|
||||
nativeScaleBy(mNativeMapViewPtr, ds, cx, cy, duration);
|
||||
}
|
||||
|
||||
@@ -282,10 +282,10 @@ class NativeMapView {
|
||||
}
|
||||
|
||||
public void setScale(double scale, double cx, double cy) {
|
||||
setScale(scale, cx, cy, 0.0);
|
||||
setScale(scale, cx, cy, 0);
|
||||
}
|
||||
|
||||
public void setScale(double scale, double cx, double cy, double duration) {
|
||||
public void setScale(double scale, double cx, double cy, long duration) {
|
||||
nativeSetScale(mNativeMapViewPtr, scale, cx, cy, duration);
|
||||
}
|
||||
|
||||
@@ -294,10 +294,10 @@ class NativeMapView {
|
||||
}
|
||||
|
||||
public void setZoom(double zoom) {
|
||||
setZoom(zoom, 0.0);
|
||||
setZoom(zoom, 0);
|
||||
}
|
||||
|
||||
public void setZoom(double zoom, double duration) {
|
||||
public void setZoom(double zoom, long duration) {
|
||||
nativeSetZoom(mNativeMapViewPtr, zoom, duration);
|
||||
}
|
||||
|
||||
@@ -306,10 +306,10 @@ class NativeMapView {
|
||||
}
|
||||
|
||||
public void setLonLatZoom(LonLatZoom lonLatZoom) {
|
||||
setLonLatZoom(lonLatZoom, 0.0);
|
||||
setLonLatZoom(lonLatZoom, 0);
|
||||
}
|
||||
|
||||
public void setLonLatZoom(LonLatZoom lonLatZoom, double duration) {
|
||||
public void setLonLatZoom(LonLatZoom lonLatZoom, long duration) {
|
||||
nativeSetLonLatZoom(mNativeMapViewPtr, lonLatZoom, duration);
|
||||
}
|
||||
|
||||
@@ -338,19 +338,19 @@ class NativeMapView {
|
||||
}
|
||||
|
||||
public void rotateBy(double sx, double sy, double ex, double ey) {
|
||||
rotateBy(sx, sy, ex, ey, 0.0);
|
||||
rotateBy(sx, sy, ex, ey, 0);
|
||||
}
|
||||
|
||||
public void rotateBy(double sx, double sy, double ex, double ey,
|
||||
double duration) {
|
||||
long duration) {
|
||||
nativeRotateBy(mNativeMapViewPtr, sx, sy, ex, ey, duration);
|
||||
}
|
||||
|
||||
public void setBearing(double degrees) {
|
||||
setBearing(degrees, 0.0);
|
||||
setBearing(degrees, 0);
|
||||
}
|
||||
|
||||
public void setBearing(double degrees, double duration) {
|
||||
public void setBearing(double degrees, long duration) {
|
||||
nativeSetBearing(mNativeMapViewPtr, degrees, duration);
|
||||
}
|
||||
|
||||
@@ -468,7 +468,7 @@ class NativeMapView {
|
||||
private native List<String> nativeGetClasses(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeSetDefaultTransitionDuration(
|
||||
long nativeMapViewPtr, long milliseconds);
|
||||
long nativeMapViewPtr, long duration);
|
||||
|
||||
private native long nativeGetDefaultTransitionDuration(long nativeMapViewPtr);
|
||||
|
||||
@@ -486,10 +486,10 @@ class NativeMapView {
|
||||
private native void nativeCancelTransitions(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeMoveBy(long nativeMapViewPtr, double dx,
|
||||
double dy, double duration);
|
||||
double dy, long duration);
|
||||
|
||||
private native void nativeSetLonLat(long nativeMapViewPtr, LonLat lonLat,
|
||||
double duration);
|
||||
long duration);
|
||||
|
||||
private native LonLat nativeGetLonLat(long nativeMapViewPtr);
|
||||
|
||||
@@ -500,20 +500,20 @@ class NativeMapView {
|
||||
private native void nativeResetPosition(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeScaleBy(long nativeMapViewPtr, double ds,
|
||||
double cx, double cy, double duration);
|
||||
double cx, double cy, long duration);
|
||||
|
||||
private native void nativeSetScale(long nativeMapViewPtr, double scale,
|
||||
double cx, double cy, double duration);
|
||||
double cx, double cy, long duration);
|
||||
|
||||
private native double nativeGetScale(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeSetZoom(long nativeMapViewPtr, double zoom,
|
||||
double duration);
|
||||
long duration);
|
||||
|
||||
private native double nativeGetZoom(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeSetLonLatZoom(long nativeMapViewPtr,
|
||||
LonLatZoom lonLatZoom, double duration);
|
||||
LonLatZoom lonLatZoom, long duration);
|
||||
|
||||
private native LonLatZoom nativeGetLonLatZoom(long nativeMapViewPtr);
|
||||
|
||||
@@ -528,10 +528,10 @@ class NativeMapView {
|
||||
private native double nativeGetMaxZoom(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeRotateBy(long nativeMapViewPtr, double sx,
|
||||
double sy, double ex, double ey, double duration);
|
||||
double sy, double ex, double ey, long duration);
|
||||
|
||||
private native void nativeSetBearing(long nativeMapViewPtr, double degrees,
|
||||
double duration);
|
||||
long duration);
|
||||
|
||||
private native void nativeSetBearing(long nativeMapViewPtr, double degrees,
|
||||
double cx, double cy);
|
||||
|
||||
@@ -3,16 +3,26 @@
|
||||
'../gyp/common.gypi',
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'androidapp',
|
||||
{ 'target_name': 'android-lib',
|
||||
'product_name': 'mapbox-gl',
|
||||
'type': 'shared_library',
|
||||
'hard_dependency': 1,
|
||||
|
||||
'dependencies': [
|
||||
'../mbgl.gyp:core',
|
||||
'../mbgl.gyp:platform-<(platform_lib)',
|
||||
'../mbgl.gyp:http-<(http_lib)',
|
||||
'../mbgl.gyp:asset-<(asset_lib)',
|
||||
'../mbgl.gyp:cache-<(cache_lib)',
|
||||
],
|
||||
|
||||
'sources': [
|
||||
'./cpp/native_map_view.cpp',
|
||||
'./cpp/jni.cpp',
|
||||
],
|
||||
|
||||
'cflags_cc': [
|
||||
'-I<(boost_root)/include',
|
||||
'<@(boost_cflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(openssl_static_libs)',
|
||||
@@ -50,15 +60,35 @@
|
||||
'libraries': [ '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
'dependencies': [
|
||||
'../mapboxgl.gyp:mbgl-standalone',
|
||||
'../mapboxgl.gyp:mbgl-android',
|
||||
'../mapboxgl.gyp:copy_certificate_bundle',
|
||||
},
|
||||
|
||||
|
||||
{ 'target_name': 'androidapp',
|
||||
'type': 'none',
|
||||
'hard_dependency': 1,
|
||||
|
||||
'variables': {
|
||||
'pwd': '<!(pwd)',
|
||||
},
|
||||
|
||||
'copies': [
|
||||
{
|
||||
'files': [
|
||||
'../common/ca-bundle.crt',
|
||||
'../styles/styles'
|
||||
],
|
||||
'destination': '<(pwd)/java/lib/src/main/assets'
|
||||
},
|
||||
],
|
||||
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'Strip dynamic library',
|
||||
'inputs': [ '<(PRODUCT_DIR)/lib.target/libmapbox-gl.so' ],
|
||||
'outputs': [ '<(pwd)/java/lib/src/main/jniLibs/$(JNIDIR)/libmapbox-gl.so' ],
|
||||
'action': [ '$(STRIP)', '<@(_inputs)', '-o', '<@(_outputs)' ]
|
||||
},
|
||||
],
|
||||
'copies': [{
|
||||
'files': [ '../styles' ],
|
||||
'destination': '<(PRODUCT_DIR)'
|
||||
}],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ NAME=$1
|
||||
export JOBS=2
|
||||
|
||||
export CC=clang CXX=clang++
|
||||
export CXXFLAGS="-Wno-unknown-warning-option -Wno-unused-local-typedefs -Wno-unknown-pragmas ${CXXFLAGS}";
|
||||
|
||||
export MASON_PLATFORM=android
|
||||
|
||||
mkdir ./android/java/app/src/main/res/raw/
|
||||
|
||||
@@ -34,6 +34,7 @@ user_data="#!/bin/bash
|
||||
export TESTMUNK_KEY=$TESTMUNK_KEY
|
||||
export TESTMUNK=$TESTMUNK
|
||||
export MASON_ANDROID_ABI=$MASON_ANDROID_ABI
|
||||
export ANDROID_ABI=$MASON_ANDROID_ABI
|
||||
|
||||
if ./android/scripts/build-$CONFIG.sh $NAME &>../build.log; then
|
||||
echo 'ANDROID BUILD PASSED'
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
#include <mbgl/platform/default/headless_view.hpp>
|
||||
#include <mbgl/platform/default/headless_display.hpp>
|
||||
#include <mbgl/storage/caching_http_file_source.hpp>
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
#include <mbgl/storage/default/sqlite_cache.hpp>
|
||||
|
||||
#if __APPLE__
|
||||
#include <mbgl/platform/darwin/log_nslog.hpp>
|
||||
@@ -35,7 +36,7 @@ int main(int argc, char *argv[]) {
|
||||
int height = 256;
|
||||
double pixelRatio = 1.0;
|
||||
std::string output = "out.png";
|
||||
std::string cache = "cache.sqlite";
|
||||
std::string cache_file = "cache.sqlite";
|
||||
std::vector<std::string> classes;
|
||||
std::string token;
|
||||
|
||||
@@ -51,7 +52,7 @@ int main(int argc, char *argv[]) {
|
||||
("class,c", po::value(&classes)->value_name("name"), "Class name")
|
||||
("token,t", po::value(&token)->value_name("key")->default_value(token), "Mapbox access token")
|
||||
("output,o", po::value(&output)->value_name("file")->default_value(output), "Output file name")
|
||||
("cache,d", po::value(&cache)->value_name("file")->default_value(cache), "Cache database file name")
|
||||
("cache,d", po::value(&cache_file)->value_name("file")->default_value(cache_file), "Cache database file name")
|
||||
;
|
||||
|
||||
try {
|
||||
@@ -74,7 +75,8 @@ int main(int argc, char *argv[]) {
|
||||
Log::Set<StderrLogBackend>();
|
||||
#endif
|
||||
|
||||
CachingHTTPFileSource fileSource(cache);
|
||||
mbgl::SQLiteCache cache(cache_file);
|
||||
mbgl::DefaultFileSource fileSource(&cache);
|
||||
|
||||
// Try to load the token from the environment.
|
||||
if (!token.size()) {
|
||||
@@ -84,14 +86,15 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
// Set access token if present
|
||||
if (token.size()) {
|
||||
fileSource.setAccessToken(std::string(token));
|
||||
}
|
||||
|
||||
HeadlessView view;
|
||||
Map map(view, fileSource);
|
||||
|
||||
// Set access token if present
|
||||
if (token.size()) {
|
||||
map.setAccessToken(std::string(token));
|
||||
}
|
||||
|
||||
map.setStyleJSON(style, ".");
|
||||
map.setClasses(classes);
|
||||
|
||||
|
||||
@@ -3,51 +3,54 @@
|
||||
'../gyp/common.gypi',
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'mbgl-render',
|
||||
{ 'target_name': 'mbgl-render',
|
||||
'product_name': 'mbgl-render',
|
||||
'type': 'executable',
|
||||
|
||||
'dependencies': [
|
||||
'../mbgl.gyp:core',
|
||||
'../mbgl.gyp:platform-<(platform_lib)',
|
||||
'../mbgl.gyp:headless-<(headless_lib)',
|
||||
'../mbgl.gyp:http-<(http_lib)',
|
||||
'../mbgl.gyp:asset-<(asset_lib)',
|
||||
'../mbgl.gyp:cache-<(cache_lib)',
|
||||
'../mbgl.gyp:copy_certificate_bundle',
|
||||
],
|
||||
|
||||
'include_dirs': [
|
||||
'../src',
|
||||
],
|
||||
|
||||
'sources': [
|
||||
'./render.cpp',
|
||||
],
|
||||
|
||||
'variables' : {
|
||||
'cflags': [
|
||||
'<@(uv_cflags)',
|
||||
'<@(png_cflags)',
|
||||
'-I<(boost_root)/include',
|
||||
'cflags_cc': [
|
||||
'<@(glfw3_cflags)',
|
||||
'<@(boost_cflags)',
|
||||
],
|
||||
'ldflags': [
|
||||
'<@(glfw3_ldflags)',
|
||||
'<@(uv_ldflags)',
|
||||
'<@(sqlite3_static_libs)',
|
||||
'<@(sqlite3_ldflags)',
|
||||
'<@(curl_ldflags)',
|
||||
'<@(png_ldflags)',
|
||||
'<@(uv_static_libs)',
|
||||
'-L<(boost_root)/lib',
|
||||
'<@(boost_ldflags)',
|
||||
'-lboost_program_options'
|
||||
],
|
||||
'libraries': [
|
||||
'<@(glfw3_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'conditions': [
|
||||
# add libuv include path and OpenGL libs
|
||||
['OS == "mac"',
|
||||
{
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': ['<@(cflags)'],
|
||||
'OTHER_LDFLAGS': ['<@(ldflags)'],
|
||||
},
|
||||
},
|
||||
{
|
||||
'cflags': ['<@(cflags)'],
|
||||
'libraries': ['<@(ldflags)'],
|
||||
}],
|
||||
],
|
||||
'include_dirs': [ '../src' ],
|
||||
'dependencies': [
|
||||
'../mapboxgl.gyp:mbgl-standalone',
|
||||
'../mapboxgl.gyp:mbgl-headless',
|
||||
'../mapboxgl.gyp:mbgl-<(platform)',
|
||||
'../mapboxgl.gyp:copy_certificate_bundle',
|
||||
['OS == "mac"', {
|
||||
'libraries': [ '<@(libraries)' ],
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
|
||||
}
|
||||
}, {
|
||||
'cflags_cc': [ '<@(cflags_cc)' ],
|
||||
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
67
config/defaults.mk
Normal file
67
config/defaults.mk
Normal file
@@ -0,0 +1,67 @@
|
||||
|
||||
#### Configuration defaults ####################################################
|
||||
|
||||
ENV_osx = MASON_PLATFORM=osx
|
||||
CONFIG_osx = -Dhost=osx -Iconfig/osx.gypi -Dinstall_prefix=$(PREFIX)
|
||||
LIBS_osx = -Dheadless_lib=$(word 1,$(HEADLESS) cgl)
|
||||
LIBS_osx += -Dplatform_lib=$(word 1,$(PLATFORM) osx)
|
||||
LIBS_osx += -Dasset_lib=$(word 1,$(ASSET) fs)
|
||||
LIBS_osx += -Dhttp_lib=$(word 1,$(HTTP) nsurl)
|
||||
LIBS_osx += -Dcache_lib=$(word 1,$(CACHE) sqlite)
|
||||
LIBS_osx += --depth=. -Goutput_dir=.
|
||||
|
||||
|
||||
ENV_ios = MASON_PLATFORM=ios
|
||||
CONFIG_ios = -Dhost=ios -Iconfig/ios.gypi -Dinstall_prefix=$(PREFIX)
|
||||
LIBS_ios = -Dheadless_lib=none
|
||||
LIBS_ios += -Dplatform_lib=$(word 1,$(PLATFORM) ios)
|
||||
LIBS_ios += -Dasset_lib=$(word 1,$(ASSET) fs)
|
||||
LIBS_ios += -Dhttp_lib=$(word 1,$(HTTP) nsurl)
|
||||
LIBS_ios += -Dcache_lib=$(word 1,$(CACHE) sqlite)
|
||||
LIBS_ios += --depth=. -Goutput_dir=.
|
||||
|
||||
|
||||
ENV_linux = MASON_PLATFORM=linux
|
||||
CONFIG_linux = -Dhost=linux -Iconfig/linux.gypi -Dinstall_prefix=$(PREFIX)
|
||||
LIBS_linux = -Dheadless_lib=$(word 1,$(HEADLESS) glx)
|
||||
LIBS_linux += -Dplatform_lib=$(word 1,$(PLATFORM) linux)
|
||||
LIBS_linux += -Dasset_lib=$(word 1,$(ASSET) fs)
|
||||
LIBS_linux += -Dhttp_lib=$(word 1,$(HTTP) curl)
|
||||
LIBS_linux += -Dcache_lib=$(word 1,$(CACHE) sqlite)
|
||||
LIBS_linux += --depth=. -Goutput_dir=.
|
||||
|
||||
ANDROID_ABIS += android-lib-arm-v8
|
||||
ENV_android-arm-v8 = $(shell MASON_ANDROID_ABI=arm-v8 ./scripts/android_env.sh)
|
||||
CONFIG_android-arm-v8 = -Dhost=android -Iconfig/android-arm-v8.gypi
|
||||
|
||||
ANDROID_ABIS += android-lib-arm-v7
|
||||
ENV_android-arm-v7 = $(shell MASON_ANDROID_ABI=arm-v7 ./scripts/android_env.sh)
|
||||
CONFIG_android-arm-v7 = -Dhost=android -Iconfig/android-arm-v7.gypi
|
||||
|
||||
ANDROID_ABIS += android-lib-arm-v5
|
||||
ENV_android-arm-v5 = $(shell MASON_ANDROID_ABI=arm-v5 ./scripts/android_env.sh)
|
||||
CONFIG_android-arm-v5 = -Dhost=android -Iconfig/android-arm-v5.gypi
|
||||
|
||||
ANDROID_ABIS += android-lib-x86
|
||||
ENV_android-x86 = $(shell MASON_ANDROID_ABI=x86 ./scripts/android_env.sh)
|
||||
CONFIG_android-x86 = -Dhost=android -Iconfig/android-x86.gypi
|
||||
|
||||
# OpenSSL build is incomplete.
|
||||
# ANDROID_ABIS += android-lib-x86-64
|
||||
# ENV_android-x86-64 = $(shell MASON_ANDROID_ABI=x86-64 ./scripts/android_env.sh)
|
||||
# CONFIG_android-x86-64 = -Dhost=android -Iconfig/android-x86-64.gypi
|
||||
|
||||
ANDROID_ABIS += android-lib-mips
|
||||
ENV_android-mips = $(shell MASON_ANDROID_ABI=mips ./scripts/android_env.sh)
|
||||
CONFIG_android-mips = -Dhost=android -Iconfig/android-mips.gypi
|
||||
|
||||
ANDROID_ABIS += android-lib-mips-64
|
||||
ENV_android-mips-64 = $(shell MASON_ANDROID_ABI=mips-64 ./scripts/android_env.sh)
|
||||
CONFIG_android-mips-64 = -Dhost=android -Iconfig/android-mips-64.gypi
|
||||
|
||||
LIBS_android = -Dheadless_lib=none
|
||||
LIBS_android += -Dplatform_lib=$(word 1,$(PLATFORM) android)
|
||||
LIBS_android += -Dasset_lib=$(word 1,$(ASSET) zip)
|
||||
LIBS_android += -Dhttp_lib=$(word 1,$(HTTP) curl)
|
||||
LIBS_android += -Dcache_lib=$(word 1,$(CACHE) sqlite)
|
||||
LIBS_android += --depth=. -Goutput_dir=.
|
||||
83
configure
vendored
83
configure
vendored
@@ -3,7 +3,7 @@
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
CONFIG_FILE=${1:-config.gypi}
|
||||
CONFIG_FILE=$1
|
||||
|
||||
if [ `uname -s` = 'Darwin' ]; then
|
||||
MASON_PLATFORM=${MASON_PLATFORM:-osx}
|
||||
@@ -46,11 +46,24 @@ case ${MASON_PLATFORM} in
|
||||
ZLIB_VERSION=system
|
||||
BOOST_VERSION=system
|
||||
NUNICODE_VERSION=1.5.1
|
||||
LIBZIP_VERSION=0.11.2
|
||||
;;
|
||||
esac
|
||||
|
||||
function abort { >&2 echo -e "\033[1m\033[31m$1\033[0m"; exit 1; }
|
||||
|
||||
if [ -z ${CONFIG_FILE} ]; then
|
||||
abort 'You need to specify an output path for the configuration file'
|
||||
fi
|
||||
|
||||
if [[ ${MASON_PLATFORM} = 'android' && -z ${MASON_ANDROID_ABI} ]]; then
|
||||
abort 'You need to specify an ABI for android platforms'
|
||||
fi
|
||||
|
||||
echo -n "MASON_PLATFORM=${MASON_PLATFORM} "
|
||||
if [ ${MASON_PLATFORM} = 'android' ]; then echo -n "MASON_ANDROID_ABI=${MASON_ANDROID_ABI} " ; fi
|
||||
echo $0 $@
|
||||
|
||||
PYTHON=`which python || abort 'Cannot find python'`
|
||||
|
||||
>&2 echo -en "\033[1m\033[32m* Using "
|
||||
@@ -72,7 +85,7 @@ LN=$'\n'
|
||||
CONFIG="# Do not edit. Generated by the configure script.
|
||||
{
|
||||
'target_defaults': {
|
||||
'cflags': [],
|
||||
'cflags%': [],
|
||||
'default_configuration': 'Release',
|
||||
'defines': [],
|
||||
'include_dirs': [],
|
||||
@@ -84,79 +97,78 @@ CONFIG="# Do not edit. Generated by the configure script.
|
||||
|
||||
if [ ! -z ${BOOST_VERSION} ]; then
|
||||
mason install boost ${BOOST_VERSION}
|
||||
CONFIG+=" 'boost_root': '$(mason prefix boost ${BOOST_VERSION})',"$LN
|
||||
CONFIG+=" 'boost_cflags%': $(quote_flags $(mason cflags boost ${BOOST_VERSION})),"$LN
|
||||
CONFIG+=" 'boost_ldflags%': $(quote_flags $(mason ldflags boost ${BOOST_VERSION})),"$LN
|
||||
fi
|
||||
|
||||
if [ ! -z ${OPENSSL_VERSION} ]; then
|
||||
mason install openssl ${OPENSSL_VERSION}
|
||||
CONFIG+=" 'openssl_static_libs': $(quote_flags $(mason static_libs openssl ${OPENSSL_VERSION})),"$LN
|
||||
CONFIG+=" 'openssl_cflags': $(quote_flags $(mason cflags openssl ${OPENSSL_VERSION})),"$LN
|
||||
CONFIG+=" 'openssl_ldflags': $(quote_flags $(mason ldflags openssl ${OPENSSL_VERSION})),"$LN
|
||||
CONFIG+=" 'openssl_static_libs%': $(quote_flags $(mason static_libs openssl ${OPENSSL_VERSION})),"$LN
|
||||
CONFIG+=" 'openssl_cflags%': $(quote_flags $(mason cflags openssl ${OPENSSL_VERSION})),"$LN
|
||||
CONFIG+=" 'openssl_ldflags%': $(quote_flags $(mason ldflags openssl ${OPENSSL_VERSION})),"$LN
|
||||
fi
|
||||
|
||||
if [ ! -z ${LIBCURL_VERSION} ]; then
|
||||
mason install libcurl ${LIBCURL_VERSION}
|
||||
CONFIG+=" 'curl_static_libs': $(quote_flags $(mason static_libs libcurl ${LIBCURL_VERSION})),"$LN
|
||||
CONFIG+=" 'curl_cflags': $(quote_flags $(mason cflags libcurl ${LIBCURL_VERSION})),"$LN
|
||||
CONFIG+=" 'curl_ldflags': $(quote_flags $(mason ldflags libcurl ${LIBCURL_VERSION})),"$LN
|
||||
else
|
||||
CONFIG+=" 'curl_static_libs': [],"$LN
|
||||
CONFIG+=" 'curl_static_libs%': $(quote_flags $(mason static_libs libcurl ${LIBCURL_VERSION})),"$LN
|
||||
CONFIG+=" 'curl_cflags%': $(quote_flags $(mason cflags libcurl ${LIBCURL_VERSION})),"$LN
|
||||
CONFIG+=" 'curl_ldflags%': $(quote_flags $(mason ldflags libcurl ${LIBCURL_VERSION})),"$LN
|
||||
fi
|
||||
|
||||
if [ ! -z ${GLFW_VERSION} ]; then
|
||||
mason install glfw ${GLFW_VERSION}
|
||||
CONFIG+=" 'glfw3_static_libs': $(quote_flags $(mason static_libs glfw ${GLFW_VERSION})),"$LN
|
||||
CONFIG+=" 'glfw3_cflags': $(quote_flags $(mason cflags glfw ${GLFW_VERSION})),"$LN
|
||||
CONFIG+=" 'glfw3_ldflags': $(quote_flags $(mason ldflags glfw ${GLFW_VERSION})),"$LN
|
||||
CONFIG+=" 'glfw3_static_libs%': $(quote_flags $(mason static_libs glfw ${GLFW_VERSION})),"$LN
|
||||
CONFIG+=" 'glfw3_cflags%': $(quote_flags $(mason cflags glfw ${GLFW_VERSION})),"$LN
|
||||
CONFIG+=" 'glfw3_ldflags%': $(quote_flags $(mason ldflags glfw ${GLFW_VERSION})),"$LN
|
||||
fi
|
||||
|
||||
if [ ! -z ${LIBPNG_VERSION} ]; then
|
||||
mason install libpng ${LIBPNG_VERSION}
|
||||
CONFIG+=" 'png_static_libs': $(quote_flags $(mason static_libs libpng ${LIBPNG_VERSION})),"$LN
|
||||
CONFIG+=" 'png_cflags': $(quote_flags $(mason cflags libpng ${LIBPNG_VERSION})),"$LN
|
||||
CONFIG+=" 'png_ldflags': $(quote_flags $(mason ldflags libpng ${LIBPNG_VERSION})),"$LN
|
||||
CONFIG+=" 'png_static_libs%': $(quote_flags $(mason static_libs libpng ${LIBPNG_VERSION})),"$LN
|
||||
CONFIG+=" 'png_cflags%': $(quote_flags $(mason cflags libpng ${LIBPNG_VERSION})),"$LN
|
||||
CONFIG+=" 'png_ldflags%': $(quote_flags $(mason ldflags libpng ${LIBPNG_VERSION})),"$LN
|
||||
fi
|
||||
|
||||
if [ ! -z ${LIBJPEG_VERSION} ]; then
|
||||
mason install jpeg ${LIBJPEG_VERSION}
|
||||
CONFIG+=" 'jpeg_static_libs': $(quote_flags $(mason static_libs jpeg ${LIBJPEG_VERSION})),"$LN
|
||||
CONFIG+=" 'jpeg_cflags': $(quote_flags $(mason cflags jpeg ${LIBJPEG_VERSION})),"$LN
|
||||
CONFIG+=" 'jpeg_ldflags': $(quote_flags $(mason ldflags jpeg ${LIBJPEG_VERSION})),"$LN
|
||||
CONFIG+=" 'jpeg_static_libs%': $(quote_flags $(mason static_libs jpeg ${LIBJPEG_VERSION})),"$LN
|
||||
CONFIG+=" 'jpeg_cflags%': $(quote_flags $(mason cflags jpeg ${LIBJPEG_VERSION})),"$LN
|
||||
CONFIG+=" 'jpeg_ldflags%': $(quote_flags $(mason ldflags jpeg ${LIBJPEG_VERSION})),"$LN
|
||||
fi
|
||||
|
||||
if [ ! -z ${SQLITE_VERSION} ]; then
|
||||
mason install sqlite ${SQLITE_VERSION}
|
||||
CONFIG+=" 'sqlite3_static_libs': $(quote_flags $(mason static_libs sqlite ${SQLITE_VERSION})),"$LN
|
||||
CONFIG+=" 'sqlite3_cflags': $(quote_flags $(mason cflags sqlite ${SQLITE_VERSION})),"$LN
|
||||
CONFIG+=" 'sqlite3_ldflags': $(quote_flags $(mason ldflags sqlite ${SQLITE_VERSION})),"$LN
|
||||
CONFIG+=" 'sqlite3_static_libs%': $(quote_flags $(mason static_libs sqlite ${SQLITE_VERSION})),"$LN
|
||||
CONFIG+=" 'sqlite3_cflags%': $(quote_flags $(mason cflags sqlite ${SQLITE_VERSION})),"$LN
|
||||
CONFIG+=" 'sqlite3_ldflags%': $(quote_flags $(mason ldflags sqlite ${SQLITE_VERSION})),"$LN
|
||||
fi
|
||||
|
||||
if [ ! -z ${LIBUV_VERSION} ]; then
|
||||
mason install libuv ${LIBUV_VERSION}
|
||||
CONFIG+=" 'uv_static_libs': $(quote_flags $(mason static_libs libuv ${LIBUV_VERSION})),"$LN
|
||||
CONFIG+=" 'uv_cflags': $(quote_flags $(mason cflags libuv ${LIBUV_VERSION})),"$LN
|
||||
CONFIG+=" 'uv_ldflags': $(quote_flags $(mason ldflags libuv ${LIBUV_VERSION})),"$LN
|
||||
CONFIG+=" 'uv_static_libs%': $(quote_flags $(mason static_libs libuv ${LIBUV_VERSION})),"$LN
|
||||
CONFIG+=" 'uv_cflags%': $(quote_flags $(mason cflags libuv ${LIBUV_VERSION})),"$LN
|
||||
CONFIG+=" 'uv_ldflags%': $(quote_flags $(mason ldflags libuv ${LIBUV_VERSION})),"$LN
|
||||
fi
|
||||
|
||||
if [ ! -z ${ZLIB_VERSION} ]; then
|
||||
mason install zlib ${ZLIB_VERSION}
|
||||
CONFIG+=" 'zlib_static_libs': $(quote_flags $(mason static_libs zlib ${ZLIB_VERSION})),"$LN
|
||||
CONFIG+=" 'zlib_cflags': $(quote_flags $(mason cflags zlib ${ZLIB_VERSION})),"$LN
|
||||
CONFIG+=" 'zlib_ldflags': $(quote_flags $(mason ldflags zlib ${ZLIB_VERSION})),"$LN
|
||||
CONFIG+=" 'zlib_static_libs%': $(quote_flags $(mason static_libs zlib ${ZLIB_VERSION})),"$LN
|
||||
CONFIG+=" 'zlib_cflags%': $(quote_flags $(mason cflags zlib ${ZLIB_VERSION})),"$LN
|
||||
CONFIG+=" 'zlib_ldflags%': $(quote_flags $(mason ldflags zlib ${ZLIB_VERSION})),"$LN
|
||||
fi
|
||||
|
||||
if [ ! -z ${NUNICODE_VERSION} ]; then
|
||||
mason install nunicode ${NUNICODE_VERSION}
|
||||
CONFIG+=" 'nu_static_libs': $(quote_flags $(mason static_libs nunicode ${NUNICODE_VERSION})),"$LN
|
||||
CONFIG+=" 'nu_cflags': $(quote_flags $(mason cflags nunicode ${NUNICODE_VERSION})),"$LN
|
||||
CONFIG+=" 'nu_ldflags': $(quote_flags $(mason ldflags nunicode ${NUNICODE_VERSION})),"$LN
|
||||
CONFIG+=" 'nu_static_libs%': $(quote_flags $(mason static_libs nunicode ${NUNICODE_VERSION})),"$LN
|
||||
CONFIG+=" 'nu_cflags%': $(quote_flags $(mason cflags nunicode ${NUNICODE_VERSION})),"$LN
|
||||
CONFIG+=" 'nu_ldflags%': $(quote_flags $(mason ldflags nunicode ${NUNICODE_VERSION})),"$LN
|
||||
fi
|
||||
|
||||
if [ ! -z ${LIBZIP_VERSION} ]; then
|
||||
mason install libzip ${LIBZIP_VERSION}
|
||||
CONFIG+=" 'zip_static_libs': $(quote_flags $(mason static_libs libzip ${LIBZIP_VERSION})),"$LN
|
||||
CONFIG+=" 'zip_cflags': $(quote_flags $(mason cflags libzip ${LIBZIP_VERSION})),"$LN
|
||||
CONFIG+=" 'zip_ldflags': $(quote_flags $(mason ldflags libzip ${LIBZIP_VERSION})),"$LN
|
||||
CONFIG+=" 'zip_static_libs%': $(quote_flags $(mason static_libs libzip ${LIBZIP_VERSION})),"$LN
|
||||
CONFIG+=" 'zip_cflags%': $(quote_flags $(mason cflags libzip ${LIBZIP_VERSION})),"$LN
|
||||
CONFIG+=" 'zip_ldflags%': $(quote_flags $(mason ldflags libzip ${LIBZIP_VERSION})),"$LN
|
||||
fi
|
||||
|
||||
CONFIG+=" }
|
||||
@@ -164,5 +176,4 @@ CONFIG+=" }
|
||||
"
|
||||
|
||||
echo "${CONFIG}" > ${CONFIG_FILE}
|
||||
|
||||
cat ${CONFIG_FILE}
|
||||
|
||||
52
gyp/asset-fs.gypi
Normal file
52
gyp/asset-fs.gypi
Normal file
@@ -0,0 +1,52 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'asset-fs',
|
||||
'product_name': 'mbgl-asset-fs',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
|
||||
'sources': [
|
||||
'../platform/default/asset_request_fs.cpp',
|
||||
],
|
||||
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(uv_cflags)',
|
||||
'<@(boost_cflags)',
|
||||
],
|
||||
'ldflags': [
|
||||
'<@(uv_ldflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(uv_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
},
|
||||
}, {
|
||||
'cflags_cc': [ '<@(cflags_cc)' ],
|
||||
}],
|
||||
],
|
||||
|
||||
'link_settings': {
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'libraries': [ '<@(libraries)' ],
|
||||
'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
62
gyp/asset-zip.gypi
Normal file
62
gyp/asset-zip.gypi
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'asset-zip',
|
||||
'product_name': 'mbgl-asset-zip',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
|
||||
'sources': [
|
||||
'../platform/default/asset_request_zip.cpp',
|
||||
'../platform/default/uv_zip.c',
|
||||
],
|
||||
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
|
||||
'variables': {
|
||||
'cflags': [
|
||||
'<@(uv_cflags)',
|
||||
'<@(zip_cflags)',
|
||||
],
|
||||
'cflags_cc': [
|
||||
'<@(uv_cflags)',
|
||||
'<@(zip_cflags)',
|
||||
'<@(boost_cflags)',
|
||||
],
|
||||
'ldflags': [
|
||||
'<@(uv_ldflags)',
|
||||
'<@(zip_ldflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(uv_static_libs)',
|
||||
'<@(zip_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CFLAGS': [ '<@(cflags)' ],
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
},
|
||||
}, {
|
||||
'cflags': [ '<@(cflags)' ],
|
||||
'cflags_cc': [ '<@(cflags_cc)' ],
|
||||
}],
|
||||
],
|
||||
|
||||
'link_settings': {
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'libraries': [ '<@(libraries)' ],
|
||||
'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
64
gyp/cache-sqlite.gypi
Normal file
64
gyp/cache-sqlite.gypi
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'cache-sqlite',
|
||||
'product_name': 'mbgl-cache-sqlite',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
|
||||
'sources': [
|
||||
'../platform/default/sqlite_cache.cpp',
|
||||
'../platform/default/sqlite3.hpp',
|
||||
'../platform/default/sqlite3.cpp',
|
||||
'../platform/default/compression.hpp',
|
||||
'../platform/default/compression.cpp',
|
||||
],
|
||||
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(uv_cflags)',
|
||||
'<@(sqlite3_cflags)',
|
||||
],
|
||||
'ldflags': [
|
||||
'<@(uv_ldflags)',
|
||||
'<@(sqlite3_ldflags)',
|
||||
'<@(zlib_ldflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(uv_static_libs)',
|
||||
'<@(sqlite3_static_libs)',
|
||||
'<@(zlib_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
},
|
||||
}, {
|
||||
'cflags_cc': [ '<@(cflags_cc)' ],
|
||||
}],
|
||||
],
|
||||
|
||||
'link_settings': {
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'libraries': [ '<@(libraries)' ],
|
||||
'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
},
|
||||
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [ '../include' ],
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,19 +1,18 @@
|
||||
{
|
||||
'variables': {
|
||||
'install_prefix%': '',
|
||||
'standalone_product_dir':'<!@(pwd)/build'
|
||||
},
|
||||
'target_defaults': {
|
||||
'default_configuration': 'Release',
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'xcode_settings': {
|
||||
'MACOSX_DEPLOYMENT_TARGET':'10.9',
|
||||
'MACOSX_DEPLOYMENT_TARGET': '10.9',
|
||||
'CLANG_CXX_LIBRARY': 'libc++',
|
||||
'CLANG_CXX_LANGUAGE_STANDARD':'c++11',
|
||||
'CLANG_CXX_LANGUAGE_STANDARD': 'c++11',
|
||||
'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
|
||||
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
|
||||
'GCC_ENABLE_CPP_RTTI':'YES',
|
||||
'GCC_ENABLE_CPP_RTTI': 'YES',
|
||||
'OTHER_CPLUSPLUSFLAGS': [
|
||||
'-Werror',
|
||||
'-Wall',
|
||||
@@ -22,18 +21,27 @@
|
||||
'-Wno-variadic-macros',
|
||||
'-frtti',
|
||||
'-fexceptions',
|
||||
'-Wno-error=unused-parameter',
|
||||
],
|
||||
'GCC_WARN_PEDANTIC': 'YES',
|
||||
'GCC_WARN_UNINITIALIZED_AUTOS': 'YES_AGGRESSIVE',
|
||||
},
|
||||
}, {
|
||||
'cflags_cc': [
|
||||
'-std=c++11',
|
||||
'-Werror',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wshadow',
|
||||
'-Wno-variadic-macros',
|
||||
'-Wno-error=unused-parameter',
|
||||
'-Wno-unknown-warning-option',
|
||||
'-frtti',
|
||||
'-fexceptions',
|
||||
],
|
||||
}],
|
||||
['OS=="linux"', {
|
||||
'cflags_cc': [
|
||||
'-Wno-unknown-pragmas', # We are using '#pragma mark', but it is only available on Darwin.
|
||||
'-Wno-literal-suffix', # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61653
|
||||
'-Wno-unknown-warning-option',
|
||||
'-Wno-error=unused-parameter',
|
||||
],
|
||||
}],
|
||||
],
|
||||
@@ -43,14 +51,31 @@
|
||||
['OS=="mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '-fPIC' ],
|
||||
'SKIP_INSTALL': 'YES',
|
||||
},
|
||||
}, {
|
||||
'cflags_cc': [ '-fPIC' ],
|
||||
}]
|
||||
}],
|
||||
['host == "ios"', {
|
||||
'xcode_settings': {
|
||||
'SDKROOT': 'iphoneos',
|
||||
'SUPPORTED_PLATFORMS': 'iphonesimulator iphoneos',
|
||||
'IPHONEOS_DEPLOYMENT_TARGET': '7.0',
|
||||
'TARGETED_DEVICE_FAMILY': '1,2',
|
||||
'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
|
||||
'CODE_SIGN_IDENTITY': 'iPhone Developer',
|
||||
},
|
||||
'configurations': {
|
||||
'Release': {
|
||||
'xcode_settings': {
|
||||
'ARCHS': [ "armv7", "armv7s", "arm64", "i386", "x86_64" ],
|
||||
},
|
||||
},
|
||||
},
|
||||
}],
|
||||
],
|
||||
}],
|
||||
],
|
||||
'cflags_cc': [ '-std=c++11', '-Werror', '-Wall', '-Wextra', '-Wshadow', '-frtti', '-fexceptions' ],
|
||||
'configurations': {
|
||||
'Debug': {
|
||||
'cflags_cc': [ '-g', '-O0', '-fno-omit-frame-pointer','-fwrapv', '-fstack-protector-all', '-fno-common' ],
|
||||
@@ -64,12 +89,12 @@
|
||||
}
|
||||
},
|
||||
'Release': {
|
||||
'cflags_cc': [ '-O3' ],
|
||||
'cflags_cc': [ '-g', '-O3' ],
|
||||
'defines': [ 'NDEBUG' ],
|
||||
'xcode_settings': {
|
||||
'GCC_OPTIMIZATION_LEVEL': '3',
|
||||
'GCC_GENERATE_DEBUGGING_SYMBOLS': 'NO',
|
||||
'DEAD_CODE_STRIPPING': 'YES',
|
||||
'GCC_GENERATE_DEBUGGING_SYMBOLS': 'YES',
|
||||
'DEAD_CODE_STRIPPING': 'NO',
|
||||
'GCC_INLINES_ARE_PRIVATE_EXTERN': 'NO'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,26 +1,17 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'mbgl-core',
|
||||
{ 'target_name': 'core',
|
||||
'product_name': 'mbgl-core',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'shaders',
|
||||
'version',
|
||||
'shaders',
|
||||
'version',
|
||||
],
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(uv_cflags)',
|
||||
'<@(sqlite3_cflags)',
|
||||
'<@(zlib_cflags)',
|
||||
'-I<(boost_root)/include',
|
||||
],
|
||||
'cflags': [
|
||||
'<@(uv_cflags)','-fPIC'
|
||||
],
|
||||
},
|
||||
|
||||
'sources': [
|
||||
'<!@(find src -name "*.hpp")',
|
||||
'<!@(find src -name "*.cpp")',
|
||||
'<!@(find src -name "*.c")',
|
||||
'<!@(find src -name "*.h")',
|
||||
@@ -29,67 +20,57 @@
|
||||
'<!@(find src -name "*.glsl")',
|
||||
'bin/style.json'
|
||||
],
|
||||
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
'../src',
|
||||
],
|
||||
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(uv_cflags)',
|
||||
'<@(boost_cflags)',
|
||||
],
|
||||
'cflags': [
|
||||
'<@(uv_cflags)',
|
||||
'-fPIC'
|
||||
],
|
||||
'ldflags': [
|
||||
'<@(uv_ldflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(uv_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
'OTHER_CFLAGS': [ '<@(cflags)' ],
|
||||
'SKIP_INSTALL': 'YES'
|
||||
},
|
||||
}, {
|
||||
'cflags_cc': [ '<@(cflags_cc)' ],
|
||||
'cflags': [ '<@(cflags)' ],
|
||||
}]
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'mbgl-standalone',
|
||||
'type': 'none',
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'mbgl-core'
|
||||
],
|
||||
'variables': {
|
||||
'core_lib':'<(PRODUCT_DIR)/libmbgl-core.a',
|
||||
'standalone_lib':'<(standalone_product_dir)/libmbgl.a'
|
||||
|
||||
'link_settings': {
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'libraries': [ '<@(libraries)' ],
|
||||
'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
},
|
||||
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [ '<(standalone_lib)' ],
|
||||
}
|
||||
}, {
|
||||
'ldflags': [ '<(standalone_lib)' ],
|
||||
}]
|
||||
],
|
||||
},
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'build standalone core lib',
|
||||
'inputs': [
|
||||
'<(core_lib)'
|
||||
],
|
||||
'outputs': [
|
||||
'<(standalone_lib)'
|
||||
],
|
||||
'action': [
|
||||
'./gyp/merge_static_libs.py',
|
||||
'<(standalone_lib)',
|
||||
'<@(uv_static_libs)',
|
||||
'<@(curl_static_libs)',
|
||||
'<@(sqlite3_static_libs)',
|
||||
'<(core_lib)'
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
18
gyp/headless-cgl.gypi
Normal file
18
gyp/headless-cgl.gypi
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'headless-cgl',
|
||||
'product_name': 'mbgl-headless-cgl',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
|
||||
'sources': [
|
||||
'../platform/default/headless_view.cpp',
|
||||
'../platform/default/headless_display.cpp',
|
||||
],
|
||||
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
18
gyp/headless-glx.gypi
Normal file
18
gyp/headless-glx.gypi
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'headless-glx',
|
||||
'product_name': 'mbgl-headless-glx',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
|
||||
'sources': [
|
||||
'../platform/default/headless_view.cpp',
|
||||
'../platform/default/headless_display.cpp',
|
||||
],
|
||||
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
55
gyp/http-curl.gypi
Normal file
55
gyp/http-curl.gypi
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'http-curl',
|
||||
'product_name': 'mbgl-http-curl',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
|
||||
'sources': [
|
||||
'../platform/default/http_request_curl.cpp',
|
||||
],
|
||||
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(uv_cflags)',
|
||||
'<@(curl_cflags)',
|
||||
'<@(boost_cflags)',
|
||||
],
|
||||
'ldflags': [
|
||||
'<@(uv_ldflags)',
|
||||
'<@(curl_ldflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(uv_static_libs)',
|
||||
'<@(curl_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
},
|
||||
}, {
|
||||
'cflags_cc': [ '<@(cflags_cc)' ],
|
||||
}],
|
||||
],
|
||||
|
||||
'link_settings': {
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'libraries': [ '<@(libraries)' ],
|
||||
'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
43
gyp/http-nsurl.gypi
Normal file
43
gyp/http-nsurl.gypi
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'http-nsurl',
|
||||
'product_name': 'mbgl-http-nsurl',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
|
||||
'sources': [
|
||||
'../platform/darwin/http_request_nsurl.mm',
|
||||
],
|
||||
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(uv_cflags)',
|
||||
],
|
||||
'ldflags': [
|
||||
'-framework Foundation', # For NSURLRequest
|
||||
'<@(uv_ldflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(uv_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
'CLANG_ENABLE_OBJC_ARC': 'NO',
|
||||
},
|
||||
|
||||
'link_settings': {
|
||||
'libraries': [ '<@(libraries)' ],
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -6,66 +6,45 @@
|
||||
'type': 'none',
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'mbgl-core',
|
||||
'mbgl-standalone',
|
||||
'mbgl-headless',
|
||||
'mbgl-<(platform)',
|
||||
],
|
||||
'copies': [
|
||||
{ 'files': [ '<(standalone_product_dir)/libmbgl.a' ], 'destination': '<(install_prefix)/lib' },
|
||||
{ 'files': [ '<(PRODUCT_DIR)/libmbgl-core.a' ], 'destination': '<(install_prefix)/lib' },
|
||||
{ 'files': [ '<(PRODUCT_DIR)/libmbgl-headless.a' ], 'destination': '<(install_prefix)/lib' },
|
||||
{ 'files': [ '<(PRODUCT_DIR)/libmbgl-<(platform).a' ], 'destination': '<(install_prefix)/lib' },
|
||||
{ 'files': [ '../include/mbgl' ], 'destination': '<(install_prefix)/include' },
|
||||
],
|
||||
'variables': {
|
||||
'conditions': [
|
||||
['OS == "linux"', {
|
||||
'other_ldflags': [
|
||||
'<@(nu_static_libs)',
|
||||
'<@(png_static_libs)',
|
||||
'<@(jpeg_static_libs)',
|
||||
'<@(glfw3_static_libs)',
|
||||
'<@(glfw3_ldflags)',
|
||||
]
|
||||
}, {
|
||||
'other_ldflags': [ ]
|
||||
}]
|
||||
],
|
||||
},
|
||||
'actions': [
|
||||
{ 'action_name': 'mbgl-config',
|
||||
'inputs': [
|
||||
'../utils/mbgl-config/mbgl-config.template.sh',
|
||||
'../utils/mbgl-config/build.sh',
|
||||
],
|
||||
'outputs': [
|
||||
'<(install_prefix)/bin/mbgl-config',
|
||||
],
|
||||
'action': [
|
||||
'./utils/mbgl-config/build.sh',
|
||||
'<(install_prefix)',
|
||||
'<(platform)',
|
||||
'<@(sqlite3_static_libs)',
|
||||
'<@(sqlite3_ldflags)',
|
||||
'<@(curl_ldflags)',
|
||||
'<@(png_ldflags)',
|
||||
'<@(other_ldflags)'
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{ 'target_name': 'copy_version',
|
||||
'type': 'none',
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'install',
|
||||
'core',
|
||||
'platform-<(platform_lib)',
|
||||
'http-<(http_lib)',
|
||||
'asset-<(asset_lib)',
|
||||
'cache-<(cache_lib)',
|
||||
'headless-<(headless_lib)',
|
||||
'standalone',
|
||||
],
|
||||
|
||||
'copies': [
|
||||
{ 'files': [ '<(PRODUCT_DIR)/libmbgl.a' ], 'destination': '<(install_prefix)/lib' },
|
||||
{ 'files': [ '<(SHARED_INTERMEDIATE_DIR)/include/mbgl/util/version.hpp' ], 'destination': '<(install_prefix)/include/mbgl/util' },
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
'actions': [
|
||||
{
|
||||
'action_name': 'Copy header files',
|
||||
'inputs': [ '../include/mbgl/mbgl.hpp' ],
|
||||
'outputs': [ '../include/mbgl/mbgl.hpp' ],
|
||||
'action': [ 'cp', '-r', 'include', '<(install_prefix)/' ]
|
||||
},
|
||||
|
||||
{ 'action_name': 'mbgl-config',
|
||||
'inputs': [
|
||||
'../utils/mbgl-config/mbgl-config.template.sh',
|
||||
'../utils/mbgl-config/build.sh',
|
||||
],
|
||||
'outputs': [
|
||||
'<(install_prefix)/bin/mbgl-config',
|
||||
],
|
||||
'action': [
|
||||
'./utils/mbgl-config/build.sh',
|
||||
'<(install_prefix)',
|
||||
'<(PRODUCT_DIR)/libmbgl.a.ldflags',
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
}],
|
||||
],
|
||||
}
|
||||
|
||||
47
gyp/link.py
Executable file
47
gyp/link.py
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import os
|
||||
from merge_static_libs import MergeLibs
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
out_lib = ''
|
||||
in_libs = []
|
||||
flags = []
|
||||
|
||||
i = 0
|
||||
l = len(args)
|
||||
while i < l:
|
||||
arg = args[i]
|
||||
|
||||
if arg[0:2] == '-l':
|
||||
flags.append(arg)
|
||||
elif arg[0:2] == '-L':
|
||||
flags.append(arg)
|
||||
elif arg == '-arch':
|
||||
i += 1
|
||||
elif arg == '-framework':
|
||||
i += 1
|
||||
flags.append(arg + ' ' + args[i])
|
||||
elif arg == '-o':
|
||||
i += 1
|
||||
out_lib = args[i]
|
||||
elif arg[0] != '-':
|
||||
in_libs.append(arg)
|
||||
else:
|
||||
print 'Ignored linker directive: ' + arg
|
||||
|
||||
i += 1
|
||||
|
||||
flags.reverse()
|
||||
unique_flags = []
|
||||
for flag in flags:
|
||||
if flag not in unique_flags:
|
||||
unique_flags.append(flag)
|
||||
unique_flags.reverse()
|
||||
|
||||
with open(out_lib + '.ldflags', 'w+') as f:
|
||||
f.write(' '.join(unique_flags));
|
||||
|
||||
MergeLibs(in_libs, out_lib)
|
||||
6
gyp/load.gypi
Normal file
6
gyp/load.gypi
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
'conditions': [
|
||||
['platform_library == "mbglosx"', {
|
||||
}],
|
||||
],
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'mbgl-headless',
|
||||
'product_name': 'mbgl-headless',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(uv_cflags)',
|
||||
],
|
||||
'cflags': [
|
||||
'<@(uv_cflags)',
|
||||
],
|
||||
},
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
'OTHER_CFLAGS': [ '<@(cflags)' ],
|
||||
}
|
||||
}, {
|
||||
'cflags_cc': [ '<@(cflags_cc)' ],
|
||||
'cflags': [ '<@(cflags)' ],
|
||||
}]
|
||||
],
|
||||
'sources': [
|
||||
'../platform/default/headless_view.cpp',
|
||||
'../platform/default/headless_display.cpp',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
{
|
||||
'target_defaults': {
|
||||
'target_conditions': [
|
||||
['_type == "static_library"', {
|
||||
'xcode_settings': {
|
||||
'SDKROOT': 'iphoneos',
|
||||
'SUPPORTED_PLATFORMS': 'iphonesimulator iphoneos',
|
||||
'CLANG_CXX_LIBRARY': 'libc++',
|
||||
'CLANG_CXX_LANGUAGE_STANDARD':'c++11',
|
||||
'IPHONEOS_DEPLOYMENT_TARGET':'7.0',
|
||||
'TARGETED_DEVICE_FAMILY': '1,2',
|
||||
'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
|
||||
'CLANG_ENABLE_OBJC_ARC': 'YES',
|
||||
'CODE_SIGN_IDENTITY': 'iPhone Developer',
|
||||
'SKIP_INSTALL': 'YES'
|
||||
},
|
||||
'configurations': {
|
||||
'Release': {
|
||||
'xcode_settings': {
|
||||
'ARCHS': [ "armv7", "armv7s", "arm64", "i386", "x86_64" ],
|
||||
},
|
||||
},
|
||||
},
|
||||
}],
|
||||
],
|
||||
},
|
||||
'targets': [
|
||||
{ 'target_name': 'mbgl-ios',
|
||||
'product_name': 'mbgl-ios',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'version',
|
||||
],
|
||||
'sources': [
|
||||
'../platform/ios/cache_database_library.mm',
|
||||
'../platform/darwin/log_nslog.mm',
|
||||
'../platform/darwin/string_nsstring.mm',
|
||||
'../platform/darwin/http_request_baton_cocoa.mm',
|
||||
'../platform/darwin/application_root.mm',
|
||||
'../platform/darwin/image.mm',
|
||||
'../platform/default/asset_request_libuv.cpp',
|
||||
],
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
'../src',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(uv_cflags)' ],
|
||||
},
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [
|
||||
'-framework ImageIO',
|
||||
'-framework MobileCoreServices',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
'conditions': [
|
||||
['platform == "osx"', {
|
||||
'includes': ['mbgl-osx.gypi'],
|
||||
'variables': { 'platform_library': 'mbgl-osx' },
|
||||
}],
|
||||
['platform == "ios"', {
|
||||
'includes': ['mbgl-ios.gypi'],
|
||||
'variables': { 'platform_library': 'mbgl-ios' },
|
||||
}],
|
||||
['platform == "linux"', {
|
||||
'includes': ['mbgl-linux.gypi'],
|
||||
'variables': { 'platform_library': 'mbgl-linux' },
|
||||
}],
|
||||
['platform == "android"', {
|
||||
'includes': ['mbgl-android.gypi'],
|
||||
'variables': { 'platform_library': 'mbgl-android' },
|
||||
}],
|
||||
],
|
||||
}
|
||||
20
gyp/none.gypi
Normal file
20
gyp/none.gypi
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'http-none',
|
||||
'product_name': 'mbgl-http-none',
|
||||
'type': 'none',
|
||||
},
|
||||
{ 'target_name': 'asset-none',
|
||||
'product_name': 'mbgl-asset-none',
|
||||
'type': 'none',
|
||||
},
|
||||
{ 'target_name': 'cache-none',
|
||||
'product_name': 'mbgl-cache-none',
|
||||
'type': 'none',
|
||||
},
|
||||
{ 'target_name': 'headless-none',
|
||||
'product_name': 'mbgl-headless-none',
|
||||
'type': 'none',
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,81 +1,75 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'mbgl-android',
|
||||
'product_name': 'mbgl-android',
|
||||
{ 'target_name': 'platform-android',
|
||||
'product_name': 'mbgl-platform-android',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'version',
|
||||
],
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(png_cflags)',
|
||||
'<@(jpeg_cflags)',
|
||||
'<@(uv_cflags)',
|
||||
'<@(curl_cflags)',
|
||||
'<@(nu_cflags)',
|
||||
'<@(zip_cflags)',
|
||||
'<@(openssl_cflags)',
|
||||
'-I<(boost_root)/include',
|
||||
],
|
||||
'cflags': [
|
||||
'<@(uv_cflags)',
|
||||
'<@(nu_cflags)',
|
||||
],
|
||||
'ldflags': [
|
||||
'<@(png_ldflags)',
|
||||
'<@(jpeg_ldflags)',
|
||||
'<@(uv_ldflags)',
|
||||
'<@(curl_ldflags)',
|
||||
'<@(nu_ldflags)',
|
||||
'<@(zip_ldflags)',
|
||||
],
|
||||
},
|
||||
|
||||
'sources': [
|
||||
'../platform/android/cache_database_data.cpp',
|
||||
'../platform/android/log_android.cpp',
|
||||
'../platform/android/asset_request_libzip.cpp',
|
||||
'../platform/default/string_stdlib.cpp',
|
||||
'../platform/default/http_request_baton_curl.cpp',
|
||||
'../platform/default/image.cpp',
|
||||
'../platform/default/image_reader.cpp',
|
||||
'../platform/default/png_reader.cpp',
|
||||
'../platform/default/jpeg_reader.cpp',
|
||||
],
|
||||
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(png_cflags)',
|
||||
'<@(jpeg_cflags)',
|
||||
'<@(uv_cflags)',
|
||||
'<@(nu_cflags)',
|
||||
'<@(boost_cflags)',
|
||||
],
|
||||
'ldflags': [
|
||||
'<@(png_ldflags)',
|
||||
'<@(jpeg_ldflags)',
|
||||
'<@(uv_ldflags)',
|
||||
'<@(nu_ldflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(png_static_libs)',
|
||||
'<@(jpeg_static_libs)',
|
||||
'<@(uv_static_libs)',
|
||||
'<@(nu_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
'../src',
|
||||
],
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'<@(png_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
'OTHER_CFLAGS': [ '<@(cflags)' ],
|
||||
}
|
||||
}, {
|
||||
'cflags_cc': [ '<@(cflags_cc)' ],
|
||||
'cflags': [ '<@(cflags)' ],
|
||||
}]
|
||||
],
|
||||
|
||||
'link_settings': {
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'libraries': [ '<@(libraries)' ],
|
||||
'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
},
|
||||
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
|
||||
}
|
||||
}, {
|
||||
'ldflags': [ '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -1,39 +1,55 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'mbgl-osx',
|
||||
'product_name': 'mbgl-osx',
|
||||
{ 'target_name': 'platform-ios',
|
||||
'product_name': 'mbgl-platform-ios',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'version',
|
||||
],
|
||||
|
||||
'sources': [
|
||||
'../platform/osx/cache_database_application_support.mm',
|
||||
'../platform/darwin/log_nslog.mm',
|
||||
'../platform/darwin/string_nsstring.mm',
|
||||
'../platform/darwin/http_request_baton_cocoa.mm',
|
||||
'../platform/darwin/application_root.mm',
|
||||
'../platform/darwin/asset_root.mm',
|
||||
'../platform/darwin/image.mm',
|
||||
'../platform/default/asset_request_libuv.cpp',
|
||||
],
|
||||
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(uv_cflags)',
|
||||
'<@(boost_cflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(uv_static_libs)',
|
||||
],
|
||||
'ldflags': [
|
||||
'-framework ImageIO',
|
||||
'-framework MobileCoreServices',
|
||||
],
|
||||
},
|
||||
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
'../src',
|
||||
],
|
||||
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(uv_cflags)' ],
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
},
|
||||
|
||||
'link_settings': {
|
||||
'libraries': [ '<@(libraries)' ],
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
|
||||
},
|
||||
},
|
||||
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [
|
||||
'-framework ImageIO',
|
||||
'-framework CoreServices',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -1,79 +1,77 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'mbgl-linux',
|
||||
'product_name': 'mbgl-linux',
|
||||
{ 'target_name': 'platform-linux',
|
||||
'product_name': 'mbgl-platform-linux',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'version',
|
||||
],
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(png_cflags)',
|
||||
'<@(jpeg_cflags)',
|
||||
'<@(uv_cflags)',
|
||||
'<@(curl_cflags)',
|
||||
'<@(nu_cflags)',
|
||||
'-I<(boost_root)/include',
|
||||
],
|
||||
'cflags': [
|
||||
'<@(uv_cflags)',
|
||||
'<@(nu_cflags)',
|
||||
],
|
||||
'ldflags': [
|
||||
'<@(png_ldflags)',
|
||||
'<@(jpeg_ldflags)',
|
||||
'<@(uv_ldflags)',
|
||||
'<@(curl_ldflags)',
|
||||
'<@(nu_ldflags)',
|
||||
],
|
||||
},
|
||||
|
||||
'sources': [
|
||||
'../platform/default/cache_database_tmp.cpp',
|
||||
'../platform/default/log_stderr.cpp',
|
||||
'../platform/default/string_stdlib.cpp',
|
||||
'../platform/default/asset_request_libuv.cpp',
|
||||
'../platform/default/http_request_baton_curl.cpp',
|
||||
'../platform/default/application_root.cpp',
|
||||
'../platform/default/asset_root.cpp',
|
||||
'../platform/default/image.cpp',
|
||||
'../platform/default/image_reader.cpp',
|
||||
'../platform/default/png_reader.cpp',
|
||||
'../platform/default/jpeg_reader.cpp',
|
||||
],
|
||||
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(png_cflags)',
|
||||
'<@(jpeg_cflags)',
|
||||
'<@(uv_cflags)',
|
||||
'<@(nu_cflags)',
|
||||
'<@(boost_cflags)',
|
||||
],
|
||||
'ldflags': [
|
||||
'<@(png_ldflags)',
|
||||
'<@(jpeg_ldflags)',
|
||||
'<@(uv_ldflags)',
|
||||
'<@(nu_ldflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(png_static_libs)',
|
||||
'<@(jpeg_static_libs)',
|
||||
'<@(uv_static_libs)',
|
||||
'<@(nu_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
'../src',
|
||||
],
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'<@(png_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
'OTHER_CFLAGS': [ '<@(cflags)' ],
|
||||
}
|
||||
}, {
|
||||
'cflags_cc': [ '<@(cflags_cc)' ],
|
||||
'cflags': [ '<@(cflags)' ],
|
||||
}]
|
||||
],
|
||||
|
||||
'link_settings': {
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'libraries': [ '<@(libraries)' ],
|
||||
'xcode_settings': { 'OTHER_LDFLAGS': [ '<@(ldflags)' ] }
|
||||
}, {
|
||||
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
},
|
||||
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
|
||||
}
|
||||
}, {
|
||||
'ldflags': [ '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
58
gyp/platform-osx.gypi
Normal file
58
gyp/platform-osx.gypi
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'platform-osx',
|
||||
'product_name': 'mbgl-platform-osx',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'hard_dependency': 1,
|
||||
'dependencies': [
|
||||
'version',
|
||||
],
|
||||
|
||||
'sources': [
|
||||
'../platform/darwin/log_nslog.mm',
|
||||
'../platform/darwin/string_nsstring.mm',
|
||||
'../platform/darwin/application_root.mm',
|
||||
'../platform/darwin/asset_root.mm',
|
||||
'../platform/darwin/image.mm',
|
||||
],
|
||||
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(uv_cflags)',
|
||||
'<@(boost_cflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(uv_static_libs)',
|
||||
],
|
||||
'ldflags': [
|
||||
'-framework Foundation',
|
||||
'-framework ImageIO',
|
||||
'-framework CoreServices',
|
||||
],
|
||||
},
|
||||
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
'../src',
|
||||
],
|
||||
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
},
|
||||
|
||||
'link_settings': {
|
||||
'libraries': [ '<@(libraries)' ],
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
|
||||
},
|
||||
},
|
||||
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
32
gyp/standalone.gypi
Normal file
32
gyp/standalone.gypi
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
'targets': [
|
||||
{ 'target_name': 'everything',
|
||||
'type': 'none',
|
||||
'hard_dependency': 1,
|
||||
|
||||
'dependencies': [
|
||||
'core',
|
||||
'platform-<(platform_lib)',
|
||||
'http-<(http_lib)',
|
||||
'asset-<(asset_lib)',
|
||||
'cache-<(cache_lib)',
|
||||
'headless-<(headless_lib)',
|
||||
],
|
||||
},
|
||||
|
||||
{ 'target_name': 'standalone',
|
||||
'product_name': 'libmbgl.a',
|
||||
'type': 'executable',
|
||||
'hard_dependency': 1,
|
||||
|
||||
'dependencies': [
|
||||
'core',
|
||||
'platform-<(platform_lib)',
|
||||
'http-<(http_lib)',
|
||||
'asset-<(asset_lib)',
|
||||
'cache-<(cache_lib)',
|
||||
'headless-<(headless_lib)',
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
'outputs': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/include/mbgl/util/version.hpp',
|
||||
],
|
||||
'action': ['<@(python)', 'scripts/build-version.py', '<(SHARED_INTERMEDIATE_DIR)', '<!@(git describe --tags --always --abbrev=0)', '<!@(git rev-parse HEAD)'],
|
||||
'action': ['<@(python)', '<@(_inputs)', '<(SHARED_INTERMEDIATE_DIR)', '<!@(git describe --tags --always --abbrev=0)', '<!@(git rev-parse HEAD)'],
|
||||
}
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
#define MBGL_ANDROID_JNI
|
||||
|
||||
#include <string>
|
||||
#include <jni.h>
|
||||
|
||||
// Forward definition of JNI types
|
||||
typedef class _jclass* jclass;
|
||||
typedef struct _jmethodID* jmethodID;
|
||||
typedef struct _jfieldID* jfieldID;
|
||||
|
||||
namespace mbgl {
|
||||
namespace android {
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/map/view.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/storage/caching_http_file_source.hpp>
|
||||
#include <mbgl/storage/default/sqlite_cache.hpp>
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <jni.h>
|
||||
@@ -25,10 +26,10 @@ public:
|
||||
void swap() override;
|
||||
|
||||
void notify() override;
|
||||
void notifyMapChange(mbgl::MapChange change, mbgl::timestamp delay) override;
|
||||
void notifyMapChange(mbgl::MapChange change, std::chrono::steady_clock::duration delay = std::chrono::steady_clock::duration::zero()) override;
|
||||
|
||||
mbgl::Map &getMap();
|
||||
mbgl::CachingHTTPFileSource &getFileSource();
|
||||
mbgl::DefaultFileSource &getFileSource();
|
||||
|
||||
void initializeDisplay();
|
||||
void terminateDisplay();
|
||||
@@ -61,7 +62,8 @@ private:
|
||||
|
||||
ANativeWindow *window = nullptr;
|
||||
|
||||
mbgl::CachingHTTPFileSource fileSource;
|
||||
mbgl::SQLiteCache fileCache;
|
||||
mbgl::DefaultFileSource fileSource;
|
||||
mbgl::Map map;
|
||||
|
||||
EGLDisplay display = EGL_NO_DISPLAY;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include <mbgl/map/transform.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/time.hpp>
|
||||
#include <mbgl/util/uv.hpp>
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
|
||||
@@ -16,6 +15,7 @@
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <chrono>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -83,8 +83,8 @@ public:
|
||||
void setClasses(const std::vector<std::string>&);
|
||||
std::vector<std::string> getClasses() const;
|
||||
|
||||
void setDefaultTransitionDuration(uint64_t milliseconds = 0);
|
||||
uint64_t getDefaultTransitionDuration();
|
||||
void setDefaultTransitionDuration(std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
std::chrono::steady_clock::duration getDefaultTransitionDuration();
|
||||
void setStyleURL(const std::string &url);
|
||||
void setStyleJSON(std::string newStyleJSON, const std::string &base = "");
|
||||
std::string getStyleJSON() const;
|
||||
@@ -93,20 +93,20 @@ public:
|
||||
void cancelTransitions();
|
||||
|
||||
// Position
|
||||
void moveBy(double dx, double dy, double duration = 0);
|
||||
void setLonLat(double lon, double lat, double duration = 0);
|
||||
void moveBy(double dx, double dy, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void setLonLat(double lon, double lat, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void getLonLat(double &lon, double &lat) const;
|
||||
void startPanning();
|
||||
void stopPanning();
|
||||
void resetPosition();
|
||||
|
||||
// Scale
|
||||
void scaleBy(double ds, double cx = -1, double cy = -1, double duration = 0);
|
||||
void setScale(double scale, double cx = -1, double cy = -1, double duration = 0);
|
||||
void scaleBy(double ds, double cx = -1, double cy = -1, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void setScale(double scale, double cx = -1, double cy = -1, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
double getScale() const;
|
||||
void setZoom(double zoom, double duration = 0);
|
||||
void setZoom(double zoom, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
double getZoom() const;
|
||||
void setLonLatZoom(double lon, double lat, double zoom, double duration = 0);
|
||||
void setLonLatZoom(double lon, double lat, double zoom, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void getLonLatZoom(double &lon, double &lat, double &zoom) const;
|
||||
void resetZoom();
|
||||
void startScaling();
|
||||
@@ -115,21 +115,25 @@ public:
|
||||
double getMaxZoom() const;
|
||||
|
||||
// Rotation
|
||||
void rotateBy(double sx, double sy, double ex, double ey, double duration = 0);
|
||||
void setBearing(double degrees, double duration = 0);
|
||||
void rotateBy(double sx, double sy, double ex, double ey, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void setBearing(double degrees, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void setBearing(double degrees, double cx, double cy);
|
||||
double getBearing() const;
|
||||
void resetNorth();
|
||||
void startRotating();
|
||||
void stopRotating();
|
||||
|
||||
// API
|
||||
void setAccessToken(const std::string &token);
|
||||
const std::string &getAccessToken() const;
|
||||
|
||||
// Debug
|
||||
void setDebug(bool value);
|
||||
void toggleDebug();
|
||||
bool getDebug() const;
|
||||
|
||||
inline const TransformState &getState() const { return state; }
|
||||
inline timestamp getTime() const { return animationTime; }
|
||||
inline std::chrono::steady_clock::time_point getTime() const { return animationTime; }
|
||||
|
||||
private:
|
||||
util::ptr<Sprite> getSprite();
|
||||
@@ -160,7 +164,10 @@ private:
|
||||
|
||||
Mode mode = Mode::None;
|
||||
|
||||
public: // TODO: make private again
|
||||
std::unique_ptr<uv::loop> loop;
|
||||
|
||||
private:
|
||||
std::unique_ptr<uv::worker> workers;
|
||||
std::thread thread;
|
||||
std::unique_ptr<uv::async> asyncTerminate;
|
||||
@@ -191,7 +198,7 @@ private:
|
||||
|
||||
View &view;
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifdef DEBUG
|
||||
const std::thread::id mainThread;
|
||||
std::thread::id mapThread;
|
||||
#endif
|
||||
@@ -214,11 +221,12 @@ private:
|
||||
std::string styleURL;
|
||||
std::string styleJSON = "";
|
||||
std::vector<std::string> classes;
|
||||
std::string accessToken;
|
||||
|
||||
std::atomic_uint_fast64_t defaultTransitionDuration;
|
||||
std::chrono::steady_clock::duration defaultTransitionDuration;
|
||||
|
||||
bool debug = false;
|
||||
timestamp animationTime = 0;
|
||||
std::chrono::steady_clock::time_point animationTime = std::chrono::steady_clock::time_point::min();
|
||||
|
||||
std::set<util::ptr<StyleSource>> activeSources;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef MBGL_MAP_TRANSFORM
|
||||
#define MBGL_MAP_TRANSFORM
|
||||
|
||||
#include <mbgl/util/time.hpp>
|
||||
#include <mbgl/map/transform_state.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
@@ -9,6 +8,7 @@
|
||||
#include <cmath>
|
||||
#include <forward_list>
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -25,18 +25,18 @@ public:
|
||||
uint16_t fb_width, uint16_t fb_height);
|
||||
|
||||
// Position
|
||||
void moveBy(double dx, double dy, timestamp duration = 0);
|
||||
void setLonLat(double lon, double lat, timestamp duration = 0);
|
||||
void setLonLatZoom(double lon, double lat, double zoom, timestamp duration = 0);
|
||||
void moveBy(double dx, double dy, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void setLonLat(double lon, double lat, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void setLonLatZoom(double lon, double lat, double zoom, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void getLonLat(double& lon, double& lat) const;
|
||||
void getLonLatZoom(double& lon, double& lat, double& zoom) const;
|
||||
void startPanning();
|
||||
void stopPanning();
|
||||
|
||||
// Zoom
|
||||
void scaleBy(double ds, double cx = -1, double cy = -1, timestamp duration = 0);
|
||||
void setScale(double scale, double cx = -1, double cy = -1, timestamp duration = 0);
|
||||
void setZoom(double zoom, timestamp duration = 0);
|
||||
void scaleBy(double ds, double cx = -1, double cy = -1, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void setScale(double scale, double cx = -1, double cy = -1, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void setZoom(double zoom, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
double getZoom() const;
|
||||
double getScale() const;
|
||||
void startScaling();
|
||||
@@ -45,8 +45,8 @@ public:
|
||||
double getMaxZoom() const;
|
||||
|
||||
// Angle
|
||||
void rotateBy(double sx, double sy, double ex, double ey, timestamp duration = 0);
|
||||
void setAngle(double angle, timestamp duration = 0);
|
||||
void rotateBy(double sx, double sy, double ex, double ey, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void setAngle(double angle, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void setAngle(double angle, double cx, double cy);
|
||||
double getAngle() const;
|
||||
void startRotating();
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
|
||||
// Transitions
|
||||
bool needsTransition() const;
|
||||
void updateTransitions(timestamp now);
|
||||
void updateTransitions(std::chrono::steady_clock::time_point now);
|
||||
void cancelTransitions();
|
||||
|
||||
// Transform state
|
||||
@@ -64,10 +64,10 @@ public:
|
||||
private:
|
||||
// Functions prefixed with underscores will *not* perform any locks. It is the caller's
|
||||
// responsibility to lock this object.
|
||||
void _moveBy(double dx, double dy, timestamp duration = 0);
|
||||
void _setScale(double scale, double cx, double cy, timestamp duration = 0);
|
||||
void _setScaleXY(double new_scale, double xn, double yn, timestamp duration = 0);
|
||||
void _setAngle(double angle, timestamp duration = 0);
|
||||
void _moveBy(double dx, double dy, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void _setScale(double scale, double cx, double cy, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void _setScaleXY(double new_scale, double xn, double yn, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void _setAngle(double angle, std::chrono::steady_clock::duration duration = std::chrono::steady_clock::duration::zero());
|
||||
void _clearPanning();
|
||||
void _clearRotating();
|
||||
void _clearScaling();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef MBGL_MAP_VIEW
|
||||
#define MBGL_MAP_VIEW
|
||||
|
||||
#include <mbgl/util/time.hpp>
|
||||
#include <chrono>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
// Notifies a watcher of map x/y/scale/rotation changes.
|
||||
// Must only be called from the same thread that caused the change.
|
||||
// Must not be called from the render thread.
|
||||
virtual void notifyMapChange(MapChange change, timestamp delay = 0) = 0;
|
||||
virtual void notifyMapChange(MapChange change, std::chrono::steady_clock::duration delay = std::chrono::steady_clock::duration::zero()) = 0;
|
||||
|
||||
protected:
|
||||
mbgl::Map *map = nullptr;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define MBGL_COMMON_GLFW_VIEW
|
||||
|
||||
#include <mbgl/mbgl.hpp>
|
||||
#include <mbgl/util/time.hpp>
|
||||
|
||||
#ifdef NVIDIA
|
||||
#define GLFW_INCLUDE_ES2
|
||||
@@ -19,7 +18,7 @@ public:
|
||||
void activate();
|
||||
void deactivate();
|
||||
void notify();
|
||||
void notifyMapChange(mbgl::MapChange change, mbgl::timestamp delay = 0);
|
||||
void notifyMapChange(mbgl::MapChange change, std::chrono::steady_clock::duration delay = std::chrono::steady_clock::duration::zero());
|
||||
|
||||
static void key(GLFWwindow *window, int key, int scancode, int action, int mods);
|
||||
static void scroll(GLFWwindow *window, double xoffset, double yoffset);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <mbgl/platform/default/glx.h>
|
||||
#define MBGL_USE_GLX 1
|
||||
#undef Status
|
||||
#endif
|
||||
|
||||
#include <mbgl/map/view.hpp>
|
||||
@@ -31,7 +32,7 @@ public:
|
||||
std::unique_ptr<uint32_t[]> readPixels();
|
||||
|
||||
void notify();
|
||||
void notifyMapChange(MapChange change, timestamp delay = 0);
|
||||
void notifyMapChange(MapChange change, std::chrono::steady_clock::duration delay = std::chrono::steady_clock::duration::zero());
|
||||
void activate();
|
||||
void deactivate();
|
||||
void swap();
|
||||
|
||||
@@ -9,7 +9,13 @@ extern "C"
|
||||
#include <jpeglib.h>
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#ifndef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mbgl { namespace util {
|
||||
|
||||
|
||||
@@ -11,7 +11,13 @@ extern "C"
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#ifndef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mbgl { namespace util {
|
||||
|
||||
|
||||
@@ -17,10 +17,11 @@ std::string uppercase(const std::string &string);
|
||||
// Lowercase a string, potentially using platform-specific routines.
|
||||
std::string lowercase(const std::string &string);
|
||||
|
||||
// Returns the path to the default cache database on this system.
|
||||
std::string defaultCacheDatabase();
|
||||
// Returns the path to the root folder of the application.
|
||||
const std::string &applicationRoot();
|
||||
|
||||
std::string applicationRoot();
|
||||
// Returns the path to the asset location.
|
||||
const std::string &assetRoot();
|
||||
|
||||
// Shows an alpha image with the specified dimensions in a named window.
|
||||
void show_debug_image(std::string name, const char *data, size_t width, size_t height);
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#ifndef MBGL_STORAGE_ASSET_REQUEST
|
||||
#define MBGL_STORAGE_ASSET_REQUEST
|
||||
|
||||
#include <mbgl/storage/base_request.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
typedef struct uv_loop_s uv_loop_t;
|
||||
|
||||
struct AssetRequestBaton;
|
||||
|
||||
class AssetRequest : public BaseRequest {
|
||||
public:
|
||||
AssetRequest(const std::string &path, uv_loop_t *loop);
|
||||
~AssetRequest();
|
||||
|
||||
void cancel();
|
||||
|
||||
private:
|
||||
AssetRequestBaton *ptr = nullptr;
|
||||
|
||||
friend struct AssetRequestBaton;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
#ifndef MBGL_STORAGE_ASSET_REQUEST_BATON
|
||||
#define MBGL_STORAGE_ASSET_REQUEST_BATON
|
||||
|
||||
#include <mbgl/util/uv.hpp>
|
||||
#include <thread>
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class AssetRequest;
|
||||
|
||||
struct AssetRequestBaton {
|
||||
AssetRequestBaton(AssetRequest *request_, const std::string &path, uv_loop_t *loop);
|
||||
|
||||
const std::thread::id threadId;
|
||||
AssetRequest *request = nullptr;
|
||||
std::unique_ptr<uv::async> asyncRun;
|
||||
std::string path;
|
||||
bool canceled = false;
|
||||
|
||||
void cancel();
|
||||
static void notifyError(AssetRequestBaton *ptr, const int code, const char *message);
|
||||
static void notifySuccess(AssetRequestBaton *ptr, const std::string body);
|
||||
static void cleanup(AssetRequestBaton *ptr);
|
||||
|
||||
// IMPLEMENT THIS PLATFORM SPECIFIC FUNCTION:
|
||||
|
||||
// Called to load the asset. Platform-specific implementation.
|
||||
static void run(AssetRequestBaton *ptr);
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,62 +0,0 @@
|
||||
#ifndef MBGL_STORAGE_CACHING_HTTP_FILE_SOURCE
|
||||
#define MBGL_STORAGE_CACHING_HTTP_FILE_SOURCE
|
||||
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
|
||||
typedef struct uv_messenger_s uv_messenger_t;
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class BaseRequest;
|
||||
class SQLiteStore;
|
||||
|
||||
class CachingHTTPFileSource : public FileSource {
|
||||
public:
|
||||
CachingHTTPFileSource(const std::string &path_);
|
||||
virtual ~CachingHTTPFileSource();
|
||||
|
||||
// Stores and checks the libuv loop for requests
|
||||
void setLoop(uv_loop_t*);
|
||||
bool hasLoop();
|
||||
void clearLoop();
|
||||
|
||||
// Set the base path/URL for relative requests
|
||||
void setBase(std::string);
|
||||
|
||||
// Set the Mapbox API access token
|
||||
void setAccessToken(std::string);
|
||||
|
||||
// Get the Mapbox API access token
|
||||
std::string getAccessToken() const;
|
||||
|
||||
std::unique_ptr<Request> request(ResourceType type, const std::string &url);
|
||||
|
||||
void prepare(std::function<void()> fn);
|
||||
|
||||
// Call this when the network status reachability changed.
|
||||
void setReachability(bool reachable);
|
||||
|
||||
private:
|
||||
std::thread::id threadId;
|
||||
|
||||
// Mapbox API access token.
|
||||
std::string accessToken;
|
||||
|
||||
// Path to the cache database.
|
||||
std::string path;
|
||||
|
||||
// Stores a URL that is used as a base for loading resources with relative path.
|
||||
std::string base;
|
||||
|
||||
std::unordered_map<std::string, std::weak_ptr<BaseRequest>> pending;
|
||||
util::ptr<SQLiteStore> store;
|
||||
uv_loop_t *loop = nullptr;
|
||||
uv_messenger_t *queue = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
24
include/mbgl/storage/default/asset_request.hpp
Normal file
24
include/mbgl/storage/default/asset_request.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef MBGL_STORAGE_DEFAULT_ASSET_REQUEST
|
||||
#define MBGL_STORAGE_DEFAULT_ASSET_REQUEST
|
||||
|
||||
#include "shared_request_base.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class AssetRequest : public SharedRequestBase {
|
||||
public:
|
||||
AssetRequest(DefaultFileSource *source, const Resource &resource);
|
||||
|
||||
void start(uv_loop_t *loop, std::unique_ptr<Response> response = nullptr);
|
||||
void cancel();
|
||||
|
||||
private:
|
||||
~AssetRequest();
|
||||
void *ptr = nullptr;
|
||||
|
||||
friend class AssetRequestImpl;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
76
include/mbgl/storage/default/http_context.hpp
Normal file
76
include/mbgl/storage/default/http_context.hpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef MBGL_STORAGE_DEFAULT_HTTP_CONTEXT
|
||||
#define MBGL_STORAGE_DEFAULT_HTTP_CONTEXT
|
||||
|
||||
#include "thread_context.hpp"
|
||||
#include <mbgl/storage/network_status.hpp>
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class HTTPRequest;
|
||||
|
||||
// This is a template class that provides a per-thread Context object. It can be used by HTTP
|
||||
// implementations to store global state. It also implements the NetworkStatus mechanism and
|
||||
// triggers immediate retries on all requests waiting for network status changes.
|
||||
|
||||
template <typename Context>
|
||||
class HTTPContext : public ThreadContext<Context> {
|
||||
public:
|
||||
HTTPContext(uv_loop_t *loop);
|
||||
~HTTPContext();
|
||||
|
||||
void addRequest(HTTPRequest *request);
|
||||
void removeRequest(HTTPRequest *baton);
|
||||
|
||||
public:
|
||||
// Will be fired when the network status becomes reachable.
|
||||
uv_async_t *reachability = nullptr;
|
||||
|
||||
// A list of all pending HTTPRequestImpls that we need to notify when the network status
|
||||
// changes.
|
||||
std::set<HTTPRequest *> requests;
|
||||
};
|
||||
|
||||
template <typename Context>
|
||||
HTTPContext<Context>::HTTPContext(uv_loop_t *loop_)
|
||||
: ThreadContext<Context>(loop_) {
|
||||
reachability = new uv_async_t;
|
||||
reachability->data = this;
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
uv_async_init(loop_, reachability, [](uv_async_t *async, int) {
|
||||
#else
|
||||
uv_async_init(loop_, reachability, [](uv_async_t *async) {
|
||||
#endif
|
||||
for (auto request : reinterpret_cast<Context *>(async->data)->requests) {
|
||||
request->retryImmediately();
|
||||
}
|
||||
});
|
||||
// Allow the loop to quit even though this handle is still active.
|
||||
uv_unref(reinterpret_cast<uv_handle_t *>(reachability));
|
||||
NetworkStatus::Subscribe(reachability);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
HTTPContext<Context>::~HTTPContext() {
|
||||
MBGL_VERIFY_THREAD(HTTPContext<Context>::tid);
|
||||
|
||||
assert(requests.empty());
|
||||
|
||||
NetworkStatus::Unsubscribe(reachability);
|
||||
uv::close(reachability);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
void HTTPContext<Context>::addRequest(HTTPRequest *request) {
|
||||
requests.insert(request);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
void HTTPContext<Context>::removeRequest(HTTPRequest *request) {
|
||||
requests.erase(request);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
26
include/mbgl/storage/default/http_request.hpp
Normal file
26
include/mbgl/storage/default/http_request.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef MBGL_STORAGE_DEFAULT_HTTP_REQUEST
|
||||
#define MBGL_STORAGE_DEFAULT_HTTP_REQUEST
|
||||
|
||||
#include "shared_request_base.hpp"
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class HTTPRequest : public SharedRequestBase {
|
||||
public:
|
||||
HTTPRequest(DefaultFileSource *source, const Resource &resource);
|
||||
|
||||
void start(uv_loop_t *loop, std::unique_ptr<Response> response = nullptr);
|
||||
void cancel();
|
||||
|
||||
void retryImmediately();
|
||||
|
||||
private:
|
||||
~HTTPRequest();
|
||||
void *ptr = nullptr;
|
||||
|
||||
friend class HTTPRequestImpl;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
51
include/mbgl/storage/default/request.hpp
Normal file
51
include/mbgl/storage/default/request.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef MBGL_STORAGE_DEFAULT_REQUEST
|
||||
#define MBGL_STORAGE_DEFAULT_REQUEST
|
||||
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
|
||||
#include <mbgl/util/util.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
typedef struct uv_async_s uv_async_t;
|
||||
typedef struct uv_loop_s uv_loop_t;
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Response;
|
||||
|
||||
class Request : private util::noncopyable {
|
||||
MBGL_STORE_THREAD(tid)
|
||||
|
||||
public:
|
||||
using Callback = std::function<void(const Response &)>;
|
||||
Request(const Resource &resource, uv_loop_t *loop, Callback callback);
|
||||
~Request();
|
||||
|
||||
public:
|
||||
// May be called from any thread.
|
||||
void notify(const std::shared_ptr<const Response> &response);
|
||||
void destruct();
|
||||
|
||||
// May be called only from the thread the Request was created in.
|
||||
void cancel();
|
||||
|
||||
private:
|
||||
static void notifyCallback(uv_async_t *async);
|
||||
static void cancelCallback(uv_async_t *async);
|
||||
|
||||
private:
|
||||
uv_async_t *notify_async = nullptr;
|
||||
uv_async_t *destruct_async = nullptr;
|
||||
Callback callback;
|
||||
std::shared_ptr<const Response> response;
|
||||
|
||||
public:
|
||||
const Resource resource;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
88
include/mbgl/storage/default/shared_request_base.hpp
Normal file
88
include/mbgl/storage/default/shared_request_base.hpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#ifndef MBGL_STORAGE_DEFAULT_SHARED_REQUEST_BASE
|
||||
#define MBGL_STORAGE_DEFAULT_SHARED_REQUEST_BASE
|
||||
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
#include <mbgl/storage/file_cache.hpp>
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
#include <mbgl/util/util.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <cassert>
|
||||
|
||||
typedef struct uv_loop_s uv_loop_t;
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Request;
|
||||
class Response;
|
||||
class DefaultFileSource;
|
||||
|
||||
class SharedRequestBase : private util::noncopyable {
|
||||
protected:
|
||||
MBGL_STORE_THREAD(tid)
|
||||
|
||||
public:
|
||||
SharedRequestBase(DefaultFileSource *source_, const Resource &resource_)
|
||||
: resource(resource_), source(source_) {}
|
||||
|
||||
virtual void start(uv_loop_t *loop, std::unique_ptr<Response> response = nullptr) = 0;
|
||||
virtual void cancel() = 0;
|
||||
|
||||
void notify(std::unique_ptr<Response> response, FileCache::Hint hint) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (source) {
|
||||
source->notify(this, observers, std::shared_ptr<const Response>(response.release()),
|
||||
hint);
|
||||
}
|
||||
}
|
||||
|
||||
void subscribe(Request *request) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
observers.insert(request);
|
||||
}
|
||||
|
||||
void unsubscribeAll() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
source = nullptr;
|
||||
observers.clear();
|
||||
cancel();
|
||||
}
|
||||
|
||||
void unsubscribe(Request *request) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
observers.erase(request);
|
||||
|
||||
if (observers.empty()) {
|
||||
// There are no observers anymore. We are initiating cancelation.
|
||||
if (source) {
|
||||
// First, remove this SharedRequestBase from the source.
|
||||
source->notify(this, observers, nullptr, FileCache::Hint::No);
|
||||
}
|
||||
|
||||
// Then, initiate cancelation of this request
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~SharedRequestBase() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
}
|
||||
|
||||
public:
|
||||
const Resource resource;
|
||||
|
||||
private:
|
||||
DefaultFileSource *source = nullptr;
|
||||
std::set<Request *> observers;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
52
include/mbgl/storage/default/sqlite_cache.hpp
Normal file
52
include/mbgl/storage/default/sqlite_cache.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef MBGL_STORAGE_DEFAULT_SQLITE_CACHE
|
||||
#define MBGL_STORAGE_DEFAULT_SQLITE_CACHE
|
||||
|
||||
#include <mbgl/storage/file_cache.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
typedef struct uv_loop_s uv_loop_t;
|
||||
|
||||
namespace mapbox { namespace util { template<typename... Types> class variant; } }
|
||||
namespace mapbox { namespace sqlite { class Database; class Statement; } }
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace util { template <typename T> class AsyncQueue; }
|
||||
|
||||
class SQLiteCache : public FileCache {
|
||||
struct GetAction;
|
||||
struct PutAction;
|
||||
struct RefreshAction;
|
||||
struct StopAction;
|
||||
using Action = mapbox::util::variant<GetAction, PutAction, RefreshAction, StopAction>;
|
||||
using Queue = util::AsyncQueue<Action>;
|
||||
|
||||
public:
|
||||
SQLiteCache(const std::string &path = ":memory:");
|
||||
~SQLiteCache();
|
||||
|
||||
void get(const Resource &resource, std::function<void(std::unique_ptr<Response>)> callback);
|
||||
void put(const Resource &resource, std::shared_ptr<const Response> response, Hint hint);
|
||||
|
||||
private:
|
||||
struct ActionDispatcher;
|
||||
void process(GetAction &action);
|
||||
void process(PutAction &action);
|
||||
void process(RefreshAction &action);
|
||||
void process(StopAction &action);
|
||||
|
||||
void createDatabase();
|
||||
|
||||
const std::string path;
|
||||
uv_loop_t *loop = nullptr;
|
||||
Queue *queue = nullptr;
|
||||
std::thread thread;
|
||||
std::unique_ptr<::mapbox::sqlite::Database> db;
|
||||
std::unique_ptr<::mapbox::sqlite::Statement> getStmt, putStmt, refreshStmt;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
78
include/mbgl/storage/default/thread_context.hpp
Normal file
78
include/mbgl/storage/default/thread_context.hpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#ifndef MBGL_STORAGE_DEFAULT_THREAD_CONTEXT
|
||||
#define MBGL_STORAGE_DEFAULT_THREAD_CONTEXT
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/util/util.hpp>
|
||||
#include <mbgl/util/uv.hpp>
|
||||
|
||||
#include <uv.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <map>
|
||||
#include <cassert>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
// This is a template class that provides a per-thread and per-loop Context object. It can be used
|
||||
// by implementations to store global state.
|
||||
|
||||
template <typename Context>
|
||||
class ThreadContext : private util::noncopyable {
|
||||
protected:
|
||||
MBGL_STORE_THREAD(tid)
|
||||
using Map = std::map<uv_loop_t *, std::unique_ptr<Context>>;
|
||||
|
||||
public:
|
||||
static Context *Get(uv_loop_t *loop);
|
||||
|
||||
private:
|
||||
static pthread_key_t key;
|
||||
static pthread_once_t once;
|
||||
|
||||
public:
|
||||
ThreadContext(uv_loop_t *loop);
|
||||
~ThreadContext();
|
||||
|
||||
public:
|
||||
uv_loop_t *loop;
|
||||
};
|
||||
|
||||
template <typename Context>
|
||||
Context *ThreadContext<Context>::Get(uv_loop_t *loop) {
|
||||
pthread_once(&once, []() {
|
||||
pthread_key_create(&key, [](void *ptr) {
|
||||
assert(ptr);
|
||||
delete reinterpret_cast<Map *>(ptr);
|
||||
});
|
||||
});
|
||||
auto contexts = reinterpret_cast<Map *>(pthread_getspecific(key));
|
||||
if (!contexts) {
|
||||
contexts = new Map();
|
||||
pthread_setspecific(key, contexts);
|
||||
}
|
||||
|
||||
// Now find a ThreadContext that matches the requested loop.
|
||||
auto it = contexts->find(loop);
|
||||
if (it == contexts->end()) {
|
||||
auto result = contexts->emplace(loop, util::make_unique<Context>(loop));
|
||||
assert(result.second); // Make sure it was actually inserted.
|
||||
return result.first->second.get();
|
||||
} else {
|
||||
return it->second.get();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
ThreadContext<Context>::ThreadContext(uv_loop_t *loop_) : loop(loop_) {
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
ThreadContext<Context>::~ThreadContext() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
60
include/mbgl/storage/default_file_source.hpp
Normal file
60
include/mbgl/storage/default_file_source.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef MBGL_STORAGE_DEFAULT_DEFAULT_FILE_SOURCE
|
||||
#define MBGL_STORAGE_DEFAULT_DEFAULT_FILE_SOURCE
|
||||
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/storage/file_cache.hpp>
|
||||
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <thread>
|
||||
|
||||
namespace mapbox { namespace util { template<typename... Types> class variant; } }
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace util { template <typename T> class AsyncQueue; }
|
||||
|
||||
class SharedRequestBase;
|
||||
|
||||
class DefaultFileSource : public FileSource {
|
||||
public:
|
||||
DefaultFileSource(FileCache *cache);
|
||||
DefaultFileSource(FileCache *cache, uv_loop_t *loop);
|
||||
~DefaultFileSource();
|
||||
|
||||
Request *request(const Resource &resource, uv_loop_t *loop, Callback callback);
|
||||
void cancel(Request *request);
|
||||
void request(const Resource &resource, Callback callback);
|
||||
|
||||
enum class CacheHint : uint8_t { Full, Refresh, No };
|
||||
void notify(SharedRequestBase *sharedRequest, const std::set<Request *> &observers,
|
||||
std::shared_ptr<const Response> response, FileCache::Hint hint);
|
||||
|
||||
private:
|
||||
struct ActionDispatcher;
|
||||
struct AddRequestAction;
|
||||
struct RemoveRequestAction;
|
||||
struct ResultAction;
|
||||
struct StopAction;
|
||||
using Action =
|
||||
mapbox::util::variant<AddRequestAction, RemoveRequestAction, ResultAction, StopAction>;
|
||||
using Queue = util::AsyncQueue<Action>;
|
||||
|
||||
void process(AddRequestAction &action);
|
||||
void process(RemoveRequestAction &action);
|
||||
void process(ResultAction &action);
|
||||
void process(StopAction &action);
|
||||
|
||||
SharedRequestBase *find(const Resource &resource);
|
||||
|
||||
std::unordered_map<Resource, SharedRequestBase *, Resource::Hash> pending;
|
||||
|
||||
uv_loop_t *loop = nullptr;
|
||||
FileCache *cache = nullptr;
|
||||
Queue *queue = nullptr;
|
||||
std::thread thread;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
27
include/mbgl/storage/file_cache.hpp
Normal file
27
include/mbgl/storage/file_cache.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef MBGL_STORAGE_FILE_CACHE
|
||||
#define MBGL_STORAGE_FILE_CACHE
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
struct Resource;
|
||||
class Response;
|
||||
|
||||
class FileCache : private util::noncopyable {
|
||||
public:
|
||||
virtual ~FileCache() = default;
|
||||
|
||||
enum class Hint : uint8_t { Full, Refresh, No };
|
||||
|
||||
virtual void get(const Resource &resource,
|
||||
std::function<void(std::unique_ptr<Response>)> callback) = 0;
|
||||
virtual void put(const Resource &resource, std::shared_ptr<const Response> response, Hint hint) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,29 +1,38 @@
|
||||
#ifndef MBGL_STORAGE_FILE_SOURCE
|
||||
#define MBGL_STORAGE_FILE_SOURCE
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/storage/resource_type.hpp>
|
||||
#include <mbgl/storage/request.hpp>
|
||||
#include "response.hpp"
|
||||
#include "resource.hpp"
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/util/util.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
typedef struct uv_loop_s uv_loop_t;
|
||||
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class FileSource : public util::noncopyable {
|
||||
class Request;
|
||||
|
||||
class FileSource : private util::noncopyable {
|
||||
protected:
|
||||
MBGL_STORE_THREAD(tid)
|
||||
|
||||
public:
|
||||
virtual ~FileSource() = default;
|
||||
|
||||
virtual void setLoop(uv_loop_t*) = 0;
|
||||
virtual bool hasLoop() = 0;
|
||||
virtual void clearLoop() = 0;
|
||||
using Callback = std::function<void(const Response &)>;
|
||||
|
||||
virtual void setBase(std::string) = 0;
|
||||
virtual std::unique_ptr<Request> request(ResourceType type, const std::string &url) = 0;
|
||||
virtual void prepare(std::function<void()> fn) = 0;
|
||||
// These can be called from any thread. The callback will be invoked in the loop.
|
||||
// You can only cancel a request from the same thread it was created in.
|
||||
virtual Request *request(const Resource &resource, uv_loop_t *loop, Callback callback) = 0;
|
||||
virtual void cancel(Request *request) = 0;
|
||||
|
||||
// These can be called from any thread. The callback will be invoked in an arbitrary other thread.
|
||||
// You cannot cancel these requests.
|
||||
virtual void request(const Resource &resource, Callback callback) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
#ifndef MBGL_STORAGE_HTTP_REQUEST_BATON
|
||||
#define MBGL_STORAGE_HTTP_REQUEST_BATON
|
||||
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
typedef struct uv_async_s uv_async_t;
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class HTTPRequest;
|
||||
|
||||
enum class HTTPResponseType : int8_t {
|
||||
// This error probably won't be resolved by retrying anytime soon. We are giving up.
|
||||
PermanentError = -5,
|
||||
|
||||
// This error might be resolved by waiting some time (e.g. server issues).
|
||||
// We are going to do an exponential back-off and will try again in a few seconds.
|
||||
TemporaryError = -4,
|
||||
|
||||
// This error was caused by a temporary error and it is likely that it will be resolved
|
||||
// immediately. We are going to try again right away. This is like the TemporaryError, except
|
||||
// that we will not perform exponential back-off.
|
||||
SingularError = -3,
|
||||
|
||||
// This error might be resolved once the network reachability status changes.
|
||||
// We are going to watch the network status for changes and will retry as soon as the operating
|
||||
// system notifies us of a network status change.
|
||||
ConnectionError = -2,
|
||||
|
||||
// The request was canceled programatically.
|
||||
Canceled = -1,
|
||||
|
||||
// The request is still in progress.
|
||||
Unknown = 0,
|
||||
|
||||
// The request returned data successfully. We retrieved and decoded the data successfully.
|
||||
Successful = 1,
|
||||
|
||||
// The request confirmed that the data wasn't changed. We already have the data.
|
||||
NotModified = 2,
|
||||
};
|
||||
|
||||
struct HTTPRequestBaton {
|
||||
HTTPRequestBaton(const std::string &path);
|
||||
~HTTPRequestBaton();
|
||||
|
||||
const std::thread::id threadId;
|
||||
const std::string path;
|
||||
|
||||
HTTPRequest *request = nullptr;
|
||||
uv_async_t *async = nullptr;
|
||||
|
||||
HTTPResponseType type = HTTPResponseType::Unknown;
|
||||
std::unique_ptr<Response> response;
|
||||
|
||||
// Implementation specific use.
|
||||
void *ptr = nullptr;
|
||||
|
||||
// IMPLEMENT THESE 3 PLATFORM SPECIFIC FUNCTIONS:
|
||||
|
||||
// Begin the HTTP request. Platform-specific implementation.
|
||||
static void start(const util::ptr<HTTPRequestBaton> &ptr);
|
||||
|
||||
// This will be called to stop/cancel the HTTP request (if possible). Platform-specific implementation.
|
||||
static void stop(const util::ptr<HTTPRequestBaton> &ptr);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
25
include/mbgl/storage/network_status.hpp
Normal file
25
include/mbgl/storage/network_status.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef MBGL_STORAGE_NETWORK_STATUS
|
||||
#define MBGL_STORAGE_NETWORK_STATUS
|
||||
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
|
||||
typedef struct uv_async_s uv_async_t;
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class NetworkStatus {
|
||||
public:
|
||||
static void Reachable();
|
||||
|
||||
static void Subscribe(uv_async_t *async);
|
||||
static void Unsubscribe(uv_async_t *async);
|
||||
|
||||
private:
|
||||
static std::mutex mtx;
|
||||
static std::set<uv_async_t *> observers;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,41 +0,0 @@
|
||||
#ifndef MBGL_STORAGE_REQUEST
|
||||
#define MBGL_STORAGE_REQUEST
|
||||
|
||||
#include <mbgl/storage/request_callback.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
|
||||
#include <thread>
|
||||
#include <forward_list>
|
||||
|
||||
typedef struct uv_loop_s uv_loop_t;
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class BaseRequest;
|
||||
|
||||
class Request {
|
||||
private:
|
||||
Request(const Request &) = delete;
|
||||
Request(Request &&) = delete;
|
||||
Request& operator=(const Request &) = delete;
|
||||
Request& operator=(Request &&) = delete;
|
||||
|
||||
public:
|
||||
Request(const util::ptr<BaseRequest> &base);
|
||||
~Request();
|
||||
|
||||
void onload(CompletedCallback cb);
|
||||
void oncancel(AbortedCallback cb);
|
||||
void cancel();
|
||||
|
||||
private:
|
||||
const std::thread::id thread_id;
|
||||
util::ptr<BaseRequest> base;
|
||||
std::forward_list<Callback *> callbacks;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef MBGL_STORAGE_REQUEST_CALLBACK
|
||||
#define MBGL_STORAGE_REQUEST_CALLBACK
|
||||
|
||||
#include <mbgl/util/variant.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Response;
|
||||
|
||||
using CompletedCallback = std::function<void(const Response &)>;
|
||||
using AbortedCallback = std::function<void()>;
|
||||
|
||||
using Callback = mapbox::util::variant<
|
||||
CompletedCallback,
|
||||
AbortedCallback
|
||||
>;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
35
include/mbgl/storage/resource.hpp
Normal file
35
include/mbgl/storage/resource.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef MBGL_STORAGE_RESOURCE
|
||||
#define MBGL_STORAGE_RESOURCE
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
struct Resource {
|
||||
enum Kind : uint8_t {
|
||||
Unknown = 0,
|
||||
Tile = 1,
|
||||
Glyphs = 2,
|
||||
Image = 3,
|
||||
JSON = 4,
|
||||
};
|
||||
|
||||
const Kind kind;
|
||||
const std::string url;
|
||||
|
||||
inline bool operator==(const Resource &res) const {
|
||||
return kind == res.kind && url == res.url;
|
||||
}
|
||||
|
||||
struct Hash {
|
||||
std::size_t operator()(Resource const& r) const {
|
||||
return std::hash<std::string>()(r.url) ^ (std::hash<uint8_t>()(r.kind) << 1);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef MBGL_STORAGE_RESOURCE_TYPE
|
||||
#define MBGL_STORAGE_RESOURCE_TYPE
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
enum class ResourceType : uint8_t {
|
||||
Unknown = 0,
|
||||
Tile = 1,
|
||||
Glyphs = 2,
|
||||
Image = 3,
|
||||
JSON = 4
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -2,25 +2,21 @@
|
||||
#define MBGL_STORAGE_RESPONSE
|
||||
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
|
||||
|
||||
class Response {
|
||||
public:
|
||||
long code = 0;
|
||||
enum Status : bool { Error, Successful };
|
||||
|
||||
Status status = Error;
|
||||
std::string message;
|
||||
int64_t modified = 0;
|
||||
int64_t expires = 0;
|
||||
std::string etag;
|
||||
std::string data;
|
||||
|
||||
std::string message;
|
||||
|
||||
static int64_t parseCacheControl(const char *value);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
95
include/mbgl/util/async_queue.hpp
Normal file
95
include/mbgl/util/async_queue.hpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#ifndef MBGL_UTIL_ASYNC_QUEUE
|
||||
#define MBGL_UTIL_ASYNC_QUEUE
|
||||
|
||||
#include "std.hpp"
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
|
||||
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
#define UV_ASYNC_PARAMS(handle) uv_async_t *handle, int
|
||||
#else
|
||||
#define UV_ASYNC_PARAMS(handle) uv_async_t *handle
|
||||
#endif
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
template <typename T>
|
||||
class AsyncQueue {
|
||||
public:
|
||||
AsyncQueue(uv_loop_t *loop, std::function<void(T &)> fn) :
|
||||
callback(fn) {
|
||||
async.data = this;
|
||||
uv_async_init(loop, &async, [](UV_ASYNC_PARAMS(handle)) {
|
||||
auto q = reinterpret_cast<AsyncQueue *>(handle->data);
|
||||
q->process();
|
||||
});
|
||||
}
|
||||
|
||||
void send(T &&data) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
queue.push(util::make_unique<T>(std::move(data)));
|
||||
}
|
||||
uv_async_send(&async);
|
||||
}
|
||||
|
||||
void send(std::unique_ptr<T> data) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
queue.push(std::move(data));
|
||||
}
|
||||
uv_async_send(&async);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
uv_close((uv_handle_t *)&async, [](uv_handle_t *handle) {
|
||||
delete reinterpret_cast<AsyncQueue *>(handle->data);
|
||||
});
|
||||
}
|
||||
|
||||
void ref() {
|
||||
uv_ref((uv_handle_t *)&async);
|
||||
}
|
||||
|
||||
void unref() {
|
||||
uv_unref((uv_handle_t *)&async);
|
||||
}
|
||||
|
||||
private:
|
||||
~AsyncQueue() {
|
||||
}
|
||||
|
||||
void process() {
|
||||
std::unique_ptr<T> item;
|
||||
while (true) {
|
||||
mutex.lock();
|
||||
if (queue.empty()) {
|
||||
mutex.unlock();
|
||||
break;
|
||||
}
|
||||
item = std::move(queue.front());
|
||||
queue.pop();
|
||||
mutex.unlock();
|
||||
callback(*item);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex mutex;
|
||||
uv_async_t async;
|
||||
std::queue<std::unique_ptr<T>> queue;
|
||||
std::function<void(T &)> callback;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -7,41 +7,13 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
typedef uint64_t timestamp;
|
||||
|
||||
namespace util {
|
||||
|
||||
|
||||
// Returns time in nanoseconds since an arbitrary point in the past. This has
|
||||
// no relation to the current time, but is continuously increasing, so
|
||||
// comparisons between different timestamps produce meaningful values.
|
||||
timestamp now();
|
||||
|
||||
|
||||
// Returns the RFC1123 formatted date. E.g. "Tue, 04 Nov 2014 02:13:24 GMT"
|
||||
std::string rfc1123(std::time_t time);
|
||||
|
||||
}
|
||||
|
||||
// used for time conversions
|
||||
constexpr timestamp operator"" _nanoseconds (long double ns) { return ns; }
|
||||
constexpr timestamp operator"" _nanosecond (long double ns) { return ns; }
|
||||
constexpr timestamp operator"" _microseconds (long double us) { return us * 1e3; }
|
||||
constexpr timestamp operator"" _microsecond (long double us) { return us * 1e3; }
|
||||
constexpr timestamp operator"" _milliseconds (long double ms) { return ms * 1e6; }
|
||||
constexpr timestamp operator"" _millisecond (long double ms) { return ms * 1e6; }
|
||||
constexpr timestamp operator"" _seconds (long double s) { return s * 1e9; }
|
||||
constexpr timestamp operator"" _second (long double s) { return s * 1e9; }
|
||||
|
||||
constexpr timestamp operator"" _nanoseconds (unsigned long long ns) { return ns; }
|
||||
constexpr timestamp operator"" _nanosecond (unsigned long long ns) { return ns; }
|
||||
constexpr timestamp operator"" _microseconds (unsigned long long us) { return us * 1e3; }
|
||||
constexpr timestamp operator"" _microsecond (unsigned long long us) { return us * 1e3; }
|
||||
constexpr timestamp operator"" _milliseconds (unsigned long long ms) { return ms * 1e6; }
|
||||
constexpr timestamp operator"" _millisecond (unsigned long long ms) { return ms * 1e6; }
|
||||
constexpr timestamp operator"" _seconds (unsigned long long s) { return s * 1e9; }
|
||||
constexpr timestamp operator"" _second (unsigned long long s) { return s * 1e9; }
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
17
include/mbgl/util/util.hpp
Normal file
17
include/mbgl/util/util.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef MBGL_UTIL_UTIL
|
||||
#define MBGL_UTIL_UTIL
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <thread>
|
||||
#define MBGL_STORE_THREAD(tid) const std::thread::id tid = std::this_thread::get_id();
|
||||
#define MBGL_VERIFY_THREAD(tid) assert(tid == std::this_thread::get_id());
|
||||
|
||||
#else
|
||||
|
||||
#define MBGL_STORE_THREAD(tid)
|
||||
#define MBGL_VERIFY_THREAD(tid)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
typedef struct uv_handle_s uv_handle_t;
|
||||
typedef struct uv_async_s uv_async_t;
|
||||
typedef struct uv_timer_s uv_timer_t;
|
||||
typedef struct uv_handle_s uv_handle_t;
|
||||
typedef struct uv_loop_s uv_loop_t;
|
||||
typedef struct uv_fs_s uv_fs_t;
|
||||
|
||||
namespace uv {
|
||||
|
||||
@@ -19,6 +20,15 @@ class worker;
|
||||
class mutex;
|
||||
class cond;
|
||||
|
||||
const char *getFileRequestError(uv_fs_t *req);
|
||||
|
||||
template <typename T>
|
||||
void close(T *specific) {
|
||||
uv_close(reinterpret_cast<uv_handle_t *>(specific), [](uv_handle_t *generic) {
|
||||
delete reinterpret_cast<T *>(generic);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#include <mbgl/util/recursive_wrapper.hpp>
|
||||
#include "recursive_wrapper.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
|
||||
@@ -34,7 +34,19 @@
|
||||
// translates to 100
|
||||
#define VARIANT_VERSION (VARIANT_MAJOR_VERSION*100000) + (VARIANT_MINOR_VERSION*100) + (VARIANT_PATCH_VERSION)
|
||||
|
||||
namespace mapbox { namespace util { namespace detail {
|
||||
namespace mapbox { namespace util {
|
||||
|
||||
// static visitor
|
||||
template <typename R = void>
|
||||
struct static_visitor
|
||||
{
|
||||
using result_type = R;
|
||||
protected:
|
||||
static_visitor() {}
|
||||
~static_visitor() {}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
static constexpr std::size_t invalid_value = std::size_t(-1);
|
||||
|
||||
@@ -109,18 +121,38 @@ struct select_type<0, T, Types...>
|
||||
using type = T;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// static visitor
|
||||
template <typename R = void>
|
||||
struct static_visitor
|
||||
template <typename T, typename R = void>
|
||||
struct enable_if_type { using type = R; };
|
||||
|
||||
template <typename F, typename V, typename Enable = void>
|
||||
struct result_of_unary_visit
|
||||
{
|
||||
using result_type = R;
|
||||
protected:
|
||||
static_visitor() {}
|
||||
~static_visitor() {}
|
||||
using type = typename std::result_of<F(V&)>::type;
|
||||
};
|
||||
|
||||
template <typename F, typename V>
|
||||
struct result_of_unary_visit<F, V, typename enable_if_type<typename F::result_type>::type >
|
||||
{
|
||||
using type = typename F::result_type;
|
||||
};
|
||||
|
||||
template <typename F, typename V, class Enable = void>
|
||||
struct result_of_binary_visit
|
||||
{
|
||||
using type = typename std::result_of<F(V&,V&)>::type;
|
||||
};
|
||||
|
||||
|
||||
template <typename F, typename V>
|
||||
struct result_of_binary_visit<F, V, typename enable_if_type<typename F::result_type>::type >
|
||||
{
|
||||
using type = typename F::result_type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <std::size_t arg1, std::size_t ... others>
|
||||
struct static_max;
|
||||
@@ -225,7 +257,7 @@ struct dispatcher;
|
||||
template <typename F, typename V, typename T, typename...Types>
|
||||
struct dispatcher<F, V, T, Types...>
|
||||
{
|
||||
using result_type = typename F::result_type;
|
||||
using result_type = typename detail::result_of_unary_visit<F, V>::type;
|
||||
VARIANT_INLINE static result_type apply_const(V const& v, F f)
|
||||
{
|
||||
if (v.get_type_index() == sizeof...(Types))
|
||||
@@ -254,7 +286,7 @@ struct dispatcher<F, V, T, Types...>
|
||||
template<typename F, typename V>
|
||||
struct dispatcher<F, V>
|
||||
{
|
||||
using result_type = typename F::result_type;
|
||||
using result_type = typename detail::result_of_unary_visit<F, V>::type;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, F)
|
||||
{
|
||||
throw std::runtime_error(std::string("unary dispatch: FAIL ") + typeid(V).name());
|
||||
@@ -273,7 +305,7 @@ struct binary_dispatcher_rhs;
|
||||
template <typename F, typename V, typename T0, typename T1, typename...Types>
|
||||
struct binary_dispatcher_rhs<F, V, T0, T1, Types...>
|
||||
{
|
||||
using result_type = typename F::result_type;
|
||||
using result_type = typename detail::result_of_binary_visit<F, V>::type;
|
||||
VARIANT_INLINE static result_type apply_const(V const& lhs, V const& rhs, F f)
|
||||
{
|
||||
if (rhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||
@@ -305,7 +337,7 @@ struct binary_dispatcher_rhs<F, V, T0, T1, Types...>
|
||||
template<typename F, typename V, typename T>
|
||||
struct binary_dispatcher_rhs<F, V, T>
|
||||
{
|
||||
using result_type = typename F::result_type;
|
||||
using result_type = typename detail::result_of_binary_visit<F, V>::type;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
@@ -323,7 +355,7 @@ struct binary_dispatcher_lhs;
|
||||
template <typename F, typename V, typename T0, typename T1, typename...Types>
|
||||
struct binary_dispatcher_lhs<F, V, T0, T1, Types...>
|
||||
{
|
||||
using result_type = typename F::result_type;
|
||||
using result_type = typename detail::result_of_binary_visit<F, V>::type;
|
||||
VARIANT_INLINE static result_type apply_const(V const& lhs, V const& rhs, F f)
|
||||
{
|
||||
if (lhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||
@@ -353,7 +385,7 @@ struct binary_dispatcher_lhs<F, V, T0, T1, Types...>
|
||||
template<typename F, typename V, typename T>
|
||||
struct binary_dispatcher_lhs<F, V, T>
|
||||
{
|
||||
using result_type = typename F::result_type;
|
||||
using result_type = typename detail::result_of_binary_visit<F, V>::type;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
@@ -371,7 +403,7 @@ struct binary_dispatcher;
|
||||
template <typename F, typename V, typename T, typename...Types>
|
||||
struct binary_dispatcher<F, V, T, Types...>
|
||||
{
|
||||
using result_type = typename F::result_type;
|
||||
using result_type = typename detail::result_of_binary_visit<F, V>::type;
|
||||
VARIANT_INLINE static result_type apply_const(V const& v0, V const& v1, F f)
|
||||
{
|
||||
if (v0.get_type_index() == sizeof...(Types))
|
||||
@@ -416,7 +448,7 @@ struct binary_dispatcher<F, V, T, Types...>
|
||||
template<typename F, typename V>
|
||||
struct binary_dispatcher<F, V>
|
||||
{
|
||||
using result_type = typename F::result_type;
|
||||
using result_type = typename detail::result_of_binary_visit<F, V>::type;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
@@ -448,7 +480,7 @@ struct less_comp
|
||||
};
|
||||
|
||||
template <typename Variant, typename Comp>
|
||||
class comparer : public static_visitor<bool>
|
||||
class comparer
|
||||
{
|
||||
public:
|
||||
explicit comparer(Variant const& lhs) noexcept
|
||||
@@ -467,7 +499,7 @@ private:
|
||||
|
||||
// operator<< helper
|
||||
template <typename Out>
|
||||
class printer : public static_visitor<>
|
||||
class printer
|
||||
{
|
||||
public:
|
||||
explicit printer(Out & out)
|
||||
|
||||
Submodule ios/mapbox-gl-cocoa updated: 2e5bfbdcd5...37c9f72675
@@ -4,7 +4,8 @@
|
||||
#include <mbgl/platform/default/settings_json.hpp>
|
||||
#include <mbgl/platform/default/glfw_view.hpp>
|
||||
#include <mbgl/platform/default/log_stderr.hpp>
|
||||
#include <mbgl/storage/caching_http_file_source.hpp>
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
#include <mbgl/storage/default/sqlite_cache.hpp>
|
||||
|
||||
#include <signal.h>
|
||||
#include <getopt.h>
|
||||
@@ -64,7 +65,9 @@ int main(int argc, char *argv[]) {
|
||||
sigaction(SIGINT, &sigIntHandler, NULL);
|
||||
|
||||
view = new GLFWView();
|
||||
mbgl::CachingHTTPFileSource fileSource(mbgl::platform::defaultCacheDatabase());
|
||||
|
||||
mbgl::SQLiteCache cache("/tmp/mbgl-cache.db");
|
||||
mbgl::DefaultFileSource fileSource(&cache);
|
||||
mbgl::Map map(*view, fileSource);
|
||||
|
||||
// Load settings
|
||||
@@ -78,12 +81,13 @@ int main(int argc, char *argv[]) {
|
||||
if (token == nullptr) {
|
||||
mbgl::Log::Warning(mbgl::Event::Setup, "no access token set. mapbox.com tiles won't work.");
|
||||
} else {
|
||||
fileSource.setAccessToken(std::string(token));
|
||||
map.setAccessToken(std::string(token));
|
||||
}
|
||||
|
||||
// Load style
|
||||
if (style.empty())
|
||||
if (style.empty()) {
|
||||
style = std::string("asset://") + std::string("styles/bright-v7.json");
|
||||
}
|
||||
|
||||
map.setStyleURL(style);
|
||||
|
||||
|
||||
@@ -3,55 +3,52 @@
|
||||
'../gyp/common.gypi',
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'linuxapp',
|
||||
{ 'target_name': 'linuxapp',
|
||||
'product_name': 'mapbox-gl',
|
||||
'type': 'executable',
|
||||
|
||||
'dependencies': [
|
||||
'../mbgl.gyp:core',
|
||||
'../mbgl.gyp:platform-<(platform_lib)',
|
||||
'../mbgl.gyp:http-<(http_lib)',
|
||||
'../mbgl.gyp:asset-<(asset_lib)',
|
||||
'../mbgl.gyp:cache-<(cache_lib)',
|
||||
'../mbgl.gyp:bundle_styles',
|
||||
'../mbgl.gyp:copy_certificate_bundle',
|
||||
],
|
||||
|
||||
'sources': [
|
||||
'./main.cpp',
|
||||
'main.cpp',
|
||||
'../platform/default/settings_json.cpp',
|
||||
'../platform/default/glfw_view.cpp',
|
||||
'../platform/default/log_stderr.cpp',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS':[
|
||||
|
||||
'variables' : {
|
||||
'cflags_cc': [
|
||||
'<@(glfw3_cflags)',
|
||||
'<@(png_cflags)',
|
||||
'<@(jpeg_cflags)',
|
||||
],
|
||||
},
|
||||
'cflags_cc': [
|
||||
'<@(glfw3_cflags)',
|
||||
'<@(png_cflags)',
|
||||
'<@(jpeg_cflags)',
|
||||
'-I<(boost_root)/include',
|
||||
],
|
||||
'variables': {
|
||||
'ldflags': [
|
||||
'<@(png_ldflags)',
|
||||
'<@(sqlite3_static_libs)',
|
||||
'<@(sqlite3_ldflags)',
|
||||
'<@(glfw3_static_libs)',
|
||||
'<@(glfw3_ldflags)',
|
||||
'<@(curl_ldflags)',
|
||||
'<@(zlib_ldflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(glfw3_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'libraries': [ '<@(libraries)' ],
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
|
||||
}
|
||||
}, {
|
||||
'libraries': [ '<@(ldflags)' ],
|
||||
'cflags_cc': [ '<@(cflags_cc)' ],
|
||||
'libraries': [ '<@(libraries)', '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
'dependencies': [
|
||||
'../mapboxgl.gyp:mbgl-standalone',
|
||||
'../mapboxgl.gyp:mbgl-linux',
|
||||
'../mapboxgl.gyp:bundle_styles',
|
||||
'../mapboxgl.gyp:copy_certificate_bundle',
|
||||
],
|
||||
|
||||
'copies': [{
|
||||
'files': [ '../styles/styles' ],
|
||||
'destination': '<(PRODUCT_DIR)'
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
#include <mbgl/platform/darwin/log_nslog.hpp>
|
||||
#include <mbgl/platform/darwin/Reachability.h>
|
||||
#include <mbgl/platform/default/glfw_view.hpp>
|
||||
#include <mbgl/storage/caching_http_file_source.hpp>
|
||||
#include <mbgl/storage/default_file_source.hpp>
|
||||
#include <mbgl/storage/default/sqlite_cache.hpp>
|
||||
#include <mbgl/storage/network_status.hpp>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -70,13 +72,39 @@
|
||||
}
|
||||
@end
|
||||
|
||||
// Returns the path to the default cache database on this system.
|
||||
const std::string &defaultCacheDatabase() {
|
||||
static const std::string path = []() -> std::string {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(
|
||||
NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||
if ([paths count] == 0) {
|
||||
// Disable the cache if we don't have a location to write.
|
||||
return "";
|
||||
}
|
||||
|
||||
NSString *p = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Mapbox GL"];
|
||||
|
||||
if (![[NSFileManager defaultManager] createDirectoryAtPath:p
|
||||
withIntermediateDirectories:YES
|
||||
attributes:nil
|
||||
error:nil]) {
|
||||
// Disable the cache if we couldn't create the directory.
|
||||
return "";
|
||||
}
|
||||
|
||||
return [[p stringByAppendingPathComponent:@"cache.db"] UTF8String];
|
||||
}();
|
||||
return path;
|
||||
}
|
||||
|
||||
int main() {
|
||||
mbgl::Log::Set<mbgl::NSLogBackend>();
|
||||
|
||||
GLFWView view;
|
||||
mbgl::CachingHTTPFileSource fileSource(mbgl::platform::defaultCacheDatabase());
|
||||
|
||||
mbgl::SQLiteCache cache(defaultCacheDatabase());
|
||||
mbgl::DefaultFileSource fileSource(&cache);
|
||||
mbgl::Map map(view, fileSource);
|
||||
mbgl::CachingHTTPFileSource *fileSourcePtr = &fileSource;
|
||||
|
||||
URLHandler *handler = [[URLHandler alloc] init];
|
||||
[handler setMap:&map];
|
||||
@@ -86,7 +114,7 @@ int main() {
|
||||
// Notify map object when network reachability status changes.
|
||||
Reachability* reachability = [Reachability reachabilityForInternetConnection];
|
||||
reachability.reachableBlock = ^(Reachability *) {
|
||||
fileSourcePtr->setReachability(true);
|
||||
mbgl::NetworkStatus::Reachable();
|
||||
};
|
||||
[reachability startNotifier];
|
||||
|
||||
@@ -99,7 +127,7 @@ int main() {
|
||||
// Set access token if present
|
||||
NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"];
|
||||
if (!accessToken) mbgl::Log::Warning(mbgl::Event::Setup, "No access token set. Mapbox vector tiles won't work.");
|
||||
if (accessToken) fileSource.setAccessToken([accessToken cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
||||
if (accessToken) map.setAccessToken([accessToken cStringUsingEncoding:[NSString defaultCStringEncoding]]);
|
||||
|
||||
// Load style
|
||||
map.setStyleURL("asset://styles/bright-v7.json");
|
||||
|
||||
@@ -3,10 +3,24 @@
|
||||
'../gyp/common.gypi',
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'osxapp',
|
||||
{ 'target_name': 'osxapp',
|
||||
'product_name': 'Mapbox GL',
|
||||
'type': 'executable',
|
||||
'product_extension': 'app',
|
||||
'mac_bundle': 1,
|
||||
'mac_bundle_resources': [
|
||||
'Icon.icns',
|
||||
],
|
||||
|
||||
'dependencies': [
|
||||
'../mbgl.gyp:bundle_styles',
|
||||
'../mbgl.gyp:core',
|
||||
'../mbgl.gyp:platform-<(platform_lib)',
|
||||
'../mbgl.gyp:http-<(http_lib)',
|
||||
'../mbgl.gyp:asset-<(asset_lib)',
|
||||
'../mbgl.gyp:cache-<(cache_lib)',
|
||||
],
|
||||
|
||||
'sources': [
|
||||
'./main.mm',
|
||||
'../platform/darwin/settings_nsuserdefaults.hpp',
|
||||
@@ -15,51 +29,34 @@
|
||||
'../platform/default/glfw_view.hpp',
|
||||
'../platform/default/glfw_view.cpp',
|
||||
],
|
||||
'product_extension': 'app',
|
||||
'mac_bundle': 1,
|
||||
'mac_bundle_resources': [
|
||||
'Icon.icns',
|
||||
|
||||
'variables' : {
|
||||
'cflags_cc': [
|
||||
'<@(glfw3_cflags)',
|
||||
],
|
||||
'ldflags': [
|
||||
'-framework SystemConfiguration', # For NSUserDefaults and Reachability
|
||||
'<@(glfw3_ldflags)',
|
||||
],
|
||||
'libraries': [
|
||||
'<@(glfw3_static_libs)',
|
||||
],
|
||||
},
|
||||
|
||||
'libraries': [
|
||||
'<@(libraries)',
|
||||
],
|
||||
|
||||
'xcode_settings': {
|
||||
'SDKROOT': 'macosx',
|
||||
'SUPPORTED_PLATFORMS':'macosx',
|
||||
'OTHER_CPLUSPLUSFLAGS': [
|
||||
'<@(glfw3_cflags)'
|
||||
],
|
||||
'OTHER_LDFLAGS': [
|
||||
'<@(glfw3_ldflags)',
|
||||
'-framework SystemConfiguration',
|
||||
],
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
|
||||
'SDKROOT': 'macosx',
|
||||
'INFOPLIST_FILE': 'Info.plist',
|
||||
'MACOSX_DEPLOYMENT_TARGET':'10.9',
|
||||
'MACOSX_DEPLOYMENT_TARGET': '10.9',
|
||||
'CLANG_ENABLE_OBJC_ARC': 'YES'
|
||||
},
|
||||
'variables' : {
|
||||
'ldflags': [
|
||||
'<@(uv_ldflags)',
|
||||
'<@(uv_static_libs)',
|
||||
'<@(sqlite3_static_libs)',
|
||||
'<@(sqlite3_ldflags)',
|
||||
'<@(glfw3_static_libs)',
|
||||
'<@(glfw3_ldflags)',
|
||||
'<@(zlib_ldflags)',
|
||||
]
|
||||
},
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
|
||||
}
|
||||
}, {
|
||||
'ldflags': [ '<@(ldflags)' ],
|
||||
}]
|
||||
],
|
||||
'dependencies': [
|
||||
'../mapboxgl.gyp:bundle_styles',
|
||||
'../mapboxgl.gyp:mbgl-core',
|
||||
'../mapboxgl.gyp:mbgl-osx',
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
13
mapboxgl.gyp
13
mapboxgl.gyp
@@ -1,13 +0,0 @@
|
||||
{
|
||||
'includes': [
|
||||
'./gyp/common.gypi',
|
||||
'./gyp/shaders.gypi',
|
||||
'./gyp/version.gypi',
|
||||
'./gyp/styles.gypi',
|
||||
'./gyp/certificates.gypi',
|
||||
'./gyp/mbgl-core.gypi',
|
||||
'./gyp/mbgl-platform.gypi',
|
||||
'./gyp/mbgl-headless.gypi',
|
||||
'./gyp/install.gypi',
|
||||
],
|
||||
}
|
||||
26
mbgl.gyp
Normal file
26
mbgl.gyp
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
'includes': [
|
||||
'./gyp/common.gypi',
|
||||
'./gyp/shaders.gypi',
|
||||
'./gyp/version.gypi',
|
||||
'./gyp/styles.gypi',
|
||||
'./gyp/certificates.gypi',
|
||||
'./gyp/standalone.gypi',
|
||||
'./gyp/core.gypi',
|
||||
'./gyp/none.gypi',
|
||||
'./gyp/install.gypi',
|
||||
],
|
||||
'conditions': [
|
||||
['headless_lib == "cgl"', { 'includes': [ './gyp/headless-cgl.gypi' ] } ],
|
||||
['headless_lib == "glx"', { 'includes': [ './gyp/headless-glx.gypi' ] } ],
|
||||
['platform_lib == "osx"', { 'includes': [ './gyp/platform-osx.gypi' ] } ],
|
||||
['platform_lib == "ios"', { 'includes': [ './gyp/platform-ios.gypi' ] } ],
|
||||
['platform_lib == "linux"', { 'includes': [ './gyp/platform-linux.gypi' ] } ],
|
||||
['platform_lib == "android"', { 'includes': [ './gyp/platform-android.gypi' ] } ],
|
||||
['http_lib == "curl"', { 'includes': [ './gyp/http-curl.gypi' ] } ],
|
||||
['http_lib == "nsurl"', { 'includes': [ './gyp/http-nsurl.gypi' ] } ],
|
||||
['asset_lib == "fs"', { 'includes': [ './gyp/asset-fs.gypi' ] } ],
|
||||
['asset_lib == "zip"', { 'includes': [ './gyp/asset-zip.gypi' ] } ],
|
||||
['cache_lib == "sqlite"', { 'includes': [ './gyp/cache-sqlite.gypi' ] } ],
|
||||
],
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
#include <mbgl/android/jni.hpp>
|
||||
#include <mbgl/storage/asset_request.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/util/uv_detail.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
|
||||
#include <cerrno>
|
||||
// NOTE a bug in the Android NDK breaks std::errno
|
||||
// See https://code.google.com/p/android/issues/detail?id=72349
|
||||
// After this is fixed change usage errno to std::errno
|
||||
#include <zip.h>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
struct AssetRequestBaton {
|
||||
AssetRequestBaton(AssetRequest *request_, const std::string &path, uv_loop_t *loop);
|
||||
~AssetRequestBaton();
|
||||
|
||||
const std::thread::id threadId;
|
||||
AssetRequest *request = nullptr;
|
||||
std::unique_ptr<uv::async> asyncRun;
|
||||
std::string path;
|
||||
bool canceled = false;
|
||||
|
||||
void cancel();
|
||||
static void notifyError(AssetRequestBaton *ptr, const int code, const char *message);
|
||||
static void notifySuccess(AssetRequestBaton *ptr, const std::string body);
|
||||
static void cleanup(AssetRequestBaton *ptr);
|
||||
static void run(AssetRequestBaton *ptr);
|
||||
};
|
||||
|
||||
AssetRequestBaton::AssetRequestBaton(AssetRequest *request_, const std::string &path_, uv_loop_t *loop)
|
||||
: threadId(std::this_thread::get_id()),
|
||||
request(request_),
|
||||
path(path_) {
|
||||
|
||||
asyncRun = mbgl::util::make_unique<uv::async>(loop, [this]() {
|
||||
run(this);
|
||||
});
|
||||
|
||||
asyncRun->send();
|
||||
}
|
||||
|
||||
AssetRequestBaton::~AssetRequestBaton() {
|
||||
}
|
||||
|
||||
void AssetRequestBaton::cancel() {
|
||||
canceled = true;
|
||||
}
|
||||
|
||||
void AssetRequestBaton::notifyError(AssetRequestBaton *ptr, const int code, const char *message) {
|
||||
assert(std::this_thread::get_id() == ptr->threadId);
|
||||
|
||||
if (ptr->request && !ptr->canceled) {
|
||||
ptr->request->response = std::unique_ptr<Response>(new Response);
|
||||
ptr->request->response->code = code;
|
||||
ptr->request->response->message = message;
|
||||
ptr->request->notify();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestBaton::notifySuccess(AssetRequestBaton *ptr, const std::string body) {
|
||||
assert(std::this_thread::get_id() == ptr->threadId);
|
||||
|
||||
if (ptr->request && !ptr->canceled) {
|
||||
ptr->request->response = std::unique_ptr<Response>(new Response);
|
||||
ptr->request->response->code = 200;
|
||||
ptr->request->response->data = body;
|
||||
ptr->request->notify();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestBaton::cleanup(AssetRequestBaton *ptr) {
|
||||
assert(std::this_thread::get_id() == ptr->threadId);
|
||||
|
||||
if (ptr->request) {
|
||||
ptr->request->ptr = nullptr;
|
||||
}
|
||||
|
||||
ptr->asyncRun.reset();
|
||||
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
void AssetRequestBaton::run(AssetRequestBaton *ptr) {
|
||||
assert(std::this_thread::get_id() == ptr->threadId);
|
||||
|
||||
if (ptr->canceled || !ptr->request) {
|
||||
// Either the AssetRequest object has been destructed, or the
|
||||
// request was canceled.
|
||||
cleanup(ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
int error = 0;
|
||||
struct zip *apk = zip_open(mbgl::android::apkPath.c_str(), 0, &error);
|
||||
if ((apk == nullptr) || ptr->canceled || !ptr->request) {
|
||||
// Opening the APK failed or was canceled. There isn't much left we can do.
|
||||
const int messageSize = zip_error_to_str(nullptr, 0, error, errno);
|
||||
const std::unique_ptr<char[]> message = mbgl::util::make_unique<char[]>(messageSize);
|
||||
zip_error_to_str(message.get(), 0, error, errno);
|
||||
notifyError(ptr, 500, message.get());
|
||||
cleanup(ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string apkFilePath = "assets/" + ptr->path;
|
||||
struct zip_file *apkFile = zip_fopen(apk, apkFilePath.c_str(), ZIP_FL_NOCASE);
|
||||
if ((apkFile == nullptr) || ptr->canceled || !ptr->request) {
|
||||
// Opening the asset failed or was canceled. We already have an open file handle
|
||||
// though, which we'll have to close.
|
||||
zip_error_get(apk, &error, nullptr);
|
||||
notifyError(ptr, error == ZIP_ER_NOENT ? 404 : 500, zip_strerror(apk));
|
||||
zip_close(apk);
|
||||
apk = nullptr;
|
||||
cleanup(ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
struct zip_stat stat;
|
||||
if ((zip_stat(apk, apkFilePath.c_str(), ZIP_FL_NOCASE, &stat) != 0) || ptr->canceled || !ptr->request) {
|
||||
// Stating failed or was canceled. We already have an open file handle
|
||||
// though, which we'll have to close.
|
||||
notifyError(ptr, 500, zip_strerror(apk));
|
||||
zip_fclose(apkFile);
|
||||
apkFile = nullptr;
|
||||
zip_close(apk);
|
||||
apk = nullptr;
|
||||
cleanup(ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
const std::unique_ptr<char[]> data = mbgl::util::make_unique<char[]>(stat.size);
|
||||
|
||||
if (static_cast<zip_uint64_t>(zip_fread(apkFile, reinterpret_cast<void *>(data.get()), stat.size)) != stat.size || ptr->canceled || !ptr->request) {
|
||||
// Reading failed or was canceled. We already have an open file handle
|
||||
// though, which we'll have to close.
|
||||
notifyError(ptr, 500, zip_file_strerror(apkFile));
|
||||
zip_fclose(apkFile);
|
||||
apkFile = nullptr;
|
||||
zip_close(apk);
|
||||
apk = nullptr;
|
||||
cleanup(ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string body(data.get(), stat.size);
|
||||
notifySuccess(ptr, body);
|
||||
|
||||
if (zip_fclose(apkFile) != 0) {
|
||||
// Closing the asset failed. But there isn't anything we can do.
|
||||
}
|
||||
apkFile = nullptr;
|
||||
|
||||
if (zip_close(apk) != 0) {
|
||||
// Closing the APK failed. But there isn't anything we can do.
|
||||
}
|
||||
apk = nullptr;
|
||||
|
||||
cleanup(ptr);
|
||||
}
|
||||
|
||||
AssetRequest::AssetRequest(const std::string &path_, uv_loop_t *loop)
|
||||
: BaseRequest(path_) {
|
||||
if (!path.empty() && path[0] == '/') {
|
||||
// This is an absolute path. We don't allow this. Note that this is not a way to absolutely
|
||||
// prevent access to resources outside the application bundle; e.g. there could be symlinks
|
||||
// in the application bundle that link to outside. We don't care about these.
|
||||
response = util::make_unique<Response>();
|
||||
response->code = 403;
|
||||
response->message = "Path is outside the application bundle";
|
||||
notify();
|
||||
} else {
|
||||
// Note: The AssetRequestBaton object is deleted in AssetRequestBaton::cleanup().
|
||||
ptr = new AssetRequestBaton(this, path, loop);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequest::cancel() {
|
||||
assert(std::this_thread::get_id() == threadId);
|
||||
|
||||
if (ptr) {
|
||||
ptr->cancel();
|
||||
|
||||
// When deleting a AssetRequest object with a uv_fs_* call is in progress, we are making sure
|
||||
// that the callback doesn't accidentally reference this object again.
|
||||
ptr->request = nullptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
notify();
|
||||
}
|
||||
|
||||
AssetRequest::~AssetRequest() {
|
||||
assert(std::this_thread::get_id() == threadId);
|
||||
cancel();
|
||||
|
||||
// Note: The AssetRequestBaton object is deleted in AssetRequestBaton::cleanup().
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
#include <mbgl/android/jni.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the path to the default cache database on this system.
|
||||
std::string defaultCacheDatabase() {
|
||||
return mbgl::android::cachePath + "/mbgl-cache.db";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,8 @@
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the path to the default shader cache on this system.
|
||||
std::string applicationRoot() {
|
||||
// Returns the path to the root folder of the application.
|
||||
const std::string &applicationRoot() {
|
||||
static const std::string root = []() -> std::string {
|
||||
NSString *path = [[[NSBundle mainBundle] resourceURL] path];
|
||||
return {[path cStringUsingEncoding : NSUTF8StringEncoding],
|
||||
|
||||
18
platform/darwin/asset_root.mm
Normal file
18
platform/darwin/asset_root.mm
Normal file
@@ -0,0 +1,18 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the path to the root folder of the application.
|
||||
const std::string &assetRoot() {
|
||||
static const std::string root = []() -> std::string {
|
||||
NSString *path = [[[NSBundle mainBundle] resourceURL] path];
|
||||
return {[path cStringUsingEncoding : NSUTF8StringEncoding],
|
||||
[path lengthOfBytesUsingEncoding:NSUTF8StringEncoding]};
|
||||
}();
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
#include <mbgl/storage/http_request_baton.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/util/parsedate.h>
|
||||
#include <mbgl/util/time.hpp>
|
||||
#include <mbgl/util/version.hpp>
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <mbgl/util/uv.hpp>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
dispatch_once_t request_initialize = 0;
|
||||
NSURLSession *session = nullptr;
|
||||
|
||||
NSString *userAgent = nil;
|
||||
|
||||
void HTTPRequestBaton::start(const util::ptr<HTTPRequestBaton> &ptr) {
|
||||
assert(std::this_thread::get_id() == ptr->threadId);
|
||||
|
||||
// Starts the request.
|
||||
util::ptr<HTTPRequestBaton> baton = ptr;
|
||||
|
||||
dispatch_once(&request_initialize, ^{
|
||||
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
sessionConfig.timeoutIntervalForResource = 30;
|
||||
sessionConfig.HTTPMaximumConnectionsPerHost = 8;
|
||||
sessionConfig.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
|
||||
sessionConfig.URLCache = nil;
|
||||
|
||||
session = [NSURLSession sessionWithConfiguration:sessionConfig];
|
||||
|
||||
// Write user agent string
|
||||
NSDictionary *systemVersion = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"];
|
||||
userAgent = [NSString stringWithFormat:@"MapboxGL/%d.%d.%d (+https://mapbox.com/mapbox-gl/; %s; %@ %@)",
|
||||
version::major, version::minor, version::patch, version::revision,
|
||||
[systemVersion objectForKey:@"ProductName"],
|
||||
[systemVersion objectForKey:@"ProductVersion"]
|
||||
];
|
||||
});
|
||||
|
||||
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@(baton->path.c_str())]];
|
||||
if (baton->response) {
|
||||
if (!baton->response->etag.empty()) {
|
||||
[request addValue:@(baton->response->etag.c_str()) forHTTPHeaderField:@"If-None-Match"];
|
||||
} else if (baton->response->modified) {
|
||||
const std::string time = util::rfc1123(baton->response->modified);
|
||||
[request addValue:@(time.c_str()) forHTTPHeaderField:@"If-Modified-Since"];
|
||||
}
|
||||
}
|
||||
|
||||
[request addValue:userAgent forHTTPHeaderField:@"User-Agent"];
|
||||
|
||||
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
|
||||
completionHandler:^(NSData *data, NSURLResponse *res, NSError *error) {
|
||||
if (error) {
|
||||
if ([error code] == NSURLErrorCancelled) {
|
||||
// The response code remains at 0 to indicate cancelation.
|
||||
// In addition, we don't need any response object.
|
||||
baton->response.reset();
|
||||
baton->type = HTTPResponseType::Canceled;
|
||||
} else {
|
||||
// TODO: Use different codes for host not found, timeout, invalid URL etc.
|
||||
// These can be categorized in temporary and permanent errors.
|
||||
baton->response = util::make_unique<Response>();
|
||||
baton->response->code = [(NSHTTPURLResponse *)res statusCode];
|
||||
baton->response->message = [[error localizedDescription] UTF8String];
|
||||
|
||||
switch ([error code]) {
|
||||
case NSURLErrorBadServerResponse: // 5xx errors
|
||||
baton->type = HTTPResponseType::TemporaryError;
|
||||
break;
|
||||
|
||||
case NSURLErrorTimedOut:
|
||||
case NSURLErrorUserCancelledAuthentication:
|
||||
baton->type = HTTPResponseType::SingularError; // retry immediately
|
||||
break;
|
||||
|
||||
case NSURLErrorNetworkConnectionLost:
|
||||
case NSURLErrorCannotFindHost:
|
||||
case NSURLErrorCannotConnectToHost:
|
||||
case NSURLErrorDNSLookupFailed:
|
||||
case NSURLErrorNotConnectedToInternet:
|
||||
case NSURLErrorInternationalRoamingOff:
|
||||
case NSURLErrorCallIsActive:
|
||||
case NSURLErrorDataNotAllowed:
|
||||
baton->type = HTTPResponseType::ConnectionError;
|
||||
break;
|
||||
|
||||
default:
|
||||
baton->type = HTTPResponseType::PermanentError;
|
||||
}
|
||||
}
|
||||
} else if ([res isKindOfClass:[NSHTTPURLResponse class]]) {
|
||||
const long code = [(NSHTTPURLResponse *)res statusCode];
|
||||
if (code == 304) {
|
||||
// Assume a Response object already exists.
|
||||
assert(baton->response);
|
||||
} else {
|
||||
baton->response = util::make_unique<Response>();
|
||||
baton->response->code = code;
|
||||
baton->response->data = {(const char *)[data bytes], [data length]};
|
||||
}
|
||||
|
||||
if (code == 304) {
|
||||
baton->type = HTTPResponseType::NotModified;
|
||||
} else if (code == 200) {
|
||||
baton->type = HTTPResponseType::Successful;
|
||||
} else {
|
||||
baton->type = HTTPResponseType::PermanentError;
|
||||
}
|
||||
|
||||
NSDictionary *headers = [(NSHTTPURLResponse *)res allHeaderFields];
|
||||
NSString *cache_control = [headers objectForKey:@"Cache-Control"];
|
||||
if (cache_control) {
|
||||
baton->response->expires = Response::parseCacheControl([cache_control UTF8String]);
|
||||
}
|
||||
|
||||
NSString *last_modified = [headers objectForKey:@"Last-Modified"];
|
||||
if (last_modified) {
|
||||
baton->response->modified = parse_date([last_modified UTF8String]);
|
||||
}
|
||||
|
||||
NSString *etag = [headers objectForKey:@"ETag"];
|
||||
if (etag) {
|
||||
baton->response->etag = [etag UTF8String];
|
||||
}
|
||||
} else {
|
||||
// This should never happen.
|
||||
baton->type = HTTPResponseType::PermanentError;
|
||||
baton->response = util::make_unique<Response>();
|
||||
baton->response->code = -1;
|
||||
baton->response->message = "response class is not NSHTTPURLResponse";
|
||||
}
|
||||
|
||||
uv_async_send(baton->async);
|
||||
}];
|
||||
|
||||
[task resume];
|
||||
|
||||
baton->ptr = const_cast<void *>(CFBridgingRetain(task));
|
||||
}
|
||||
|
||||
void HTTPRequestBaton::stop(const util::ptr<HTTPRequestBaton> &ptr) {
|
||||
assert(std::this_thread::get_id() == ptr->threadId);
|
||||
assert(ptr->ptr);
|
||||
|
||||
NSURLSessionDataTask *task = CFBridgingRelease(ptr->ptr);
|
||||
ptr->ptr = nullptr;
|
||||
[task cancel];
|
||||
}
|
||||
|
||||
}
|
||||
419
platform/darwin/http_request_nsurl.mm
Normal file
419
platform/darwin/http_request_nsurl.mm
Normal file
@@ -0,0 +1,419 @@
|
||||
#include <mbgl/storage/default/http_request.hpp>
|
||||
#include <mbgl/storage/default/http_context.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/util/uv.hpp>
|
||||
|
||||
#include <mbgl/util/time.hpp>
|
||||
#include <mbgl/util/parsedate.h>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <map>
|
||||
#include <cassert>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
enum class ResponseStatus : uint8_t {
|
||||
// This error probably won't be resolved by retrying anytime soon. We are giving up.
|
||||
PermanentError,
|
||||
|
||||
// This error might be resolved by waiting some time (e.g. server issues).
|
||||
// We are going to do an exponential back-off and will try again in a few seconds.
|
||||
TemporaryError,
|
||||
|
||||
// This error was caused by a temporary error and it is likely that it will be resolved
|
||||
// immediately. We are going to try again right away. This is like the TemporaryError, except
|
||||
// that we will not perform exponential back-off.
|
||||
SingularError,
|
||||
|
||||
// This error might be resolved once the network reachability status changes.
|
||||
// We are going to watch the network status for changes and will retry as soon as the
|
||||
// operating system notifies us of a network status change.
|
||||
ConnectionError,
|
||||
|
||||
// The request was canceled mid-way.
|
||||
Canceled,
|
||||
|
||||
// The request returned data successfully. We retrieved and decoded the data successfully.
|
||||
Successful,
|
||||
|
||||
// The request confirmed that the data wasn't changed. We already have the data.
|
||||
NotModified,
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
class HTTPNSURLContext;
|
||||
|
||||
class HTTPRequestImpl {
|
||||
public:
|
||||
HTTPRequestImpl(HTTPRequest *request, uv_loop_t *loop, std::unique_ptr<Response> response);
|
||||
~HTTPRequestImpl();
|
||||
|
||||
void cancel();
|
||||
void cancelTimer();
|
||||
|
||||
void start();
|
||||
void handleResult(NSData *data, NSURLResponse *res, NSError *error);
|
||||
void handleResponse();
|
||||
|
||||
void retry(uint64_t timeout);
|
||||
void retryImmediately();
|
||||
static void restart(uv_timer_t *timer, int);
|
||||
|
||||
private:
|
||||
HTTPNSURLContext *context = nullptr;
|
||||
HTTPRequest *request = nullptr;
|
||||
NSURLSessionDataTask *task = nullptr;
|
||||
std::unique_ptr<Response> response;
|
||||
std::unique_ptr<Response> existingResponse;
|
||||
ResponseStatus status = ResponseStatus::PermanentError;
|
||||
uv_async_t *async = nullptr;
|
||||
int attempts = 0;
|
||||
uv_timer_t *timer = nullptr;
|
||||
enum : bool { PreemptImmediately, ExponentialBackoff } strategy = PreemptImmediately;
|
||||
|
||||
static const int maxAttempts = 4;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
class HTTPNSURLContext : public HTTPContext<HTTPNSURLContext> {
|
||||
public:
|
||||
HTTPNSURLContext(uv_loop_t *loop);
|
||||
~HTTPNSURLContext();
|
||||
|
||||
NSURLSession *session = nil;
|
||||
NSString *userAgent = nil;
|
||||
};
|
||||
|
||||
template<> pthread_key_t ThreadContext<HTTPNSURLContext>::key{};
|
||||
template<> pthread_once_t ThreadContext<HTTPNSURLContext>::once = PTHREAD_ONCE_INIT;
|
||||
|
||||
HTTPNSURLContext::HTTPNSURLContext(uv_loop_t *loop_) : HTTPContext(loop_) {
|
||||
@autoreleasepool {
|
||||
NSURLSessionConfiguration *sessionConfig =
|
||||
[NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
sessionConfig.timeoutIntervalForResource = 30;
|
||||
sessionConfig.HTTPMaximumConnectionsPerHost = 8;
|
||||
sessionConfig.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
|
||||
sessionConfig.URLCache = nil;
|
||||
|
||||
session = [NSURLSession sessionWithConfiguration:sessionConfig];
|
||||
[session retain];
|
||||
|
||||
// Write user agent string
|
||||
userAgent = @"MapboxGL";
|
||||
}
|
||||
}
|
||||
|
||||
HTTPNSURLContext::~HTTPNSURLContext() {
|
||||
[session release];
|
||||
session = nullptr;
|
||||
|
||||
[userAgent release];
|
||||
userAgent = nullptr;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
HTTPRequestImpl::HTTPRequestImpl(HTTPRequest *request_, uv_loop_t *loop,
|
||||
std::unique_ptr<Response> existingResponse_)
|
||||
: context(HTTPNSURLContext::Get(loop)),
|
||||
request(request_),
|
||||
existingResponse(std::move(existingResponse_)),
|
||||
async(new uv_async_t) {
|
||||
assert(request);
|
||||
context->addRequest(request);
|
||||
|
||||
async->data = this;
|
||||
uv_async_init(loop, async, [](uv_async_t *as, int) {
|
||||
auto impl = reinterpret_cast<HTTPRequestImpl *>(as->data);
|
||||
impl->handleResponse();
|
||||
});
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::start() {
|
||||
assert(!task);
|
||||
|
||||
attempts++;
|
||||
|
||||
@autoreleasepool {
|
||||
NSMutableURLRequest *req = [[NSMutableURLRequest alloc]
|
||||
initWithURL:[NSURL URLWithString:@(request->resource.url.c_str())]];
|
||||
if (existingResponse) {
|
||||
if (!existingResponse->etag.empty()) {
|
||||
[req addValue:@(existingResponse->etag.c_str()) forHTTPHeaderField:@"If-None-Match"];
|
||||
} else if (existingResponse->modified) {
|
||||
const std::string time = util::rfc1123(existingResponse->modified);
|
||||
[req addValue:@(time.c_str()) forHTTPHeaderField:@"If-Modified-Since"];
|
||||
}
|
||||
}
|
||||
|
||||
[req addValue:context->userAgent forHTTPHeaderField:@"User-Agent"];
|
||||
|
||||
task = [context->session dataTaskWithRequest:req
|
||||
completionHandler:^(NSData *data, NSURLResponse *res,
|
||||
NSError *error) { handleResult(data, res, error); }];
|
||||
[req release];
|
||||
[task retain];
|
||||
[task resume];
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::handleResponse() {
|
||||
if (task) {
|
||||
[task release];
|
||||
task = nullptr;
|
||||
}
|
||||
|
||||
if (request) {
|
||||
if (status == ResponseStatus::TemporaryError && attempts < maxAttempts) {
|
||||
strategy = ExponentialBackoff;
|
||||
return retry((1 << (attempts - 1)) * 1000);
|
||||
} else if (status == ResponseStatus::ConnectionError && attempts < maxAttempts) {
|
||||
// By default, we will retry every 30 seconds (network change notification will
|
||||
// preempt the timeout).
|
||||
strategy = PreemptImmediately;
|
||||
return retry(30000);
|
||||
}
|
||||
|
||||
// Actually return the response.
|
||||
if (status == ResponseStatus::NotModified) {
|
||||
request->notify(std::move(response), FileCache::Hint::Refresh);
|
||||
} else {
|
||||
request->notify(std::move(response), FileCache::Hint::Full);
|
||||
}
|
||||
|
||||
context->removeRequest(request);
|
||||
delete request;
|
||||
request = nullptr;
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::cancel() {
|
||||
context->removeRequest(request);
|
||||
request = nullptr;
|
||||
|
||||
// Stop the backoff timer to avoid re-triggering this request.
|
||||
cancelTimer();
|
||||
|
||||
if (task) {
|
||||
[task cancel];
|
||||
[task release];
|
||||
task = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::cancelTimer() {
|
||||
if (timer) {
|
||||
uv_timer_stop(timer);
|
||||
uv::close(timer);
|
||||
timer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
HTTPRequestImpl::~HTTPRequestImpl() {
|
||||
assert(!task);
|
||||
assert(async);
|
||||
|
||||
// Stop the backoff timer to avoid re-triggering this request.
|
||||
cancelTimer();
|
||||
|
||||
uv::close(async);
|
||||
|
||||
if (request) {
|
||||
context->removeRequest(request);
|
||||
request->ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t parseCacheControl(const char *value) {
|
||||
if (value) {
|
||||
unsigned long long seconds = 0;
|
||||
// TODO: cache-control may contain other information as well:
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
|
||||
if (std::sscanf(value, "max-age=%llu", &seconds) == 1) {
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()).count() +
|
||||
seconds;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::handleResult(NSData *data, NSURLResponse *res, NSError *error) {
|
||||
if (error) {
|
||||
if ([error code] == NSURLErrorCancelled) {
|
||||
status = ResponseStatus::Canceled;
|
||||
} else {
|
||||
// TODO: Use different codes for host not found, timeout, invalid URL etc.
|
||||
// These can be categorized in temporary and permanent errors.
|
||||
response = util::make_unique<Response>();
|
||||
response->status = Response::Error;
|
||||
response->message = [[error localizedDescription] UTF8String];
|
||||
|
||||
switch ([error code]) {
|
||||
case NSURLErrorBadServerResponse: // 5xx errors
|
||||
status = ResponseStatus::TemporaryError;
|
||||
break;
|
||||
|
||||
case NSURLErrorTimedOut:
|
||||
case NSURLErrorUserCancelledAuthentication:
|
||||
status = ResponseStatus::SingularError; // retry immediately
|
||||
break;
|
||||
|
||||
case NSURLErrorNetworkConnectionLost:
|
||||
case NSURLErrorCannotFindHost:
|
||||
case NSURLErrorCannotConnectToHost:
|
||||
case NSURLErrorDNSLookupFailed:
|
||||
case NSURLErrorNotConnectedToInternet:
|
||||
case NSURLErrorInternationalRoamingOff:
|
||||
case NSURLErrorCallIsActive:
|
||||
case NSURLErrorDataNotAllowed:
|
||||
status = ResponseStatus::ConnectionError;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = ResponseStatus::PermanentError;
|
||||
}
|
||||
}
|
||||
} else if ([res isKindOfClass:[NSHTTPURLResponse class]]) {
|
||||
const long responseCode = [(NSHTTPURLResponse *)res statusCode];
|
||||
|
||||
response = util::make_unique<Response>();
|
||||
response->data = {(const char *)[data bytes], [data length]};
|
||||
|
||||
NSDictionary *headers = [(NSHTTPURLResponse *)res allHeaderFields];
|
||||
NSString *cache_control = [headers objectForKey:@"Cache-Control"];
|
||||
if (cache_control) {
|
||||
response->expires = parseCacheControl([cache_control UTF8String]);
|
||||
}
|
||||
|
||||
NSString *expires = [headers objectForKey:@"Expires"];
|
||||
if (expires) {
|
||||
response->expires = parse_date([expires UTF8String]);
|
||||
}
|
||||
|
||||
NSString *last_modified = [headers objectForKey:@"Last-Modified"];
|
||||
if (last_modified) {
|
||||
response->modified = parse_date([last_modified UTF8String]);
|
||||
}
|
||||
|
||||
NSString *etag = [headers objectForKey:@"ETag"];
|
||||
if (etag) {
|
||||
response->etag = [etag UTF8String];
|
||||
}
|
||||
|
||||
if (responseCode == 304) {
|
||||
if (existingResponse) {
|
||||
// We're going to reuse the old response object, but need to copy over the new
|
||||
// expires value (if possible).
|
||||
std::swap(response, existingResponse);
|
||||
if (existingResponse->expires) {
|
||||
response->expires = existingResponse->expires;
|
||||
}
|
||||
status = ResponseStatus::NotModified;
|
||||
} else {
|
||||
// This is an unsolicited 304 response and should only happen on malfunctioning
|
||||
// HTTP servers. It likely doesn't include any data, but we don't have much options.
|
||||
response->status = Response::Successful;
|
||||
status = ResponseStatus::Successful;
|
||||
}
|
||||
} else if (responseCode == 200) {
|
||||
response->status = Response::Successful;
|
||||
status = ResponseStatus::Successful;
|
||||
} else if (responseCode >= 500 && responseCode < 600) {
|
||||
// Server errors may be temporary, so back off exponentially.
|
||||
response->status = Response::Error;
|
||||
response->message = "HTTP status code " + std::to_string(responseCode);
|
||||
status = ResponseStatus::TemporaryError;
|
||||
} else {
|
||||
// We don't know how to handle any other errors, so declare them as permanently failing.
|
||||
response->status = Response::Error;
|
||||
response->message = "HTTP status code " + std::to_string(responseCode);
|
||||
status = ResponseStatus::PermanentError;
|
||||
}
|
||||
} else {
|
||||
// This should never happen.
|
||||
status = ResponseStatus::PermanentError;
|
||||
response = util::make_unique<Response>();
|
||||
response->status = Response::Error;
|
||||
response->message = "response class is not NSHTTPURLResponse";
|
||||
}
|
||||
|
||||
uv_async_send(async);
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::retry(uint64_t timeout) {
|
||||
response.reset();
|
||||
|
||||
assert(!timer);
|
||||
timer = new uv_timer_t;
|
||||
timer->data = this;
|
||||
uv_timer_init(async->loop, timer);
|
||||
uv_timer_start(timer, restart, timeout, 0);
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::retryImmediately() {
|
||||
// All batons get notified when the network status changed, but some of them
|
||||
// might not actually wait for the network to become available again.
|
||||
if (timer && strategy == PreemptImmediately) {
|
||||
// Triggers the timer upon the next event loop iteration.
|
||||
uv_timer_stop(timer);
|
||||
uv_timer_start(timer, restart, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::restart(uv_timer_t *timer, int) {
|
||||
// Restart the request.
|
||||
auto impl = reinterpret_cast<HTTPRequestImpl *>(timer->data);
|
||||
|
||||
// Get rid of the timer.
|
||||
impl->timer = nullptr;
|
||||
uv::close(timer);
|
||||
|
||||
impl->start();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
HTTPRequest::HTTPRequest(DefaultFileSource *source, const Resource &resource)
|
||||
: SharedRequestBase(source, resource) {
|
||||
}
|
||||
|
||||
HTTPRequest::~HTTPRequest() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (ptr) {
|
||||
reinterpret_cast<HTTPRequestImpl *>(ptr)->cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPRequest::start(uv_loop_t *loop, std::unique_ptr<Response> response) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
assert(!ptr);
|
||||
ptr = new HTTPRequestImpl(this, loop, std::move(response));
|
||||
}
|
||||
|
||||
void HTTPRequest::retryImmediately() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (ptr) {
|
||||
reinterpret_cast<HTTPRequestImpl *>(ptr)->retryImmediately();
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPRequest::cancel() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,14 +7,13 @@
|
||||
namespace mbgl {
|
||||
|
||||
void NSLogBackend::record(EventSeverity severity, Event event, const std::string &msg) {
|
||||
NSLog(@"[%s] %s: %@", EventSeverityClass(severity).c_str(), EventClass(event).c_str(),
|
||||
[[NSString alloc] initWithBytes:msg.data()
|
||||
length:msg.size()
|
||||
encoding:NSUTF8StringEncoding]);
|
||||
NSString *message =
|
||||
[[NSString alloc] initWithBytes:msg.data() length:msg.size() encoding:NSUTF8StringEncoding];
|
||||
NSLog(@"[%s] %s: %@", EventSeverityClass(severity).c_str(), EventClass(event).c_str(), message);
|
||||
[message release];
|
||||
}
|
||||
|
||||
|
||||
void NSLogBackend::record(EventSeverity severity, Event event, const char* format, ...) {
|
||||
void NSLogBackend::record(EventSeverity severity, Event event, const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
const size_t len = vsnprintf(NULL, 0, format, args);
|
||||
@@ -23,17 +22,22 @@ void NSLogBackend::record(EventSeverity severity, Event event, const char* forma
|
||||
va_start(args, format);
|
||||
vsnprintf(buffer.get(), len + 1, format, args);
|
||||
va_end(args);
|
||||
NSLog(@"[%s] %s: %s", EventSeverityClass(severity).c_str(), EventClass(event).c_str(), buffer.get());
|
||||
NSLog(@"[%s] %s: %s", EventSeverityClass(severity).c_str(), EventClass(event).c_str(),
|
||||
buffer.get());
|
||||
}
|
||||
|
||||
void NSLogBackend::record(EventSeverity severity, Event event, int64_t code) {
|
||||
NSLog(@"[%s] %s: (%lld)", EventSeverityClass(severity).c_str(), EventClass(event).c_str(), code);
|
||||
NSLog(@"[%s] %s: (%lld)", EventSeverityClass(severity).c_str(), EventClass(event).c_str(),
|
||||
code);
|
||||
}
|
||||
|
||||
void NSLogBackend::record(EventSeverity severity, Event event, int64_t code, const std::string &msg) {
|
||||
NSLog(@"[%s] %s: (%lld) %@", EventSeverityClass(severity).c_str(), EventClass(event).c_str(), code,
|
||||
[[NSString alloc] initWithBytes:msg.data()
|
||||
length:msg.size()
|
||||
encoding:NSUTF8StringEncoding]);
|
||||
void NSLogBackend::record(EventSeverity severity, Event event, int64_t code,
|
||||
const std::string &msg) {
|
||||
NSString *message =
|
||||
[[NSString alloc] initWithBytes:msg.data() length:msg.size() encoding:NSUTF8StringEncoding];
|
||||
NSLog(@"[%s] %s: (%lld) %@", EventSeverityClass(severity).c_str(), EventClass(event).c_str(),
|
||||
code, message);
|
||||
[message release];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,15 +6,27 @@ namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
std::string uppercase(const std::string &string) {
|
||||
NSString *nsstring = [[NSString alloc] initWithBytesNoCopy:const_cast<char *>(string.data()) length:string.size() encoding:NSUTF8StringEncoding freeWhenDone:NO];
|
||||
nsstring = [nsstring uppercaseString];
|
||||
return { [nsstring cStringUsingEncoding:NSUTF8StringEncoding], [nsstring lengthOfBytesUsingEncoding:NSUTF8StringEncoding] };
|
||||
NSString *original = [[NSString alloc] initWithBytesNoCopy:const_cast<char *>(string.data())
|
||||
length:string.size()
|
||||
encoding:NSUTF8StringEncoding
|
||||
freeWhenDone:NO];
|
||||
NSString *uppercase = [original uppercaseString];
|
||||
const std::string result{[uppercase cStringUsingEncoding : NSUTF8StringEncoding],
|
||||
[uppercase lengthOfBytesUsingEncoding:NSUTF8StringEncoding]};
|
||||
[original release];
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string lowercase(const std::string &string) {
|
||||
NSString *nsstring = [[NSString alloc] initWithBytesNoCopy:const_cast<char *>(string.data()) length:string.size() encoding:NSUTF8StringEncoding freeWhenDone:NO];
|
||||
nsstring = [nsstring lowercaseString];
|
||||
return { [nsstring cStringUsingEncoding:NSUTF8StringEncoding], [nsstring lengthOfBytesUsingEncoding:NSUTF8StringEncoding] };
|
||||
NSString *original = [[NSString alloc] initWithBytesNoCopy:const_cast<char *>(string.data())
|
||||
length:string.size()
|
||||
encoding:NSUTF8StringEncoding
|
||||
freeWhenDone:NO];
|
||||
NSString *lowercase = [original lowercaseString];
|
||||
const std::string result{[lowercase cStringUsingEncoding : NSUTF8StringEncoding],
|
||||
[lowercase lengthOfBytesUsingEncoding:NSUTF8StringEncoding]};
|
||||
[original release];
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,26 @@
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
#include <mbgl/util/uv.hpp>
|
||||
#include <uv.h>
|
||||
#include <libgen.h>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the path the application root.
|
||||
std::string applicationRoot() {
|
||||
static const std::string root = uv::cwd();
|
||||
// Returns the path to the root folder of the application.
|
||||
const std::string &applicationRoot() {
|
||||
static const std::string root = []() -> std::string {
|
||||
size_t max = 0;
|
||||
std::string dir;
|
||||
do {
|
||||
// Gradually increase the length of the string in case the path was truncated.
|
||||
max += 256;
|
||||
dir.resize(max);
|
||||
uv_exepath(const_cast<char *>(dir.data()), &max);
|
||||
} while (max == dir.size());
|
||||
dir.resize(max - 1);
|
||||
dir = dirname(const_cast<char *>(dir.c_str()));
|
||||
return dir;
|
||||
}();
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
252
platform/default/asset_request_fs.cpp
Normal file
252
platform/default/asset_request_fs.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
#include <mbgl/storage/default/asset_request.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/util/util.hpp>
|
||||
#include <mbgl/util/uv.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#ifndef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
namespace algo = boost::algorithm;
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class AssetRequestImpl {
|
||||
MBGL_STORE_THREAD(tid)
|
||||
|
||||
public:
|
||||
AssetRequestImpl(AssetRequest *request, uv_loop_t *loop);
|
||||
~AssetRequestImpl();
|
||||
|
||||
static void fileOpened(uv_fs_t *req);
|
||||
static void fileStated(uv_fs_t *req);
|
||||
static void fileRead(uv_fs_t *req);
|
||||
static void fileClosed(uv_fs_t *req);
|
||||
static void notifyError(uv_fs_t *req);
|
||||
static void cleanup(uv_fs_t *req);
|
||||
|
||||
|
||||
AssetRequest *request = nullptr;
|
||||
bool canceled = false;
|
||||
uv_fs_t req;
|
||||
uv_file fd = -1;
|
||||
uv_buf_t buffer;
|
||||
std::unique_ptr<Response> response;
|
||||
};
|
||||
|
||||
AssetRequestImpl::~AssetRequestImpl() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (request) {
|
||||
request->ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop) : request(request_) {
|
||||
req.data = this;
|
||||
|
||||
const auto &url = request->resource.url;
|
||||
std::string path;
|
||||
if (url.size() <= 8 || url[8] == '/') {
|
||||
// This is an empty or absolute path.
|
||||
path = url.substr(8);
|
||||
} else {
|
||||
// This is a relative path. Prefix with the application root.
|
||||
path = platform::assetRoot() + "/" + url.substr(8);
|
||||
}
|
||||
|
||||
uv_fs_open(loop, &req, path.c_str(), O_RDONLY, S_IRUSR, fileOpened);
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileOpened(uv_fs_t *req) {
|
||||
assert(req->data);
|
||||
auto self = reinterpret_cast<AssetRequestImpl *>(req->data);
|
||||
MBGL_VERIFY_THREAD(self->tid);
|
||||
|
||||
if (req->result < 0) {
|
||||
// Opening failed or was canceled. There isn't much left we can do.
|
||||
notifyError(req);
|
||||
cleanup(req);
|
||||
} else {
|
||||
const uv_file fd = uv_file(req->result);
|
||||
|
||||
// We're going to reuse this handle, so we need to cleanup first.
|
||||
uv_fs_req_cleanup(req);
|
||||
|
||||
if (self->canceled) {
|
||||
// The request was canceled.
|
||||
uv_fs_close(req->loop, req, fd, fileClosed);
|
||||
} else {
|
||||
self->fd = fd;
|
||||
uv_fs_fstat(req->loop, req, fd, fileStated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileStated(uv_fs_t *req) {
|
||||
assert(req->data);
|
||||
auto self = reinterpret_cast<AssetRequestImpl *>(req->data);
|
||||
MBGL_VERIFY_THREAD(self->tid);
|
||||
|
||||
if (req->result != 0 || self->canceled) {
|
||||
// Stating failed or was canceled. We already have an open file handle
|
||||
// though, which we'll have to close.
|
||||
notifyError(req);
|
||||
|
||||
uv_fs_req_cleanup(req);
|
||||
uv_fs_close(req->loop, req, self->fd, fileClosed);
|
||||
} else {
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
auto stat = static_cast<const uv_statbuf_t *>(req->ptr);
|
||||
#else
|
||||
auto stat = static_cast<const uv_stat_t *>(req->ptr);
|
||||
#endif
|
||||
if (stat->st_size > std::numeric_limits<int>::max()) {
|
||||
// File is too large for us to open this way because uv_buf's only support unsigned
|
||||
// ints as maximum size.
|
||||
auto response = util::make_unique<Response>();
|
||||
response->status = Response::Error;
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
response->message = uv_strerror(uv_err_t {UV_EFBIG, 0});
|
||||
#else
|
||||
response->message = uv_strerror(UV_EFBIG);
|
||||
#endif
|
||||
assert(self->request);
|
||||
self->request->notify(std::move(response), FileCache::Hint::No);
|
||||
delete self->request;
|
||||
|
||||
uv_fs_req_cleanup(req);
|
||||
uv_fs_close(req->loop, req, self->fd, fileClosed);
|
||||
} else {
|
||||
self->response = util::make_unique<Response>();
|
||||
#ifdef __APPLE__
|
||||
self->response->modified = stat->st_mtimespec.tv_sec;
|
||||
#else
|
||||
self->response->modified = stat->st_mtime;
|
||||
#endif
|
||||
self->response->etag = std::to_string(stat->st_ino);
|
||||
const auto size = (unsigned int)(stat->st_size);
|
||||
self->response->data.resize(size);
|
||||
self->buffer = uv_buf_init(const_cast<char *>(self->response->data.data()), size);
|
||||
uv_fs_req_cleanup(req);
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
uv_fs_read(req->loop, req, self->fd, self->buffer.base, self->buffer.len, -1, fileRead);
|
||||
#else
|
||||
uv_fs_read(req->loop, req, self->fd, &self->buffer, 1, 0, fileRead);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileRead(uv_fs_t *req) {
|
||||
assert(req->data);
|
||||
auto self = reinterpret_cast<AssetRequestImpl *>(req->data);
|
||||
MBGL_VERIFY_THREAD(self->tid);
|
||||
|
||||
if (req->result < 0 || self->canceled) {
|
||||
// Stating failed or was canceled. We already have an open file handle
|
||||
// though, which we'll have to close.
|
||||
notifyError(req);
|
||||
} else {
|
||||
// File was successfully read.
|
||||
self->response->status = Response::Successful;
|
||||
assert(self->request);
|
||||
self->request->notify(std::move(self->response), FileCache::Hint::No);
|
||||
delete self->request;
|
||||
}
|
||||
|
||||
uv_fs_req_cleanup(req);
|
||||
uv_fs_close(req->loop, req, self->fd, fileClosed);
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileClosed(uv_fs_t *req) {
|
||||
assert(req->data);
|
||||
auto self = reinterpret_cast<AssetRequestImpl *>(req->data);
|
||||
MBGL_VERIFY_THREAD(self->tid);
|
||||
(void(self)); // Silence unused variable error in Release mode
|
||||
|
||||
if (req->result < 0) {
|
||||
// Closing the file failed. But there isn't anything we can do.
|
||||
}
|
||||
|
||||
cleanup(req);
|
||||
}
|
||||
|
||||
void AssetRequestImpl::notifyError(uv_fs_t *req) {
|
||||
assert(req->data);
|
||||
auto self = reinterpret_cast<AssetRequestImpl *>(req->data);
|
||||
MBGL_VERIFY_THREAD(self->tid);
|
||||
|
||||
if (req->result < 0 && !self->canceled && req->result != UV_ECANCELED) {
|
||||
auto response = util::make_unique<Response>();
|
||||
response->status = Response::Error;
|
||||
response->message = uv::getFileRequestError(req);
|
||||
assert(self->request);
|
||||
self->request->notify(std::move(response), FileCache::Hint::No);
|
||||
delete self->request;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::cleanup(uv_fs_t *req) {
|
||||
assert(req->data);
|
||||
auto self = reinterpret_cast<AssetRequestImpl *>(req->data);
|
||||
MBGL_VERIFY_THREAD(self->tid);
|
||||
uv_fs_req_cleanup(req);
|
||||
delete self;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
AssetRequest::AssetRequest(DefaultFileSource *source_, const Resource &resource_)
|
||||
: SharedRequestBase(source_, resource_) {
|
||||
assert(algo::starts_with(resource.url, "asset://"));
|
||||
}
|
||||
|
||||
AssetRequest::~AssetRequest() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (ptr) {
|
||||
reinterpret_cast<AssetRequestImpl *>(ptr)->request = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequest::start(uv_loop_t *loop, std::unique_ptr<Response> response) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
// We're ignoring the existing response if any.
|
||||
(void(response));
|
||||
|
||||
assert(!ptr);
|
||||
ptr = new AssetRequestImpl(this, loop);
|
||||
// Note: the AssetRequestImpl deletes itself.
|
||||
}
|
||||
|
||||
void AssetRequest::cancel() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (ptr) {
|
||||
reinterpret_cast<AssetRequestImpl *>(ptr)->canceled = true;
|
||||
|
||||
// uv_cancel fails frequently when the request has already been started.
|
||||
// In that case, we have to let it complete and check the canceled bool
|
||||
// instead. The cancelation callback will delete the AssetRequest object.
|
||||
uv_cancel((uv_req_t *)&reinterpret_cast<AssetRequestImpl *>(ptr)->req);
|
||||
} else {
|
||||
// This request is canceled before we called start. We're safe to delete
|
||||
// ourselves now.
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
#include <mbgl/storage/asset_request.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
struct AssetRequestBaton {
|
||||
AssetRequestBaton(AssetRequest *request_, const std::string &path, uv_loop_t *loop);
|
||||
~AssetRequestBaton();
|
||||
|
||||
void cancel();
|
||||
static void fileOpened(uv_fs_t *req);
|
||||
static void fileStated(uv_fs_t *req);
|
||||
static void fileRead(uv_fs_t *req);
|
||||
static void fileClosed(uv_fs_t *req);
|
||||
static void notifyError(uv_fs_t *req);
|
||||
static void cleanup(uv_fs_t *req);
|
||||
|
||||
const std::thread::id threadId;
|
||||
AssetRequest *request = nullptr;
|
||||
uv_fs_t req;
|
||||
uv_file fd = -1;
|
||||
bool canceled = false;
|
||||
std::string body;
|
||||
uv_buf_t buffer;
|
||||
};
|
||||
|
||||
AssetRequestBaton::AssetRequestBaton(AssetRequest *request_, const std::string &path, uv_loop_t *loop)
|
||||
: threadId(std::this_thread::get_id()), request(request_) {
|
||||
req.data = this;
|
||||
uv_fs_open(loop, &req, path.c_str(), O_RDONLY, S_IRUSR, fileOpened);
|
||||
}
|
||||
|
||||
AssetRequestBaton::~AssetRequestBaton() {
|
||||
}
|
||||
|
||||
void AssetRequestBaton::cancel() {
|
||||
canceled = true;
|
||||
|
||||
// uv_cancel fails frequently when the request has already been started.
|
||||
// In that case, we have to let it complete and check the canceled bool
|
||||
// instead.
|
||||
uv_cancel((uv_req_t *)&req);
|
||||
}
|
||||
|
||||
void AssetRequestBaton::notifyError(uv_fs_t *req) {
|
||||
AssetRequestBaton *ptr = reinterpret_cast<AssetRequestBaton *>(req->data);
|
||||
assert(std::this_thread::get_id() == ptr->threadId);
|
||||
|
||||
if (ptr->request && req->result < 0 && !ptr->canceled && req->result != UV_ECANCELED) {
|
||||
ptr->request->response = util::make_unique<Response>();
|
||||
ptr->request->response->code = req->result == UV_ENOENT ? 404 : 500;
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
ptr->request->response->message = uv_strerror(uv_last_error(req->loop));
|
||||
#else
|
||||
ptr->request->response->message = uv_strerror(int(req->result));
|
||||
#endif
|
||||
ptr->request->notify();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestBaton::fileOpened(uv_fs_t *req) {
|
||||
AssetRequestBaton *ptr = reinterpret_cast<AssetRequestBaton *>(req->data);
|
||||
assert(std::this_thread::get_id() == ptr->threadId);
|
||||
|
||||
if (req->result < 0) {
|
||||
// Opening failed or was canceled. There isn't much left we can do.
|
||||
notifyError(req);
|
||||
cleanup(req);
|
||||
} else {
|
||||
const uv_file fd = uv_file(req->result);
|
||||
|
||||
// We're going to reuse this handle, so we need to cleanup first.
|
||||
uv_fs_req_cleanup(req);
|
||||
|
||||
if (ptr->canceled || !ptr->request) {
|
||||
// Either the AssetRequest object has been destructed, or the
|
||||
// request was canceled.
|
||||
uv_fs_close(req->loop, req, fd, fileClosed);
|
||||
} else {
|
||||
ptr->fd = fd;
|
||||
uv_fs_fstat(req->loop, req, fd, fileStated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestBaton::fileStated(uv_fs_t *req) {
|
||||
AssetRequestBaton *ptr = reinterpret_cast<AssetRequestBaton *>(req->data);
|
||||
assert(std::this_thread::get_id() == ptr->threadId);
|
||||
|
||||
if (req->result != 0 || ptr->canceled || !ptr->request) {
|
||||
// Stating failed or was canceled. We already have an open file handle
|
||||
// though, which we'll have to close.
|
||||
notifyError(req);
|
||||
|
||||
uv_fs_req_cleanup(req);
|
||||
uv_fs_close(req->loop, req, ptr->fd, fileClosed);
|
||||
} else {
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
const uv_statbuf_t *stat = static_cast<const uv_statbuf_t *>(req->ptr);
|
||||
#else
|
||||
const uv_stat_t *stat = static_cast<const uv_stat_t *>(req->ptr);
|
||||
#endif
|
||||
if (stat->st_size > std::numeric_limits<int>::max()) {
|
||||
// File is too large for us to open this way because uv_buf's only support unsigned
|
||||
// ints as maximum size.
|
||||
if (ptr->request) {
|
||||
ptr->request->response = util::make_unique<Response>();
|
||||
ptr->request->response->code = UV_EFBIG;
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
ptr->request->response->message = uv_strerror(uv_err_t {UV_EFBIG, 0});
|
||||
#else
|
||||
ptr->request->response->message = uv_strerror(UV_EFBIG);
|
||||
#endif
|
||||
ptr->request->notify();
|
||||
}
|
||||
|
||||
uv_fs_req_cleanup(req);
|
||||
uv_fs_close(req->loop, req, ptr->fd, fileClosed);
|
||||
} else {
|
||||
const unsigned int size = (unsigned int)(stat->st_size);
|
||||
ptr->body.resize(size);
|
||||
ptr->buffer = uv_buf_init(const_cast<char *>(ptr->body.data()), size);
|
||||
uv_fs_req_cleanup(req);
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
uv_fs_read(req->loop, req, ptr->fd, ptr->buffer.base, ptr->buffer.len, -1, fileRead);
|
||||
#else
|
||||
uv_fs_read(req->loop, req, ptr->fd, &ptr->buffer, 1, 0, fileRead);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestBaton::fileRead(uv_fs_t *req) {
|
||||
AssetRequestBaton *ptr = reinterpret_cast<AssetRequestBaton *>(req->data);
|
||||
assert(std::this_thread::get_id() == ptr->threadId);
|
||||
|
||||
if (req->result < 0 || ptr->canceled || !ptr->request) {
|
||||
// Reading failed or was canceled. We already have an open file handle
|
||||
// though, which we'll have to close.
|
||||
notifyError(req);
|
||||
} else {
|
||||
// File was successfully read.
|
||||
if (ptr->request) {
|
||||
ptr->request->response = util::make_unique<Response>();
|
||||
ptr->request->response->code = 200;
|
||||
ptr->request->response->data = std::move(ptr->body);
|
||||
ptr->request->notify();
|
||||
}
|
||||
}
|
||||
|
||||
uv_fs_req_cleanup(req);
|
||||
uv_fs_close(req->loop, req, ptr->fd, fileClosed);
|
||||
}
|
||||
|
||||
void AssetRequestBaton::fileClosed(uv_fs_t *req) {
|
||||
assert(std::this_thread::get_id() == (reinterpret_cast<AssetRequestBaton *>(req->data))->threadId);
|
||||
|
||||
if (req->result < 0) {
|
||||
// Closing the file failed. But there isn't anything we can do.
|
||||
}
|
||||
|
||||
cleanup(req);
|
||||
}
|
||||
|
||||
void AssetRequestBaton::cleanup(uv_fs_t *req) {
|
||||
AssetRequestBaton *ptr = reinterpret_cast<AssetRequestBaton *>(req->data);
|
||||
assert(std::this_thread::get_id() == ptr->threadId);
|
||||
|
||||
if (ptr->request) {
|
||||
ptr->request->ptr = nullptr;
|
||||
}
|
||||
|
||||
uv_fs_req_cleanup(req);
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
|
||||
AssetRequest::AssetRequest(const std::string &path_, uv_loop_t *loop)
|
||||
: BaseRequest(path_) {
|
||||
if (!path.empty() && path[0] == '/') {
|
||||
// This is an absolute path. We don't allow this. Note that this is not a way to absolutely
|
||||
// prevent access to resources outside the application bundle; e.g. there could be symlinks
|
||||
// in the application bundle that link to outside. We don't care about these.
|
||||
response = util::make_unique<Response>();
|
||||
response->code = 403;
|
||||
response->message = "Path is outside the application bundle";
|
||||
notify();
|
||||
} else {
|
||||
// Note: The AssetRequestBaton object is deleted in AssetRequestBaton::cleanup().
|
||||
ptr = new AssetRequestBaton(this, platform::applicationRoot() + "/" + path, loop);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequest::cancel() {
|
||||
assert(std::this_thread::get_id() == threadId);
|
||||
|
||||
if (ptr) {
|
||||
ptr->cancel();
|
||||
|
||||
// When deleting a AssetRequest object with a uv_fs_* call is in progress, we are making sure
|
||||
// that the callback doesn't accidentally reference this object again.
|
||||
ptr->request = nullptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
notify();
|
||||
}
|
||||
|
||||
AssetRequest::~AssetRequest() {
|
||||
assert(std::this_thread::get_id() == threadId);
|
||||
cancel();
|
||||
|
||||
// Note: The AssetRequestBaton object is deleted in AssetRequestBaton::cleanup().
|
||||
}
|
||||
|
||||
}
|
||||
301
platform/default/asset_request_zip.cpp
Normal file
301
platform/default/asset_request_zip.cpp
Normal file
@@ -0,0 +1,301 @@
|
||||
#include <mbgl/storage/default/asset_request.hpp>
|
||||
#include <mbgl/storage/default/thread_context.hpp>
|
||||
#include <mbgl/android/jni.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
#include "uv_zip.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#ifndef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#include <forward_list>
|
||||
|
||||
namespace algo = boost::algorithm;
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class AssetZipContext : public ThreadContext<AssetZipContext> {
|
||||
public:
|
||||
AssetZipContext(uv_loop_t *loop);
|
||||
~AssetZipContext();
|
||||
|
||||
uv_zip_t *getHandle();
|
||||
void returnHandle(uv_zip_t *zip);
|
||||
|
||||
private:
|
||||
// A list of resuable uv_zip handles to avoid creating and destroying them all the time.
|
||||
std::forward_list<uv_zip_t *> handles;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
template<> pthread_key_t ThreadContext<AssetZipContext>::key{};
|
||||
template<> pthread_once_t ThreadContext<AssetZipContext>::once = PTHREAD_ONCE_INIT;
|
||||
|
||||
AssetZipContext::AssetZipContext(uv_loop_t *loop_) : ThreadContext(loop_) {
|
||||
}
|
||||
|
||||
uv_zip_t *AssetZipContext::getHandle() {
|
||||
if (!handles.empty()) {
|
||||
auto zip = handles.front();
|
||||
handles.pop_front();
|
||||
return zip;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetZipContext::returnHandle(uv_zip_t *zip) {
|
||||
uv_zip_cleanup(zip);
|
||||
handles.push_front(zip);
|
||||
}
|
||||
|
||||
AssetZipContext::~AssetZipContext() {
|
||||
// Close all zip handles
|
||||
for (auto zip : handles) {
|
||||
uv_zip_discard(loop, zip, [](uv_zip_t *zip_) {
|
||||
uv_zip_cleanup(zip_);
|
||||
delete zip_;
|
||||
});
|
||||
}
|
||||
handles.clear();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
class AssetRequestImpl {
|
||||
MBGL_STORE_THREAD(tid)
|
||||
|
||||
public:
|
||||
AssetRequestImpl(AssetRequest *request, uv_loop_t *loop);
|
||||
~AssetRequestImpl();
|
||||
|
||||
void cancel();
|
||||
|
||||
private:
|
||||
AssetZipContext &context;
|
||||
AssetRequest *request = nullptr;
|
||||
const std::string path;
|
||||
std::unique_ptr<Response> response;
|
||||
uv_buf_t buffer;
|
||||
|
||||
private:
|
||||
void openZipArchive();
|
||||
void archiveOpened(uv_zip_t *zip);
|
||||
void fileStated(uv_zip_t *zip);
|
||||
void fileOpened(uv_zip_t *zip);
|
||||
void fileRead(uv_zip_t *zip);
|
||||
void fileClosed(uv_zip_t *zip);
|
||||
void cleanup(uv_zip_t *zip);
|
||||
|
||||
void notifyError(const char *message);
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
AssetRequestImpl::~AssetRequestImpl() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (request) {
|
||||
request->ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop)
|
||||
: context(*AssetZipContext::Get(loop)),
|
||||
request(request_),
|
||||
path(request->resource.url.substr(8)) {
|
||||
auto zip = context.getHandle();
|
||||
if (zip) {
|
||||
archiveOpened(zip);
|
||||
} else {
|
||||
openZipArchive();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::openZipArchive() {
|
||||
uv_fs_t *req = new uv_fs_t();
|
||||
req->data = this;
|
||||
|
||||
// We're using uv_fs_open first to obtain a file descriptor. Then, uv_zip_fdopen will operate
|
||||
// on a read-only file.
|
||||
uv_fs_open(context.loop, req, platform::assetRoot().c_str(), O_RDONLY, S_IRUSR, [](uv_fs_t *fsReq) {
|
||||
if (fsReq->result < 0) {
|
||||
auto impl = reinterpret_cast<AssetRequestImpl *>(fsReq->data);
|
||||
impl->notifyError(uv::getFileRequestError(fsReq));
|
||||
delete impl;
|
||||
} else {
|
||||
uv_zip_t *zip = new uv_zip_t();
|
||||
uv_zip_init(zip);
|
||||
zip->data = fsReq->data;
|
||||
uv_zip_fdopen(fsReq->loop, zip, uv_file(fsReq->result), 0, [](uv_zip_t *openZip) {
|
||||
auto impl = reinterpret_cast<AssetRequestImpl *>(openZip->data);
|
||||
if (openZip->result < 0) {
|
||||
impl->notifyError(openZip->message);
|
||||
delete openZip;
|
||||
delete impl;
|
||||
} else {
|
||||
impl->archiveOpened(openZip);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
uv_fs_req_cleanup(fsReq);
|
||||
delete fsReq;
|
||||
fsReq = nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
#define INVOKE_MEMBER(name) \
|
||||
[](uv_zip_t *zip_) { \
|
||||
assert(zip_->data); \
|
||||
reinterpret_cast<AssetRequestImpl *>(zip_->data)->name(zip_); \
|
||||
}
|
||||
|
||||
void AssetRequestImpl::archiveOpened(uv_zip_t *zip) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
zip->data = this;
|
||||
uv_zip_stat(context.loop, zip, path.c_str(), 0, INVOKE_MEMBER(fileStated));
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileStated(uv_zip_t *zip) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (!request || zip->result < 0) {
|
||||
// Stat failed, probably because the file doesn't exist.
|
||||
if (zip->result < 0) {
|
||||
notifyError(zip->message);
|
||||
}
|
||||
cleanup(zip);
|
||||
} else if (!(zip->stat->valid & ZIP_STAT_SIZE)) {
|
||||
// We couldn't obtain the size of the file.
|
||||
notifyError("Could not determine file size in zip file");
|
||||
cleanup(zip);
|
||||
} else {
|
||||
response = util::make_unique<Response>();
|
||||
|
||||
// Allocate the space for reading the data.
|
||||
response->data.resize(zip->stat->size);
|
||||
buffer = uv_buf_init(const_cast<char *>(response->data.data()), zip->stat->size);
|
||||
|
||||
// Get the modification time in case we have one.
|
||||
if (zip->stat->valid & ZIP_STAT_MTIME) {
|
||||
response->modified = zip->stat->mtime;
|
||||
}
|
||||
|
||||
uv_zip_fopen(context.loop, zip, path.c_str(), 0, INVOKE_MEMBER(fileOpened));
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileOpened(uv_zip_t *zip) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (zip->result < 0) {
|
||||
// Opening failed.
|
||||
notifyError(zip->message);
|
||||
cleanup(zip);
|
||||
} else if (!request) {
|
||||
// The request was canceled. Close the file again.
|
||||
uv_zip_fclose(context.loop, zip, zip->file, INVOKE_MEMBER(fileClosed));
|
||||
} else {
|
||||
uv_zip_fread(context.loop, zip, zip->file, &buffer, INVOKE_MEMBER(fileRead));
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileRead(uv_zip_t *zip) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (zip->result < 0) {
|
||||
// Reading failed. We still have an open file handle though.
|
||||
notifyError(zip->message);
|
||||
} else if (request) {
|
||||
response->status = Response::Successful;
|
||||
request->notify(std::move(response), FileCache::Hint::No);
|
||||
delete request;
|
||||
assert(request == nullptr);
|
||||
}
|
||||
|
||||
uv_zip_fclose(context.loop, zip, zip->file, INVOKE_MEMBER(fileClosed));
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileClosed(uv_zip_t *zip) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (zip->result < 0) {
|
||||
// Closing the file failed. But there isn't anything we can do.
|
||||
}
|
||||
|
||||
cleanup(zip);
|
||||
}
|
||||
|
||||
void AssetRequestImpl::cleanup(uv_zip_t *zip) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
context.returnHandle(zip);
|
||||
delete this;
|
||||
}
|
||||
|
||||
void AssetRequestImpl::notifyError(const char *message) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (request) {
|
||||
response = util::make_unique<Response>();
|
||||
response->status = Response::Error;
|
||||
response->message = message;
|
||||
request->notify(std::move(response), FileCache::Hint::No);
|
||||
delete request;
|
||||
assert(request == nullptr);
|
||||
} else {
|
||||
// The request was already canceled and deleted.
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::cancel() {
|
||||
request = nullptr;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
AssetRequest::AssetRequest(DefaultFileSource *source_, const Resource &resource_)
|
||||
: SharedRequestBase(source_, resource_) {
|
||||
assert(algo::starts_with(resource.url, "asset://"));
|
||||
}
|
||||
|
||||
AssetRequest::~AssetRequest() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (ptr) {
|
||||
reinterpret_cast<AssetRequestImpl *>(ptr)->cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequest::start(uv_loop_t *loop, std::unique_ptr<Response> response) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
// We're ignoring the existing response if any.
|
||||
(void(response));
|
||||
|
||||
assert(!ptr);
|
||||
ptr = new AssetRequestImpl(this, loop);
|
||||
// Note: the AssetRequestImpl deletes itself.
|
||||
}
|
||||
|
||||
void AssetRequest::cancel() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (ptr) {
|
||||
reinterpret_cast<AssetRequestImpl *>(ptr)->cancel();
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
}
|
||||
28
platform/default/asset_root.cpp
Normal file
28
platform/default/asset_root.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
#include <uv.h>
|
||||
#include <libgen.h>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the path to the root folder of the application.
|
||||
const std::string &assetRoot() {
|
||||
static const std::string root = []() -> std::string {
|
||||
size_t max = 0;
|
||||
std::string dir;
|
||||
do {
|
||||
// Gradually increase the length of the string in case the path was truncated.
|
||||
max += 256;
|
||||
dir.resize(max);
|
||||
uv_exepath(const_cast<char *>(dir.data()), &max);
|
||||
} while (max == dir.size());
|
||||
dir.resize(max - 1);
|
||||
dir = dirname(const_cast<char *>(dir.c_str()));
|
||||
return dir;
|
||||
}();
|
||||
return root;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the path to the default cache database on this system.
|
||||
std::string defaultCacheDatabase() {
|
||||
return "/tmp/mbgl-cache.db";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,25 @@
|
||||
#include <mbgl/util/compression.hpp>
|
||||
#include "compression.hpp"
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
// Check zlib library version.
|
||||
const static bool zlibVersionCheck = []() {
|
||||
const char *const version = zlibVersion();
|
||||
if (version[0] != ZLIB_VERSION[0]) {
|
||||
char message[96];
|
||||
snprintf(message, 96, "zlib version mismatch: headers report %s, but library reports %s",
|
||||
ZLIB_VERSION, version);
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
return true;
|
||||
}();
|
||||
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
@@ -174,7 +174,7 @@ void GLFWView::key(GLFWwindow *window, int key, int /*scancode*/, int action, in
|
||||
break;
|
||||
case GLFW_KEY_R:
|
||||
if (!mods) {
|
||||
view->map->setDefaultTransitionDuration(300);
|
||||
view->map->setDefaultTransitionDuration(std::chrono::milliseconds(300));
|
||||
if (view->map->hasClass("night")) {
|
||||
view->map->removeClass("night");
|
||||
} else {
|
||||
@@ -239,9 +239,9 @@ void GLFWView::mouseClick(GLFWwindow *window, int button, int action, int modifi
|
||||
double now = glfwGetTime();
|
||||
if (now - view->lastClick < 0.4 /* ms */) {
|
||||
if (modifiers & GLFW_MOD_SHIFT) {
|
||||
view->map->scaleBy(0.5, view->lastX, view->lastY, 0.5);
|
||||
view->map->scaleBy(0.5, view->lastX, view->lastY, std::chrono::milliseconds(500));
|
||||
} else {
|
||||
view->map->scaleBy(2.0, view->lastX, view->lastY, 0.5);
|
||||
view->map->scaleBy(2.0, view->lastX, view->lastY, std::chrono::milliseconds(500));
|
||||
}
|
||||
}
|
||||
view->lastClick = now;
|
||||
@@ -301,7 +301,7 @@ void GLFWView::swap() {
|
||||
fps();
|
||||
}
|
||||
|
||||
void GLFWView::notifyMapChange(mbgl::MapChange /*change*/, mbgl::timestamp /*delay*/) {
|
||||
void GLFWView::notifyMapChange(mbgl::MapChange /*change*/, std::chrono::steady_clock::duration /*delay*/) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@@ -244,7 +244,7 @@ void HeadlessView::notify() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
void HeadlessView::notifyMapChange(mbgl::MapChange /*change*/, mbgl::timestamp /*delay*/) {
|
||||
void HeadlessView::notifyMapChange(mbgl::MapChange /*change*/, std::chrono::steady_clock::duration /*delay*/) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user