Updating from master
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,6 +16,7 @@
|
||||
/test/build
|
||||
/test/node_modules
|
||||
/test/fixtures/*/*_actual.*
|
||||
/test/fixtures/database/*.db
|
||||
/include/mbgl/shader/shaders.hpp
|
||||
/src/shader/shaders_gl.cpp
|
||||
/src/shader/shaders_gles2.cpp
|
||||
|
||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -12,7 +12,7 @@
|
||||
|
||||
[submodule "test/ios/KIF"]
|
||||
path = test/ios/KIF
|
||||
url = https://github.com/mapbox/KIF.git
|
||||
url = https://github.com/kif-framework/KIF.git
|
||||
|
||||
[submodule "platform/ios/vendor/SMCalloutView"]
|
||||
path = platform/ios/vendor/SMCalloutView
|
||||
|
||||
2
.mason
2
.mason
Submodule .mason updated: 03869fd11e...c43967404c
146
.travis.yml
146
.travis.yml
@@ -1,95 +1,99 @@
|
||||
language: cpp
|
||||
language: android
|
||||
|
||||
sudo: false
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- os: linux
|
||||
include:
|
||||
- os: linux
|
||||
env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=arm-v7 TESTMUNK=yes
|
||||
compiler: clang
|
||||
env: FLAVOR=linux CXX=g++-4.8 BUILDTYPE=Release
|
||||
addons:
|
||||
apt:
|
||||
sources: [ 'ubuntu-toolchain-r-test' ]
|
||||
packages: [ 'gdb', 'g++-4.8', 'gcc-4.8', 'libllvm3.4', 'xutils-dev', 'libxxf86vm-dev', 'x11proto-xf86vidmode-dev', 'mesa-utils' ]
|
||||
- os: linux
|
||||
env: CONFIG=debug MASON_PLATFORM=android MASON_ANDROID_ABI=arm-v7 TESTMUNK=no
|
||||
compiler: clang
|
||||
env: FLAVOR=linux CXX=clang++ BUILDTYPE=Debug
|
||||
addons:
|
||||
apt:
|
||||
sources: [ 'ubuntu-toolchain-r-test' ]
|
||||
packages: [ 'gdb', 'libgcc-4.8-dev', 'libstdc++-4.8-dev', 'libstdc++6', 'libllvm3.4', 'xutils-dev', 'libxxf86vm-dev', 'x11proto-xf86vidmode-dev', 'mesa-utils' ]
|
||||
- os: linux
|
||||
env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=arm-v5 TESTMUNK=no
|
||||
compiler: clang
|
||||
- os: linux
|
||||
env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=arm-v8 TESTMUNK=no
|
||||
compiler: clang
|
||||
- os: linux
|
||||
env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=x86 TESTMUNK=no
|
||||
compiler: clang
|
||||
- os: linux
|
||||
env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=mips TESTMUNK=no
|
||||
compiler: clang
|
||||
- os: linux
|
||||
env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=mips-64 TESTMUNK=no
|
||||
compiler: clang
|
||||
- os: linux
|
||||
env: BUILDTYPE=Release JOBS=16
|
||||
compiler: clang
|
||||
- os: linux
|
||||
env: BUILDTYPE=Debug JOBS=16
|
||||
compiler: clang
|
||||
- os: linux
|
||||
env: BUILDTYPE=Release JOBS=8
|
||||
compiler: gcc
|
||||
env: FLAVOR=linux CXX=clang++ BUILDTYPE=Release
|
||||
addons:
|
||||
apt:
|
||||
sources: [ 'ubuntu-toolchain-r-test' ]
|
||||
packages: [ 'gdb', 'libgcc-4.8-dev', 'libstdc++-4.8-dev', 'libstdc++6', 'libllvm3.4', 'xutils-dev', 'libxxf86vm-dev', 'x11proto-xf86vidmode-dev', 'mesa-utils' ]
|
||||
- os: osx
|
||||
env: BUILDTYPE=Debug JOBS=8 MASON_PLATFORM=osx
|
||||
compiler: clang
|
||||
env: FLAVOR=osx BUILDTYPE=Debug
|
||||
- os: osx
|
||||
env: BUILDTYPE=Release JOBS=8 MASON_PLATFORM=ios
|
||||
compiler: clang
|
||||
env: FLAVOR=ios BUILDTYPE=Release
|
||||
- os: linux
|
||||
env: FLAVOR=android ANDROID_ABI=arm-v7 BUILDTYPE=Release
|
||||
android:
|
||||
components: [ 'build-tools-22.0.0', 'android-22', 'extra' ]
|
||||
addons:
|
||||
apt:
|
||||
packages: [ 'lib32stdc++6' ]
|
||||
- os: linux
|
||||
env: FLAVOR=android ANDROID_ABI=arm-v7 BUILDTYPE=Debug
|
||||
android:
|
||||
components: [ 'build-tools-22.0.0', 'android-22', 'extra' ]
|
||||
addons:
|
||||
apt:
|
||||
packages: [ 'lib32stdc++6' ]
|
||||
- os: linux
|
||||
env: FLAVOR=android ANDROID_ABI=arm-v8 BUILDTYPE=Release
|
||||
android:
|
||||
components: [ 'build-tools-22.0.0', 'android-22', 'extra' ]
|
||||
addons:
|
||||
apt:
|
||||
packages: [ 'lib32stdc++6' ]
|
||||
- os: linux
|
||||
env: FLAVOR=android ANDROID_ABI=x86 BUILDTYPE=Release
|
||||
android:
|
||||
components: [ 'build-tools-22.0.0', 'android-22', 'extra' ]
|
||||
addons:
|
||||
apt:
|
||||
packages: [ 'lib32stdc++6' ]
|
||||
- os: linux
|
||||
env: FLAVOR=android ANDROID_ABI=mips BUILDTYPE=Release
|
||||
android:
|
||||
components: [ 'build-tools-22.0.0', 'android-22', 'extra' ]
|
||||
addons:
|
||||
apt:
|
||||
packages: [ 'lib32stdc++6' ]
|
||||
|
||||
env:
|
||||
global:
|
||||
- secure: "MZHblLZXG/jWf2w0ZFlxCLDwx2qtGgRDODQyg1BR7JIuMz6AtWv8XR/sUczWLbiABCL0a/NzJF1g4v2pI7X69IntcjOdIABBgTh7++6+1TJ0Kp8viEltb55nQG3lHy/R6fOaI7Pj9tuCX0PCRtGA5C/fGnodLGEjy3RVOJ09ln0="
|
||||
- secure: "KaSQbhgjtV7ZCkesHmvrNsbQVjk5SPfGKB1VkWenRGYhLF45HpSRNwSxMQddZ566Pg7qIFgF1iWl/B0QW3B6AWL5WmzQ5AOJgwS876pNIc/UT7ubMPtgAtjpvw1bQvQP3B8MrB+3OE5c6tD+a3LhR9krV//dOsfErR5Yy+3Mbkc="
|
||||
- ANDROID_BUILD_INSTANCE_PROFILE: arn:aws:iam::234858372212:instance-profile/android-gl-build/travis/instance-profile/travis-mapbox-gl-native-AndroidInstanceProfile-13EA815DD8IQ9
|
||||
- secure: "RiBIBfVhhaMjU5ksuwJO3shdvG9FpinBjdSv4co9jg9171SR8edNriedHjVKSIeBhSGNmZmX+twS3dJS/By6tl/LKh9sTynA+ZAYYljkE7jn881B/gMrlYvdAA6og5KvkhV1/0iJWlhuZrMTkhpDR200iLgg3EWBhWjltzmDW/I="
|
||||
- secure: "CHBiUM60TolDbQnn+4IRA/tvOKwKs3g9EDvv8YHSJMg3FuHmjKQkprBasvxf3hnTXg4WLZEubmeDcyJ6RRzPP5mMSr/hksYl0pSjj/6TUecE5fHPVVeN7txVqkpOBf9i45Y+iBUQMjBb1NnDK3pHXxpnAs1Q/pe7vReErj4GF1U="
|
||||
- LD_LIBRARY_PATH: '/usr/local/lib'
|
||||
- TERM: dumb
|
||||
# begin iOS code signing
|
||||
- secure: "I6Iu75X1E+js5tzijtKi1EGtIuBcA4/25nDYe0svV4HAtujY71ZJZ4eB6355CKhFXpLXrF3i7eKVX3v+zWS0QROPEWacgsqsvNg+Ba9cnznW/faUSOYekCfhzWd/6reYDM7KzKAQwSUHLk9JIWK/kkmi4r+vVJK7h+tjPllK5YA="
|
||||
- IOS_APP_NAME="Mapbox GL"
|
||||
- 'IOS_DEVELOPER_NAME="iPhone Distribution: Mapbox, Inc."'
|
||||
- IOS_PROFILE_NAME="ios-in-house"
|
||||
- secure: "nQqSM8rd7OHtV4MqmNqVnkrVHqxKqQsaWRYk4/nPdhbeVWtTtkk0df711LrF1TUtbEPEewHxYUvTZ/UXmwJNeoKdzTHavI8hnatRkgjyxGERPn1il1Otelht9I+LQQHf+plrpRjVWBrNIW0Zox1B3cqn6d3NglpbXrEQ2EjYGNA="
|
||||
# end iOS code signing
|
||||
|
||||
before_install:
|
||||
- if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then sudo service mysql stop; fi
|
||||
- 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
|
||||
- TERM: dumb
|
||||
# AWS
|
||||
- secure: "MZHblLZXG/jWf2w0ZFlxCLDwx2qtGgRDODQyg1BR7JIuMz6AtWv8XR/sUczWLbiABCL0a/NzJF1g4v2pI7X69IntcjOdIABBgTh7++6+1TJ0Kp8viEltb55nQG3lHy/R6fOaI7Pj9tuCX0PCRtGA5C/fGnodLGEjy3RVOJ09ln0="
|
||||
- secure: "KaSQbhgjtV7ZCkesHmvrNsbQVjk5SPfGKB1VkWenRGYhLF45HpSRNwSxMQddZ566Pg7qIFgF1iWl/B0QW3B6AWL5WmzQ5AOJgwS876pNIc/UT7ubMPtgAtjpvw1bQvQP3B8MrB+3OE5c6tD+a3LhR9krV//dOsfErR5Yy+3Mbkc="
|
||||
# Access Token
|
||||
- secure: "RiBIBfVhhaMjU5ksuwJO3shdvG9FpinBjdSv4co9jg9171SR8edNriedHjVKSIeBhSGNmZmX+twS3dJS/By6tl/LKh9sTynA+ZAYYljkE7jn881B/gMrlYvdAA6og5KvkhV1/0iJWlhuZrMTkhpDR200iLgg3EWBhWjltzmDW/I="
|
||||
# Testmunk
|
||||
- secure: "CHBiUM60TolDbQnn+4IRA/tvOKwKs3g9EDvv8YHSJMg3FuHmjKQkprBasvxf3hnTXg4WLZEubmeDcyJ6RRzPP5mMSr/hksYl0pSjj/6TUecE5fHPVVeN7txVqkpOBf9i45Y+iBUQMjBb1NnDK3pHXxpnAs1Q/pe7vReErj4GF1U="
|
||||
# iOS code signing
|
||||
- secure: "I6Iu75X1E+js5tzijtKi1EGtIuBcA4/25nDYe0svV4HAtujY71ZJZ4eB6355CKhFXpLXrF3i7eKVX3v+zWS0QROPEWacgsqsvNg+Ba9cnznW/faUSOYekCfhzWd/6reYDM7KzKAQwSUHLk9JIWK/kkmi4r+vVJK7h+tjPllK5YA="
|
||||
- IOS_APP_NAME="Mapbox GL"
|
||||
- 'IOS_DEVELOPER_NAME="iPhone Distribution: Mapbox, Inc."'
|
||||
- IOS_PROFILE_NAME="ios-in-house"
|
||||
- secure: "nQqSM8rd7OHtV4MqmNqVnkrVHqxKqQsaWRYk4/nPdhbeVWtTtkk0df711LrF1TUtbEPEewHxYUvTZ/UXmwJNeoKdzTHavI8hnatRkgjyxGERPn1il1Otelht9I+LQQHf+plrpRjVWBrNIW0Zox1B3cqn6d3NglpbXrEQ2EjYGNA="
|
||||
- KIF_SCREENSHOTS="${TRAVIS_BUILD_DIR}/screenshots"
|
||||
|
||||
install:
|
||||
- ulimit -c
|
||||
|
||||
before_script:
|
||||
# Set the core file limit to unlimited so a core file is generated upon crash
|
||||
- ulimit -c unlimited -S
|
||||
# begin iOS code signing
|
||||
- openssl aes-256-cbc -k "$IOS_ENCRYPTION_SECRET" -in scripts/ios_travis/ios-in-house.mobileprovision.enc -d -a -out scripts/ios_travis/ios-in-house.mobileprovision
|
||||
- openssl aes-256-cbc -k "$IOS_ENCRYPTION_SECRET" -in scripts/ios_travis/ios-dist.cer.enc -d -a -out scripts/ios_travis/ios-dist.cer
|
||||
- openssl aes-256-cbc -k "$IOS_ENCRYPTION_SECRET" -in scripts/ios_travis/ios-dist.p12.enc -d -a -out scripts/ios_travis/ios-dist.p12
|
||||
- ./scripts/ios_travis/add-key.sh
|
||||
# end iOS code signing
|
||||
- ./scripts/${FLAVOR}/install.sh
|
||||
|
||||
script:
|
||||
- ./scripts/travis_script.sh
|
||||
- ./scripts/${FLAVOR}/run.sh
|
||||
|
||||
after_script:
|
||||
- ./scripts/ios_travis/remove-key.sh
|
||||
after_failure:
|
||||
- "[ -f scripts/${FLAVOR}/run.sh ] && scripts/${FLAVOR}/run.sh"
|
||||
|
||||
notifications:
|
||||
slack:
|
||||
secure: HHQYr7sF8M1SzoWSqgKVYtwAgGdLLCyTMsQjFhEEQNYO92ZwURE5s03qWTGH5k8+4Yqn26yrXt3NztLC4JIOpcGervN2mSZyq4dZgFTcWEd61igw0qwSenlwvFfbE1ASK/KYCzfyn9MIfHN+ovwLoRxXZkPwinKDvl3DXjBaFNg=
|
||||
|
||||
git:
|
||||
submodules: false
|
||||
|
||||
149
Makefile
149
Makefile
@@ -4,11 +4,16 @@ PREFIX ?= /usr/local
|
||||
ANDROID_ABI ?= arm-v7
|
||||
|
||||
ifeq ($(shell uname -s), Darwin)
|
||||
HOST ?= osx
|
||||
HEADLESS ?= cgl
|
||||
HOST = osx
|
||||
HEADLESS = cgl
|
||||
JOBS ?= $(shell sysctl -n hw.ncpu)
|
||||
endif
|
||||
HOST ?= linux
|
||||
|
||||
ifeq ($(shell uname -s), Linux)
|
||||
HOST = linux
|
||||
JOBS ?= $(shell grep --count processor /proc/cpuinfo)
|
||||
endif
|
||||
|
||||
JOBS ?= 1
|
||||
|
||||
all: mbgl
|
||||
@@ -26,52 +31,53 @@ config/%.gypi: configure
|
||||
styles/styles:
|
||||
git submodule update --init styles
|
||||
|
||||
ifeq ($(shell uname -s), Darwin)
|
||||
SMCalloutView:
|
||||
git submodule update --init platform/ios/vendor/SMCalloutView
|
||||
else
|
||||
SMCalloutView:
|
||||
endif
|
||||
|
||||
KIF:
|
||||
git submodule update --init test/ios/KIF
|
||||
|
||||
|
||||
#### Build files ###############################################################
|
||||
|
||||
.PRECIOUS: Makefile/project
|
||||
Makefile/project: config/$(HOST).gypi styles/styles SMCalloutView
|
||||
deps/run_gyp gyp/$(HOST).gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make
|
||||
|
||||
.PRECIOUS: Xcode/project
|
||||
Xcode/project: config/$(HOST).gypi styles/styles SMCalloutView
|
||||
deps/run_gyp gyp/$(HOST).gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f xcode
|
||||
|
||||
|
||||
#### Library builds ############################################################
|
||||
|
||||
.PRECIOUS: Makefile/mbgl
|
||||
Makefile/mbgl: config/$(HOST).gypi styles/styles SMCalloutView
|
||||
deps/run_gyp mbgl.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make
|
||||
|
||||
mbgl: Makefile/mbgl
|
||||
mbgl: Makefile/project
|
||||
$(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) everything
|
||||
|
||||
standalone: Makefile/mbgl
|
||||
standalone: Makefile/project
|
||||
LINK=`pwd`/gyp/link.py $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) standalone
|
||||
|
||||
install: Makefile/mbgl
|
||||
install: Makefile/project
|
||||
LINK=`pwd`/gyp/link.py $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) install
|
||||
|
||||
.PRECIOUS: Xcode/mbgl
|
||||
Xcode/mbgl: config/$(HOST).gypi styles/styles SMCalloutView
|
||||
deps/run_gyp mbgl.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f xcode
|
||||
|
||||
##### Test builds ##############################################################
|
||||
|
||||
.PRECIOUS: Makefile/test
|
||||
Makefile/test: test/test.gyp config/$(HOST).gypi styles/styles SMCalloutView
|
||||
deps/run_gyp test/test.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make
|
||||
|
||||
.PHONY: test
|
||||
test: Makefile/test
|
||||
test: Makefile/project
|
||||
$(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 styles/styles SMCalloutView
|
||||
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 $(JOBS)
|
||||
.PHONY: xtest
|
||||
xtest: XCPRETTY := $(shell ./scripts/xcpretty.sh)
|
||||
xtest: Xcode/project
|
||||
xcodebuild -project ./build/osx/gyp/osx.xcodeproj -configuration $(BUILDTYPE) -target test -jobs $(JOBS) $(XCPRETTY)
|
||||
|
||||
xtest-%: xtest
|
||||
./scripts/run_tests.sh "build/osx/Build/Products/$(BUILDTYPE)/test" --gtest_filter=$*
|
||||
@@ -79,31 +85,23 @@ xtest-%: xtest
|
||||
|
||||
#### Mac OS X application builds ###############################################
|
||||
|
||||
.PRECIOUS: Makefile/osx
|
||||
Makefile/osx: macosx/mapboxgl-app.gyp config/osx.gypi styles/styles
|
||||
deps/run_gyp macosx/mapboxgl-app.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f make
|
||||
|
||||
.PHONY: osx run-osx
|
||||
osx: Makefile/osx
|
||||
osx: Makefile/project
|
||||
$(MAKE) -C build/osx BUILDTYPE=$(BUILDTYPE) osxapp
|
||||
|
||||
run-osx: osx
|
||||
"build/osx/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL"
|
||||
|
||||
|
||||
.PRECIOUS: Xcode/osx
|
||||
Xcode/osx: macosx/mapboxgl-app.gyp config/osx.gypi styles/styles
|
||||
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-proj: Xcode/project
|
||||
open ./build/osx/gyp/osx.xcodeproj
|
||||
|
||||
xosx: Xcode/osx
|
||||
xcodebuild -project ./build/osx/macosx/mapboxgl-app.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs $(JOBS)
|
||||
xosx: XCPRETTY := $(shell ./scripts/xcpretty.sh)
|
||||
xosx: Xcode/project
|
||||
xcodebuild -project ./build/osx/gyp/osx.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs $(JOBS) $(XCPRETTY)
|
||||
|
||||
run-xosx: xosx
|
||||
"build/osx/Build/Products/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL"
|
||||
"gyp/build/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL"
|
||||
|
||||
# Legacy name
|
||||
xproj: xosx-proj
|
||||
@@ -113,21 +111,29 @@ xproj: xosx-proj
|
||||
#### iOS application builds ####################################################
|
||||
|
||||
.PRECIOUS: Xcode/ios
|
||||
Xcode/ios: ios/app/mapboxgl-app.gyp config/ios.gypi styles/styles SMCalloutView
|
||||
deps/run_gyp ios/app/mapboxgl-app.gyp $(CONFIG_ios) $(LIBS_ios) --generator-output=./build/ios -f xcode
|
||||
Xcode/ios: gyp/ios.gyp config/ios.gypi styles/styles SMCalloutView
|
||||
deps/run_gyp gyp/ios.gyp $(CONFIG_ios) $(LIBS_ios) --generator-output=./build/ios -f xcode
|
||||
|
||||
.PHONY: ios-proj ios isim ipackage
|
||||
ios-proj: Xcode/ios
|
||||
open ./build/ios/ios/app/mapboxgl-app.xcodeproj
|
||||
open ./build/ios/gyp/ios.xcodeproj
|
||||
|
||||
ios: XCPRETTY := $(shell ./scripts/xcpretty.sh)
|
||||
ios: Xcode/ios
|
||||
xcodebuild -sdk iphoneos ARCHS="arm64 armv7 armv7s" PROVISIONING_PROFILE="2b532944-bf3d-4bf4-aa6c-a81676984ae8" -project ./build/ios/ios/app/mapboxgl-app.xcodeproj -configuration Release -target iosapp -jobs $(JOBS)
|
||||
xcodebuild -sdk iphoneos ARCHS="arm64 armv7 armv7s" PROVISIONING_PROFILE="2b532944-bf3d-4bf4-aa6c-a81676984ae8" -project ./build/ios/gyp/ios.xcodeproj -configuration Release -target iosapp -jobs $(JOBS) $(XCPRETTY)
|
||||
|
||||
isim: XCPRETTY := $(shell ./scripts/xcpretty.sh)
|
||||
isim: Xcode/ios
|
||||
xcodebuild -sdk iphonesimulator ARCHS="x86_64 i386" -project ./build/ios/ios/app/mapboxgl-app.xcodeproj -configuration Debug -target iosapp -jobs $(JOBS)
|
||||
xcodebuild -sdk iphonesimulator ARCHS="x86_64 i386" -project ./build/ios/gyp/ios.xcodeproj -configuration Debug -target iosapp -jobs $(JOBS) $(XCPRETTY)
|
||||
|
||||
ipackage: clean Xcode/ios
|
||||
./scripts/package_ios.sh
|
||||
./scripts/ios/package.sh
|
||||
|
||||
ipackage-sim: clean Xcode/ios
|
||||
./scripts/ios/package.sh sim
|
||||
|
||||
itest: ipackage-sim KIF
|
||||
./scripts/ios/test.sh
|
||||
|
||||
# Legacy name
|
||||
iproj: ios-proj
|
||||
@@ -135,34 +141,20 @@ iproj: ios-proj
|
||||
|
||||
#### Linux application builds ##################################################
|
||||
|
||||
.PRECIOUS: Makefile/linux
|
||||
Makefile/linux: linux/mapboxgl-app.gyp config/$(HOST).gypi styles/styles
|
||||
deps/run_gyp linux/mapboxgl-app.gyp $(CONFIG_$(HOST)) $(LIBS_linux) --generator-output=./build/$(HOST) -f make
|
||||
|
||||
.PHONY: linux run-linux
|
||||
linux: Makefile/linux
|
||||
linux: Makefile/project
|
||||
$(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 styles/styles
|
||||
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
|
||||
.PHONY: xlinux run-xlinux
|
||||
xlinux: XCPRETTY := $(shell ./scripts/xcpretty.sh)
|
||||
xlinux: Xcode/project
|
||||
xcodebuild -project ./build/osx/gyp/osx.xcodeproj -configuration $(BUILDTYPE) -target linuxapp -jobs $(JOBS) $(XCPRETTY)
|
||||
|
||||
run-xlinux: xlinux
|
||||
"build/osx/Build/Products/$(BUILDTYPE)/mapbox-gl"
|
||||
|
||||
# Legacy name
|
||||
lproj: xlinux-proj
|
||||
"gyp/build/$(BUILDTYPE)/mapbox-gl"
|
||||
|
||||
|
||||
#### Android libaries #########################################################
|
||||
@@ -194,22 +186,15 @@ android-deploy: $(ANDROID_ABIS)
|
||||
|
||||
android-project: android-lib
|
||||
|
||||
|
||||
##### Render builds ############################################################
|
||||
|
||||
.PRECIOUS: Makefile/render
|
||||
Makefile/render: bin/render.gyp config/$(HOST).gypi
|
||||
deps/run_gyp bin/render.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make
|
||||
|
||||
render: Makefile/render
|
||||
render: Makefile/project
|
||||
$(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) mbgl-render
|
||||
|
||||
.PRECIOUS: Xcode/render
|
||||
Xcode/render: bin/render.gyp config/osx.gypi styles/styles
|
||||
deps/run_gyp bin/render.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f xcode
|
||||
|
||||
.PHONY: xrender-proj
|
||||
xrender-proj: Xcode/render
|
||||
open ./build/osx/bin/render.xcodeproj
|
||||
.PHONY: xrender run-xrender
|
||||
xrender: Xcode/project
|
||||
xcodebuild -project ./build/osx/gyp/osx.xcodeproj -configuration $(BUILDTYPE) -target mbgl-render -jobs $(JOBS)
|
||||
|
||||
|
||||
##### Maintenace operations ####################################################
|
||||
|
||||
13
README.md
13
README.md
@@ -49,7 +49,7 @@ Target OS X: 10.9+
|
||||
If you merely want to install the library for iOS and try it out as an Objective-C consumer:
|
||||
|
||||
0. Use [Homebrew](http://brew.sh/) to install Boost headers: `brew install boost`.
|
||||
1. Run `./scripts/package_ios.sh`. The packaging script will produce the statically-linked `libMapboxGL.a`, `MapboxGL.bundle` for resources, and a `Headers` folder.
|
||||
1. Run `make ipackage`. The packaging script will produce the statically-linked `libMapboxGL.a`, `MapboxGL.bundle` for resources, and a `Headers` folder.
|
||||
2. Copy the contents of `build/ios/pkg/static` into your project. It should happen automatically, but ensure that:
|
||||
- `Headers` is in your *Header Search Paths* (`HEADER_SEARCH_PATHS`) build setting.
|
||||
- `MapboxGL.bundle` is in your target's *Copy Bundle Resources* build phase.
|
||||
@@ -68,11 +68,13 @@ If you merely want to install the library for iOS and try it out as an Objective
|
||||
5. [Set the Mapbox API access token](#mapbox-api-access-tokens).
|
||||
6. `#import "MapboxGL.h"`
|
||||
|
||||
If you want to build from source and/or contribute to development of the project, run `make iproj`, which will create and open an Xcode project which can build the entire library from source as well as an Objective-C test app.
|
||||
If you want to build from source and/or contribute to development of the project, run `make iproj`, which will create and open an Xcode project which can build the entire library from source as well as an Objective-C test app. If you don't have an Apple Developer account, change the destination from "My Mac" to a simulator such as "iPhone 6" before you run and build the app.
|
||||
|
||||
You can run `make itest` to run the included integration tests. Requires `gem install xcpretty`. If you want to run the tests in Xcode instead, first `make ipackage` to create a local static library version, then open `test/ios/ios-tests.xcodeproj`, and lastly `Command + U` on the `Mapbox GL Tests` application target.
|
||||
|
||||
Target devices: iPhone 4S and above (5, 5c, 5s, 6, 6 Plus) and iPad 2 and above (3, 4, Mini, Air, Mini 2, Air 2).
|
||||
|
||||
Target iOS: 7.0 through 8.1
|
||||
Target iOS: 7.0 through latest 8.x.
|
||||
|
||||
|
||||
## Linux
|
||||
@@ -84,6 +86,7 @@ Install GCC 4.8+ if you are running Ubuntu 13.10 or older. Alternatively, you ca
|
||||
sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test
|
||||
sudo apt-get update
|
||||
sudo apt-get install gcc-4.8 g++-4.8
|
||||
export CXX=g++-4.8
|
||||
|
||||
Ensure you have git and other build essentials:
|
||||
|
||||
@@ -108,10 +111,6 @@ Otherwise, you can just install
|
||||
|
||||
sudo apt-get install libboost-dev libboost-program-options-dev
|
||||
|
||||
Once you're done installing the build dependencies, you can get started by running
|
||||
|
||||
./configure
|
||||
|
||||
Then, you can then proceed to build the library:
|
||||
|
||||
git submodule update --init
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <cstdint>
|
||||
#include <cinttypes>
|
||||
#include <cassert>
|
||||
|
||||
#include <string>
|
||||
#include <locale>
|
||||
@@ -255,20 +256,6 @@ void JNICALL nativeDestroySurface(JNIEnv *env, jobject obj, jlong nativeMapViewP
|
||||
nativeMapView->destroySurface();
|
||||
}
|
||||
|
||||
void JNICALL nativeStart(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeStart");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->start();
|
||||
}
|
||||
|
||||
void JNICALL nativeStop(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeStop");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->stop();
|
||||
}
|
||||
|
||||
void JNICALL nativePause(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativePause");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
@@ -287,14 +274,7 @@ void JNICALL nativeUpdate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeUpdate");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->getMap().triggerUpdate();
|
||||
}
|
||||
|
||||
void JNICALL nativeTerminate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
|
||||
mbgl::Log::Debug(mbgl::Event::JNI, "nativeTerminate");
|
||||
assert(nativeMapViewPtr != 0);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->getMap().terminate();
|
||||
nativeMapView->getMap().update();
|
||||
}
|
||||
|
||||
void JNICALL nativeResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint width, jint height,
|
||||
@@ -310,7 +290,7 @@ void JNICALL nativeResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint
|
||||
assert(fbWidth <= UINT16_MAX);
|
||||
assert(fbHeight <= UINT16_MAX);
|
||||
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
|
||||
nativeMapView->resize(width, height, ratio, fbWidth, fbHeight);
|
||||
nativeMapView->getMap().resize(width, height, ratio);
|
||||
}
|
||||
|
||||
void JNICALL nativeRemoveClass(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring clazz) {
|
||||
@@ -938,12 +918,9 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||
{"nativeCreateSurface", "(JLandroid/view/Surface;)V",
|
||||
reinterpret_cast<void *>(&nativeCreateSurface)},
|
||||
{"nativeDestroySurface", "(J)V", reinterpret_cast<void *>(&nativeDestroySurface)},
|
||||
{"nativeStart", "(J)V", reinterpret_cast<void *>(&nativeStart)},
|
||||
{"nativeStop", "(J)V", reinterpret_cast<void *>(&nativeStop)},
|
||||
{"nativePause", "(J)V", reinterpret_cast<void *>(&nativePause)},
|
||||
{"nativeResume", "(J)V", reinterpret_cast<void *>(&nativeResume)},
|
||||
{"nativeUpdate", "(J)V", reinterpret_cast<void *>(&nativeUpdate)},
|
||||
{"nativeTerminate", "(J)V", reinterpret_cast<void *>(&nativeTerminate)},
|
||||
{"nativeResize", "(JIIFII)V",
|
||||
reinterpret_cast<void *>(static_cast<void JNICALL (
|
||||
*)(JNIEnv *, jobject, jlong, jint, jint, jfloat, jint, jint)>(&nativeResize))},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include <tuple>
|
||||
@@ -16,6 +17,7 @@
|
||||
#include <mbgl/platform/gl.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
pthread_once_t loadGLExtensions = PTHREAD_ONCE_INIT;
|
||||
|
||||
@@ -59,7 +61,7 @@ NativeMapView::NativeMapView(JNIEnv *env, jobject obj_)
|
||||
: mbgl::View(*this),
|
||||
fileCache(mbgl::android::cachePath + "/mbgl-cache.db"),
|
||||
fileSource(&fileCache),
|
||||
map(*this, fileSource) {
|
||||
map(*this, fileSource, MapMode::Continuous, true) {
|
||||
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::NativeMapView");
|
||||
|
||||
assert(env != nullptr);
|
||||
@@ -121,11 +123,11 @@ void NativeMapView::deactivate() {
|
||||
}
|
||||
}
|
||||
|
||||
void NativeMapView::invalidate() {
|
||||
void NativeMapView::invalidate(std::function<void()> render) {
|
||||
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::invalidate");
|
||||
|
||||
if ((display != EGL_NO_DISPLAY) && (surface != EGL_NO_SURFACE)) {
|
||||
map.render();
|
||||
render();
|
||||
|
||||
if (!eglSwapBuffers(display, surface)) {
|
||||
mbgl::Log::Error(mbgl::Event::OpenGL, "eglSwapBuffers() returned error %d",
|
||||
@@ -576,23 +578,6 @@ EGLConfig NativeMapView::chooseConfig(const EGLConfig configs[], EGLint numConfi
|
||||
return configId;
|
||||
}
|
||||
|
||||
void NativeMapView::start() {
|
||||
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::start");
|
||||
|
||||
if (display == EGL_NO_DISPLAY) {
|
||||
initializeDisplay();
|
||||
}
|
||||
|
||||
if (context == EGL_NO_CONTEXT) {
|
||||
initializeContext();
|
||||
}
|
||||
|
||||
assert(display != EGL_NO_DISPLAY);
|
||||
assert(context != EGL_NO_CONTEXT);
|
||||
|
||||
map.start(true);
|
||||
}
|
||||
|
||||
void loadExtensions() {
|
||||
const GLubyte *str = glGetString(GL_EXTENSIONS);
|
||||
if (str == nullptr) {
|
||||
@@ -689,14 +674,6 @@ void loadExtensions() {
|
||||
}
|
||||
}
|
||||
|
||||
void NativeMapView::stop() {
|
||||
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::stop");
|
||||
|
||||
if ((display != EGL_NO_DISPLAY) && (context != EGL_NO_CONTEXT)) {
|
||||
map.stop();
|
||||
}
|
||||
}
|
||||
|
||||
void NativeMapView::pause(bool waitForPause) {
|
||||
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::pause %s",
|
||||
(waitForPause) ? "true" : "false");
|
||||
@@ -824,9 +801,5 @@ void NativeMapView::updateFps() {
|
||||
env = nullptr;
|
||||
}
|
||||
|
||||
void NativeMapView::resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth, uint16_t fbHeight) {
|
||||
View::resize(width, height, ratio, fbWidth, fbHeight);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,7 +419,6 @@ public class MapView extends SurfaceView {
|
||||
|
||||
mNativeMapView.initializeDisplay();
|
||||
mNativeMapView.initializeContext();
|
||||
mNativeMapView.start();
|
||||
}
|
||||
|
||||
// Called when we need to save instance state
|
||||
@@ -441,7 +440,6 @@ public class MapView extends SurfaceView {
|
||||
// Called when we need to clean up
|
||||
// Must be called from Activity onDestroy
|
||||
public void onDestroy() {
|
||||
mNativeMapView.stop();
|
||||
mNativeMapView.terminateContext();
|
||||
mNativeMapView.terminateDisplay();
|
||||
}
|
||||
|
||||
@@ -73,14 +73,6 @@ class NativeMapView {
|
||||
nativeDestroySurface(mNativeMapViewPtr);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
nativeStart(mNativeMapViewPtr);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
nativeStop(mNativeMapViewPtr);
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
nativePause(mNativeMapViewPtr);
|
||||
}
|
||||
@@ -386,18 +378,12 @@ class NativeMapView {
|
||||
|
||||
private native void nativeDestroySurface(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeStart(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeStop(long nativeMapViewPtr);
|
||||
|
||||
private native void nativePause(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeResume(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeUpdate(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeTerminate(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeResize(long nativeMapViewPtr, int width,
|
||||
int height, float ratio, int fbWidth, int fbHeight);
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
export BUILDTYPE=Debug
|
||||
|
||||
./android/scripts/common.sh $1
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
export BUILDTYPE=Release
|
||||
|
||||
./android/scripts/common.sh $1
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
NAME=$1
|
||||
|
||||
case `uname -s` in
|
||||
'Darwin') export JOBS=`sysctl -n hw.ncpu` ;;
|
||||
'Linux') export JOBS=`nproc` ;;
|
||||
*) export JOBS=1 ;;
|
||||
esac
|
||||
|
||||
|
||||
export CC=clang CXX=clang++
|
||||
export MASON_PLATFORM=android
|
||||
|
||||
mkdir -p ./android/java/MapboxGLAndroidSDKTestApp/src/main/res/raw/
|
||||
echo "${MAPBOX_ACCESS_TOKEN}" >> ./android/java/MapboxGLAndroidSDKTestApp/src/main/res/raw/token.txt
|
||||
|
||||
make android -j$JOBS BUILDTYPE=$BUILDTYPE JOBS=$JOBS
|
||||
|
||||
S3_PREFIX=s3://mapbox/mapbox-gl-native/android/build/${NAME}
|
||||
APK_OUTPUTS=./android/java/MapboxGLAndroidSDKTestApp/build/outputs/apk
|
||||
|
||||
# Upload the shared object.
|
||||
aws s3 cp \
|
||||
./build/android-${ANDROID_ABI}/${BUILDTYPE}/lib.target/libmapbox-gl.so \
|
||||
${S3_PREFIX}/libmapbox-gl.so
|
||||
|
||||
# Upload either the debug or the release build
|
||||
if [ ${BUILDTYPE} == "Debug" ] ; then
|
||||
aws s3 cp \
|
||||
${APK_OUTPUTS}/MapboxGLAndroidSDKTestApp-debug.apk \
|
||||
${S3_PREFIX}/MapboxGLAndroidSDKTestApp-debug.apk
|
||||
elif [ ${BUILDTYPE} == "Release" ] ; then
|
||||
aws s3 cp \
|
||||
${APK_OUTPUTS}/MapboxGLAndroidSDKTestApp-release-unsigned.apk \
|
||||
${S3_PREFIX}/MapboxGLAndroidSDKTestApp-release-unsigned.apk
|
||||
fi
|
||||
@@ -1,85 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
cwd=$(pwd)
|
||||
|
||||
region="us-east-1"
|
||||
region_ami="ami-022e0c6a"
|
||||
sleep=10
|
||||
instance_name="android-gl-build-$TRAVIS_REPO_SLUG-$TRAVIS_JOB_NUMBER"
|
||||
echo $ami_name
|
||||
|
||||
NAME=$TRAVIS_JOB_ID
|
||||
|
||||
user_data="#!/bin/bash
|
||||
cd /android
|
||||
git clone git://github.com/mapbox/mapbox-gl-native.git
|
||||
|
||||
pushd mapbox-gl-native
|
||||
if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then
|
||||
git checkout $TRAVIS_COMMIT
|
||||
else
|
||||
git fetch origin +refs/pull/$TRAVIS_PULL_REQUEST/merge:
|
||||
git checkout FETCH_HEAD
|
||||
fi
|
||||
git submodule update --init --recursive
|
||||
|
||||
export ANDROID_NDK_PATH=/android/android-ndk-r10d
|
||||
export JAVA_HOME=/android/jdk1.7.0_71
|
||||
export ANDROID_HOME=/android/android-sdk-linux
|
||||
export PATH=\$PATH:/android/jdk1.7.0_71/bin
|
||||
export MAPBOX_ACCESS_TOKEN=$MAPBOX_ACCESS_TOKEN
|
||||
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'
|
||||
else
|
||||
echo 'ANDROID BUILD FAILED'
|
||||
fi
|
||||
popd
|
||||
|
||||
aws s3 cp --region us-east-1 build.log s3://mapbox/mapbox-gl-native/android/build/${NAME}/build-log.txt
|
||||
shutdown -P now"
|
||||
|
||||
id=$(aws ec2 run-instances \
|
||||
--region $region \
|
||||
--image-id $region_ami \
|
||||
--count 1 \
|
||||
--instance-type m3.large \
|
||||
--iam-instance-profile Arn="$ANDROID_BUILD_INSTANCE_PROFILE" \
|
||||
--instance-initiated-shutdown-behavior terminate \
|
||||
--user-data "$user_data" | jq -r '.Instances[0].InstanceId')
|
||||
|
||||
echo "Instance: $region $id"
|
||||
|
||||
sleep 10
|
||||
|
||||
result=$(aws ec2 create-tags --region $region --resources $id --tags "Key=Name,Value=$instance_name")
|
||||
|
||||
instance_status_terminated=$(aws ec2 describe-instances --region $region --instance-id $id | jq -r '.Reservations[0].Instances[0].State.Name')
|
||||
|
||||
until [ "$instance_status_terminated" = "terminated" ]; do
|
||||
instance_status_terminated=$(aws ec2 describe-instances --region $region --instance-id $id | jq -r '.Reservations[0].Instances[0].State.Name')
|
||||
echo "Instance terminating status $region $id: $instance_status_terminated"
|
||||
sleep $sleep
|
||||
done
|
||||
|
||||
echo "Build finished"
|
||||
|
||||
output=$(aws ec2 get-console-output --region $region --instance-id $id | jq -r '.Output')
|
||||
|
||||
aws s3 cp --region $region s3://mapbox/mapbox-gl-native/android/build/${NAME}/build-log.txt build.log
|
||||
cat build.log
|
||||
|
||||
if [[ $output == *"ANDROID BUILD PASSED"* ]]; then
|
||||
echo "ANDROID BUILD PASSED"
|
||||
exit 0
|
||||
else
|
||||
echo "ANDROID BUILD FAILED"
|
||||
exit 1
|
||||
fi
|
||||
@@ -31,32 +31,32 @@ 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)
|
||||
ENV_android-arm-v8 = $(shell MASON_ANDROID_ABI=arm-v8 ./scripts/android/toolchain.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)
|
||||
ENV_android-arm-v7 = $(shell MASON_ANDROID_ABI=arm-v7 ./scripts/android/toolchain.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)
|
||||
ENV_android-arm-v5 = $(shell MASON_ANDROID_ABI=arm-v5 ./scripts/android/toolchain.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)
|
||||
ENV_android-x86 = $(shell MASON_ANDROID_ABI=x86 ./scripts/android/toolchain.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)
|
||||
# ENV_android-x86-64 = $(shell MASON_ANDROID_ABI=x86-64 ./scripts/android/toolchain.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)
|
||||
ENV_android-mips = $(shell MASON_ANDROID_ABI=mips ./scripts/android/toolchain.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)
|
||||
ENV_android-mips-64 = $(shell MASON_ANDROID_ABI=mips-64 ./scripts/android/toolchain.sh)
|
||||
CONFIG_android-mips-64 = -Dhost=android -Iconfig/android-mips-64.gypi
|
||||
|
||||
LIBS_android = -Dheadless_lib=none
|
||||
|
||||
5
configure
vendored
5
configure
vendored
@@ -15,7 +15,8 @@ function finish {
|
||||
trap finish EXIT
|
||||
|
||||
# Install mason
|
||||
. ./scripts/local_mason.sh
|
||||
git submodule update --init .mason
|
||||
export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason"
|
||||
|
||||
case ${MASON_PLATFORM} in
|
||||
'ios')
|
||||
@@ -44,7 +45,7 @@ case ${MASON_PLATFORM} in
|
||||
LIBCURL_VERSION=system
|
||||
LIBUV_VERSION=0.10.28
|
||||
ZLIB_VERSION=system
|
||||
BOOST_VERSION=system
|
||||
BOOST_VERSION=1.57.0
|
||||
NUNICODE_VERSION=1.5.1
|
||||
LIBZIP_VERSION=0.11.2
|
||||
;;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
export TRAVIS_OS_NAME=linux
|
||||
|
||||
cd build
|
||||
|
||||
source ./scripts/local_mason.sh
|
||||
mason install mesa 10.4.3
|
||||
export LD_LIBRARY_PATH=`mason prefix mesa 10.4.3`/lib
|
||||
|
||||
export DISPLAY=:99.0
|
||||
Xvfb :99 -ac -screen 0 1024x768x24 &
|
||||
|
||||
if [[ ${CXX} == "g++" ]]; then
|
||||
export CXX="g++-4.8"
|
||||
export CC="gcc-4.8"
|
||||
fi
|
||||
|
||||
source ./scripts/install_node.sh
|
||||
|
||||
make linux -j`nproc`
|
||||
make test-* -j`nproc`
|
||||
./scripts/compare_images.sh
|
||||
5
gyp/ios.gyp
Normal file
5
gyp/ios.gyp
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
'includes': [
|
||||
'../ios/app/mapboxgl-app.gypi',
|
||||
],
|
||||
}
|
||||
7
gyp/linux.gyp
Normal file
7
gyp/linux.gyp
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
'includes': [
|
||||
'../linux/mapboxgl-app.gypi',
|
||||
'../test/test.gypi',
|
||||
'../bin/render.gypi',
|
||||
],
|
||||
}
|
||||
8
gyp/osx.gyp
Normal file
8
gyp/osx.gyp
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
'includes': [
|
||||
'../macosx/mapboxgl-app.gypi',
|
||||
'../linux/mapboxgl-app.gypi',
|
||||
'../test/test.gypi',
|
||||
'../bin/render.gypi',
|
||||
],
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
'sources': [
|
||||
'../platform/android/log_android.cpp',
|
||||
'../platform/android/asset_root.cpp',
|
||||
'../platform/default/thread.cpp',
|
||||
'../platform/default/string_stdlib.cpp',
|
||||
'../platform/default/image.cpp',
|
||||
'../platform/default/image_reader.cpp',
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
'../platform/darwin/application_root.mm',
|
||||
'../platform/darwin/asset_root.mm',
|
||||
'../platform/darwin/image.mm',
|
||||
'../platform/darwin/nsthread.mm',
|
||||
'../platform/darwin/reachability.m',
|
||||
'../include/mbgl/ios/MapboxGL.h',
|
||||
'../include/mbgl/ios/MGLMapboxEvents.h',
|
||||
@@ -22,6 +23,8 @@
|
||||
'../include/mbgl/ios/MGLMapView.h',
|
||||
'../include/mbgl/ios/MGLMapView+IBAdditions.h',
|
||||
'../platform/ios/MGLMapView.mm',
|
||||
'../platform/ios/MGLFileCache.h',
|
||||
'../platform/ios/MGLFileCache.mm',
|
||||
'../include/mbgl/ios/MGLAccountManager.h',
|
||||
'../platform/ios/MGLAccountManager.m',
|
||||
'../include/mbgl/ios/MGLAnnotation.h',
|
||||
@@ -33,6 +36,9 @@
|
||||
'../include/mbgl/ios/MGLMetricsLocationManager.h',
|
||||
'../platform/ios/MGLMetricsLocationManager.m',
|
||||
'../include/mbgl/ios/MGLTypes.h',
|
||||
'../platform/ios/NSBundle+MGLAdditions.h',
|
||||
'../platform/ios/NSBundle+MGLAdditions.m',
|
||||
'../platform/ios/NSException+MGLAdditions.h',
|
||||
'../platform/ios/NSProcessInfo+MGLAdditions.h',
|
||||
'../platform/ios/NSProcessInfo+MGLAdditions.m',
|
||||
'../platform/ios/NSString+MGLAdditions.h',
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
'../platform/default/string_stdlib.cpp',
|
||||
'../platform/default/application_root.cpp',
|
||||
'../platform/default/asset_root.cpp',
|
||||
'../platform/default/thread.cpp',
|
||||
'../platform/default/image.cpp',
|
||||
'../platform/default/image_reader.cpp',
|
||||
'../platform/default/png_reader.cpp',
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
'../platform/darwin/application_root.mm',
|
||||
'../platform/darwin/asset_root.mm',
|
||||
'../platform/darwin/image.mm',
|
||||
'../platform/darwin/nsthread.mm',
|
||||
],
|
||||
|
||||
'variables': {
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
void notify() override;
|
||||
void invalidate() override;
|
||||
void invalidate(std::function<void()> render) override;
|
||||
|
||||
void notifyMapChange(mbgl::MapChange change, Duration delay = Duration::zero()) override;
|
||||
|
||||
@@ -39,17 +39,12 @@ public:
|
||||
void createSurface(ANativeWindow *window);
|
||||
void destroySurface();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
void resume();
|
||||
void pause(bool waitForPause = false);
|
||||
|
||||
void enableFps(bool enable);
|
||||
void updateFps();
|
||||
|
||||
void resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth, uint16_t fbHeight);
|
||||
|
||||
private:
|
||||
EGLConfig chooseConfig(const EGLConfig configs[], EGLint numConfigs);
|
||||
|
||||
|
||||
@@ -49,11 +49,6 @@ IB_DESIGNABLE
|
||||
|
||||
/** @name Managing Constraints */
|
||||
|
||||
/** A view controller whose top and bottom layout guides to use for proper setup of constraints in the map view internals.
|
||||
*
|
||||
* Certain components of the map view, such as the heading compass and the data attribution button, need to be aware of the view controller layout in order to avoid positioning content under a top navigation bar or a bottom toolbar. */
|
||||
@property (nonatomic, weak) IBOutlet UIViewController *viewControllerForLayoutGuides;
|
||||
|
||||
#pragma mark - Accessing Map Properties
|
||||
|
||||
/** @name Accessing Map Properties */
|
||||
|
||||
@@ -4,6 +4,7 @@ extern NSString *const MGLEventTypeMapLoad;
|
||||
extern NSString *const MGLEventTypeMapTap;
|
||||
extern NSString *const MGLEventTypeMapDragEnd;
|
||||
extern NSString *const MGLEventTypeLocation;
|
||||
extern NSString *const MGLEventTypeVisit;
|
||||
|
||||
extern NSString *const MGLEventKeyLatitude;
|
||||
extern NSString *const MGLEventKeyLongitude;
|
||||
@@ -16,6 +17,8 @@ extern NSString *const MGLEventKeyVerticalAccuracy;
|
||||
extern NSString *const MGLEventKeyPushEnabled;
|
||||
extern NSString *const MGLEventKeyEmailEnabled;
|
||||
extern NSString *const MGLEventKeyGestureID;
|
||||
extern NSString *const MGLEventKeyArrivalDate;
|
||||
extern NSString *const MGLEventKeyDepartureDate;
|
||||
|
||||
extern NSString *const MGLEventGestureSingleTap;
|
||||
extern NSString *const MGLEventGestureDoubleTap;
|
||||
@@ -32,6 +35,7 @@ extern NSString *const MGLEventGestureRotateStart;
|
||||
+ (void) setToken:(NSString *)token;
|
||||
+ (void) setAppName:(NSString *)appName;
|
||||
+ (void) setAppVersion:(NSString *)appVersion;
|
||||
+ (void) setAppBuildNumber:(NSString *)appBuildNumber;
|
||||
+ (void) pauseMetricsCollection;
|
||||
+ (void) resumeMetricsCollection;
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
// These methods can be called from any thread.
|
||||
//
|
||||
+ (instancetype)sharedManager;
|
||||
+ (void) startUpdatingLocation;
|
||||
+ (void) stopUpdatingLocation;
|
||||
- (void) startUpdatingLocation;
|
||||
- (void) stopUpdatingLocation;
|
||||
- (void) startMonitoringVisits;
|
||||
- (void) stopMonitoringVisits;
|
||||
|
||||
@end
|
||||
|
||||
@@ -54,11 +54,6 @@ public:
|
||||
// Only call this while the OpenGL context is exclusive to this thread.
|
||||
void performCleanup();
|
||||
|
||||
// #############################################################################################
|
||||
|
||||
// Request to terminate the environment.
|
||||
void terminate();
|
||||
|
||||
private:
|
||||
unsigned id;
|
||||
FileSource& fileSource;
|
||||
@@ -67,9 +62,6 @@ private:
|
||||
std::vector<uint32_t> abandonedVAOs;
|
||||
std::vector<uint32_t> abandonedBuffers;
|
||||
std::vector<uint32_t> abandonedTextures;
|
||||
|
||||
public:
|
||||
uv_loop_t* const loop;
|
||||
};
|
||||
|
||||
class EnvironmentScope final {
|
||||
|
||||
@@ -1,96 +1,57 @@
|
||||
#ifndef MBGL_MAP_MAP
|
||||
#define MBGL_MAP_MAP
|
||||
|
||||
#include <mbgl/map/transform.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/map/update.hpp>
|
||||
#include <mbgl/map/mode.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/util/projection.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
#include <mbgl/util/vec.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <iosfwd>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
namespace uv { class async; }
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Painter;
|
||||
class GlyphStore;
|
||||
class LayerDescription;
|
||||
class Sprite;
|
||||
class Style;
|
||||
class StyleLayer;
|
||||
class TexturePool;
|
||||
class FileSource;
|
||||
class View;
|
||||
class GlyphAtlas;
|
||||
class SpriteAtlas;
|
||||
class LineAtlas;
|
||||
class Environment;
|
||||
class EnvironmentScope;
|
||||
class AnnotationManager;
|
||||
class MapData;
|
||||
class Worker;
|
||||
class MapContext;
|
||||
class StillImage;
|
||||
|
||||
namespace util {
|
||||
template <class T> class Thread;
|
||||
}
|
||||
|
||||
class Map : private util::noncopyable {
|
||||
friend class View;
|
||||
|
||||
public:
|
||||
enum class Mode : uint8_t {
|
||||
None, // we're not doing any processing
|
||||
Continuous, // continually updating map
|
||||
Still, // a once-off still image.
|
||||
};
|
||||
|
||||
explicit Map(View&, FileSource&);
|
||||
explicit Map(View&, FileSource&,
|
||||
MapMode mode = MapMode::Continuous,
|
||||
bool startPaused = false);
|
||||
~Map();
|
||||
|
||||
// Start the map render thread. It is asynchronous.
|
||||
void start(bool startPaused = false, Mode mode = Mode::Continuous);
|
||||
inline void start(Mode renderMode) { start(false, renderMode); }
|
||||
|
||||
// Stop the map render thread. This call will block until the map rendering thread stopped.
|
||||
// The optional callback function will be invoked repeatedly until the map thread is stopped.
|
||||
// The callback function should wait until it is woken up again by view.notify(), otherwise
|
||||
// this will be a busy waiting loop.
|
||||
void stop(std::function<void ()> callback = std::function<void ()>());
|
||||
|
||||
// Pauses the render thread. The render thread will stop running but will not be terminated and will not lose state until resumed.
|
||||
void pause(bool waitForPause = false);
|
||||
|
||||
// Resumes a paused render thread
|
||||
void resume();
|
||||
|
||||
// Register a callback that will get called (on the render thread) when all resources have
|
||||
// been loaded and a complete render occurs.
|
||||
using StillImageCallback = std::function<void(std::unique_ptr<const StillImage>)>;
|
||||
void renderStill(StillImageCallback callback);
|
||||
|
||||
// Triggers a synchronous or asynchronous render.
|
||||
void renderSync();
|
||||
|
||||
// Unconditionally performs a render with the current map state. May only be called from the Map
|
||||
// thread.
|
||||
void render();
|
||||
void renderAsync();
|
||||
|
||||
// Notifies the Map thread that the state has changed and an update might be necessary.
|
||||
void triggerUpdate(Update = Update::Nothing);
|
||||
|
||||
// Triggers a render. Can be called from any thread.
|
||||
void triggerRender();
|
||||
|
||||
// Releases resources immediately
|
||||
void terminate();
|
||||
void update(Update update = Update::Nothing);
|
||||
|
||||
// Styling
|
||||
void addClass(const std::string&);
|
||||
@@ -134,18 +95,23 @@ public:
|
||||
double getBearing() const;
|
||||
void resetNorth();
|
||||
|
||||
// Size
|
||||
void resize(uint16_t width, uint16_t height, float ratio = 1);
|
||||
uint16_t getWidth() const;
|
||||
uint16_t getHeight() const;
|
||||
|
||||
// API
|
||||
void setAccessToken(const std::string &token);
|
||||
std::string getAccessToken() const;
|
||||
|
||||
// Projection
|
||||
inline void getWorldBoundsMeters(ProjectedMeters &sw, ProjectedMeters &ne) const { Projection::getWorldBoundsMeters(sw, ne); }
|
||||
inline void getWorldBoundsLatLng(LatLng &sw, LatLng &ne) const { Projection::getWorldBoundsLatLng(sw, ne); }
|
||||
inline double getMetersPerPixelAtLatitude(const double lat, const double zoom) const { return Projection::getMetersPerPixelAtLatitude(lat, zoom); }
|
||||
inline const ProjectedMeters projectedMetersForLatLng(const LatLng latLng) const { return Projection::projectedMetersForLatLng(latLng); }
|
||||
inline const LatLng latLngForProjectedMeters(const ProjectedMeters projectedMeters) const { return Projection::latLngForProjectedMeters(projectedMeters); }
|
||||
inline const vec2<double> pixelForLatLng(const LatLng latLng) const { return state.pixelForLatLng(latLng); }
|
||||
inline const LatLng latLngForPixel(const vec2<double> pixel) const { return state.latLngForPixel(pixel); }
|
||||
void getWorldBoundsMeters(ProjectedMeters &sw, ProjectedMeters &ne) const;
|
||||
void getWorldBoundsLatLng(LatLng &sw, LatLng &ne) const;
|
||||
double getMetersPerPixelAtLatitude(const double lat, const double zoom) const;
|
||||
const ProjectedMeters projectedMetersForLatLng(const LatLng latLng) const;
|
||||
const LatLng latLngForProjectedMeters(const ProjectedMeters projectedMeters) const;
|
||||
const vec2<double> pixelForLatLng(const LatLng latLng) const;
|
||||
const LatLng latLngForPixel(const vec2<double> pixel) const;
|
||||
|
||||
// Annotations
|
||||
void setDefaultPointAnnotationSymbol(const std::string&);
|
||||
@@ -160,7 +126,6 @@ public:
|
||||
|
||||
// Memory
|
||||
void setSourceTileCacheSize(size_t);
|
||||
size_t getSourceTileCacheSize() const { return sourceCacheSize; }
|
||||
void onLowMemory();
|
||||
|
||||
// Debug
|
||||
@@ -168,104 +133,9 @@ public:
|
||||
void toggleDebug();
|
||||
bool getDebug() const;
|
||||
|
||||
inline const TransformState &getState() const { return state; }
|
||||
TimePoint getTime() const;
|
||||
inline AnnotationManager& getAnnotationManager() const { return *annotationManager; }
|
||||
|
||||
private:
|
||||
// Runs the map event loop. ONLY run this function when you want to get render a single frame
|
||||
// with this map object. It will *not* spawn a separate thread and instead block until the
|
||||
// frame is completely rendered.
|
||||
void run();
|
||||
|
||||
// This may only be called by the View object.
|
||||
void resize(uint16_t width, uint16_t height, float ratio = 1);
|
||||
void resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth, uint16_t fbHeight);
|
||||
|
||||
util::ptr<Sprite> getSprite();
|
||||
Worker& getWorker();
|
||||
|
||||
// Checks if render thread needs to pause
|
||||
void checkForPause();
|
||||
|
||||
// Setup
|
||||
void setup();
|
||||
|
||||
void updateTiles();
|
||||
|
||||
// Triggered by triggerUpdate();
|
||||
void update();
|
||||
|
||||
// Loads the style set in the data object. Called by Update::StyleInfo
|
||||
void reloadStyle();
|
||||
void loadStyleJSON(const std::string& json, const std::string& base);
|
||||
|
||||
// Prepares a map render by updating the tiles we need for the current view, as well as updating
|
||||
// the stylesheet.
|
||||
void prepare();
|
||||
|
||||
// Runs the function in the map thread.
|
||||
void invokeTask(std::function<void()>&&);
|
||||
template <typename Fn> auto invokeSyncTask(const Fn& fn) -> decltype(fn());
|
||||
|
||||
void processTasks();
|
||||
|
||||
void updateAnnotationTiles(const std::vector<TileID>&);
|
||||
|
||||
size_t sourceCacheSize;
|
||||
|
||||
Mode mode = Mode::None;
|
||||
|
||||
const std::unique_ptr<Environment> env;
|
||||
std::unique_ptr<EnvironmentScope> scope;
|
||||
View &view;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Worker> workers;
|
||||
std::thread thread;
|
||||
std::unique_ptr<uv::async> asyncTerminate;
|
||||
std::unique_ptr<uv::async> asyncUpdate;
|
||||
std::unique_ptr<uv::async> asyncInvoke;
|
||||
std::unique_ptr<uv::async> asyncRender;
|
||||
|
||||
bool terminating = false;
|
||||
bool pausing = false;
|
||||
bool isPaused = false;
|
||||
std::mutex mutexRun;
|
||||
std::condition_variable condRun;
|
||||
std::mutex mutexPause;
|
||||
std::condition_variable condPause;
|
||||
|
||||
// Used to signal that rendering completed.
|
||||
bool rendered = false;
|
||||
std::condition_variable condRendered;
|
||||
std::mutex mutexRendered;
|
||||
|
||||
// Stores whether the map thread has been stopped already.
|
||||
std::atomic_bool isStopped;
|
||||
|
||||
Transform transform;
|
||||
TransformState state;
|
||||
|
||||
FileSource& fileSource;
|
||||
|
||||
util::ptr<Style> style;
|
||||
std::unique_ptr<GlyphAtlas> glyphAtlas;
|
||||
util::ptr<GlyphStore> glyphStore;
|
||||
std::unique_ptr<SpriteAtlas> spriteAtlas;
|
||||
util::ptr<Sprite> sprite;
|
||||
std::unique_ptr<LineAtlas> lineAtlas;
|
||||
util::ptr<TexturePool> texturePool;
|
||||
std::unique_ptr<Painter> painter;
|
||||
std::unique_ptr<AnnotationManager> annotationManager;
|
||||
|
||||
const std::unique_ptr<MapData> data;
|
||||
|
||||
std::atomic<UpdateType> updated;
|
||||
|
||||
std::mutex mutexTask;
|
||||
std::queue<std::function<void()>> tasks;
|
||||
StillImageCallback callback;
|
||||
const std::unique_ptr<util::Thread<MapContext>> context;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
15
include/mbgl/map/mode.hpp
Normal file
15
include/mbgl/map/mode.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef MBGL_MAP_MODE
|
||||
#define MBGL_MAP_MODE
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
enum class MapMode : uint8_t {
|
||||
Continuous, // continually updating map
|
||||
Still, // a once-off still image
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -9,7 +9,6 @@ using UpdateType = uint32_t;
|
||||
|
||||
enum class Update : UpdateType {
|
||||
Nothing = 0,
|
||||
StyleInfo = 1 << 0,
|
||||
Debug = 1 << 1,
|
||||
DefaultTransitionDuration = 1 << 2,
|
||||
Classes = 1 << 3,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define MBGL_MAP_VIEW
|
||||
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <functional>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -39,13 +40,13 @@ public:
|
||||
|
||||
virtual void notify() = 0;
|
||||
|
||||
// Called from the render thread. The implementation must trigger a rerender.
|
||||
// (i.e. map->renderSync() or map->renderAsync() must be called as a result of this)
|
||||
virtual void invalidate() = 0;
|
||||
// Called from the render thread. The implementation should resize the framebuffer.
|
||||
virtual void resize(uint16_t width, uint16_t height, float pixelRatio);
|
||||
|
||||
// Called from the render (=GL) thread. Signals that the contents of the contents
|
||||
// may be discarded. The default is a no-op.
|
||||
virtual void discard();
|
||||
// Called from the render thread. The implementation must trigger a rerender.
|
||||
// (i.e. either the passed render() function for rendering immediately on the map thread,
|
||||
// or map->renderSync() from the main thread must be called as a result of this)
|
||||
virtual void invalidate(std::function<void()> render) = 0;
|
||||
|
||||
// Reads the pixel data from the current framebuffer. If your View implementation
|
||||
// doesn't support reading from the framebuffer, return a null pointer.
|
||||
@@ -58,10 +59,6 @@ public:
|
||||
MapChange change,
|
||||
Duration delay = Duration::zero());
|
||||
|
||||
protected:
|
||||
// Resizes the view
|
||||
void resize(uint16_t width, uint16_t height, float ratio, uint16_t fbWidth, uint16_t fbHeight);
|
||||
|
||||
protected:
|
||||
mbgl::Map *map = nullptr;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
void notify() override;
|
||||
void invalidate() override;
|
||||
void invalidate(std::function<void()> render) override;
|
||||
|
||||
static void onKey(GLFWwindow *window, int key, int scancode, int action, int mods);
|
||||
static void onScroll(GLFWwindow *window, double xoffset, double yoffset);
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
static void onMouseClick(GLFWwindow *window, int button, int action, int modifiers);
|
||||
static void onMouseMove(GLFWwindow *window, double x, double y);
|
||||
|
||||
int run();
|
||||
void run();
|
||||
void fps();
|
||||
|
||||
public:
|
||||
|
||||
@@ -17,6 +17,7 @@ typedef XID GLXPbuffer;
|
||||
#include <mbgl/platform/gl.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -28,13 +29,11 @@ public:
|
||||
HeadlessView(std::shared_ptr<HeadlessDisplay> display, uint16_t width = 256, uint16_t height = 256, float pixelRatio = 1);
|
||||
~HeadlessView();
|
||||
|
||||
void resize(uint16_t width, uint16_t height, float pixelRatio);
|
||||
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
void notify() override;
|
||||
void invalidate() override;
|
||||
void discard() override;
|
||||
void resize(uint16_t width, uint16_t height, float pixelRatio) override;
|
||||
void invalidate(std::function<void()> render) override;
|
||||
std::unique_ptr<StillImage> readStillImage() override;
|
||||
|
||||
private:
|
||||
@@ -56,12 +55,7 @@ private:
|
||||
float pixelRatio = 0;
|
||||
};
|
||||
|
||||
// These are the values that represent the state of the current framebuffer.
|
||||
Dimensions current;
|
||||
|
||||
// These are the values that will be used after the next discard() event.
|
||||
std::mutex prospectiveMutex;
|
||||
Dimensions prospective;
|
||||
Dimensions dimensions;
|
||||
|
||||
#if MBGL_USE_CGL
|
||||
CGLContextObj glContext = nullptr;
|
||||
|
||||
@@ -10,10 +10,9 @@ extern "C"
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#ifndef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
||||
@@ -12,10 +12,9 @@ extern "C"
|
||||
#include <memory>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#ifndef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ inline void start_group(const std::string &str) {
|
||||
if (gl::PushDebugGroup != nullptr) {
|
||||
MBGL_CHECK_ERROR(gl::PushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, GLsizei(str.size()), str.c_str()));
|
||||
} else if (gl::PushGroupMarkerEXT != nullptr) {
|
||||
MBGL_CHECK_ERROR(gl::PushGroupMarkerEXT(GLsizei(str.size()), str.c_str()));
|
||||
MBGL_CHECK_ERROR(gl::PushGroupMarkerEXT(GLsizei(str.size() + 1), str.c_str()));
|
||||
}
|
||||
// fprintf(stderr, "%s%s\n", std::string(indent * 4, ' ').c_str(), str.c_str());
|
||||
// indent++;
|
||||
|
||||
@@ -21,6 +21,9 @@ const std::string &applicationRoot();
|
||||
// Returns the path to the asset location.
|
||||
const std::string &assetRoot();
|
||||
|
||||
// Makes the current thread low priority.
|
||||
void makeThreadLowPriority();
|
||||
|
||||
// Shows an alpha image with the specified dimensions in a named window.
|
||||
void showDebugImage(std::string name, const char *data, size_t width, size_t height);
|
||||
|
||||
|
||||
@@ -16,12 +16,9 @@ public:
|
||||
~DefaultFileSource() override;
|
||||
|
||||
// FileSource API
|
||||
Request *request(const Resource &resource, uv_loop_t *loop, const Environment &env,
|
||||
Callback callback) override;
|
||||
void cancel(Request *request) override;
|
||||
void request(const Resource &resource, const Environment &env, Callback callback) override;
|
||||
|
||||
void abort(const Environment &env) override;
|
||||
Request* request(const Resource&, uv_loop_t*, Callback) override;
|
||||
void cancel(Request*) override;
|
||||
void request(const Resource&, Callback) override;
|
||||
|
||||
public:
|
||||
class Impl;
|
||||
|
||||
@@ -15,7 +15,6 @@ typedef struct uv_loop_s uv_loop_t;
|
||||
namespace mbgl {
|
||||
|
||||
class Request;
|
||||
class Environment;
|
||||
|
||||
class FileSource : private util::noncopyable {
|
||||
protected:
|
||||
@@ -28,19 +27,12 @@ public:
|
||||
|
||||
// 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, const Environment &env,
|
||||
Callback callback) = 0;
|
||||
virtual void cancel(Request *request) = 0;
|
||||
virtual Request* request(const Resource&, uv_loop_t*, Callback) = 0;
|
||||
virtual void cancel(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, const Environment &env, Callback callback) = 0;
|
||||
|
||||
// This can be called from any thread. All requests with the environment pointer env should be
|
||||
// notified as errored. Note that this is /different/ from canceling requests; a canceled
|
||||
// request's callback is never called, while an aborted request's callback is called with
|
||||
// a error message.
|
||||
virtual void abort(const Environment &env) = 0;
|
||||
virtual void request(const Resource&, Callback) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -17,14 +17,13 @@ typedef struct uv_loop_s uv_loop_t;
|
||||
namespace mbgl {
|
||||
|
||||
class Response;
|
||||
class Environment;
|
||||
|
||||
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, const Environment &env, Callback callback);
|
||||
Request(const Resource &resource, uv_loop_t *loop, Callback callback);
|
||||
|
||||
public:
|
||||
// May be called from any thread.
|
||||
@@ -48,11 +47,6 @@ private:
|
||||
|
||||
public:
|
||||
const Resource resource;
|
||||
|
||||
// The environment ref is used to associate requests with a particular environment. This allows
|
||||
// us to only terminate requests associated with that environment, e.g. when the map the env
|
||||
// belongs to is discarded.
|
||||
const Environment &env;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -20,8 +20,9 @@ public:
|
||||
void get(const Resource &resource, Callback callback) override;
|
||||
void put(const Resource &resource, std::shared_ptr<const Response> response, Hint hint) override;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
|
||||
private:
|
||||
const std::unique_ptr<util::Thread<Impl>> thread;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
#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
|
||||
87
include/mbgl/util/gl_helper.hpp
Normal file
87
include/mbgl/util/gl_helper.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef MBGL_UTIL_GL_HELPER
|
||||
#define MBGL_UTIL_GL_HELPER
|
||||
|
||||
#include <mbgl/platform/gl.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T, T (*Create)(), void (*Destroy)(const T&)>
|
||||
class Preserve {
|
||||
public:
|
||||
Preserve() : data(Create()) {}
|
||||
~Preserve() { Destroy(data); }
|
||||
|
||||
private:
|
||||
const T data;
|
||||
};
|
||||
|
||||
inline bool getBlend() {
|
||||
return glIsEnabled(GL_BLEND);
|
||||
}
|
||||
|
||||
inline void setBlend(const bool& enabled) {
|
||||
enabled ? MBGL_CHECK_ERROR(glEnable(GL_BLEND)) : MBGL_CHECK_ERROR(glDisable(GL_BLEND));
|
||||
}
|
||||
|
||||
inline std::array<double, 4> getClearColor() {
|
||||
std::array<double, 4> color;
|
||||
MBGL_CHECK_ERROR(glGetDoublev(GL_COLOR_CLEAR_VALUE, color.data()));
|
||||
return color;
|
||||
}
|
||||
|
||||
inline void setClearColor(const std::array<double, 4>& color) {
|
||||
MBGL_CHECK_ERROR(glClearColor(color[0], color[1], color[2], color[3]));
|
||||
}
|
||||
|
||||
|
||||
inline std::array<GLenum, 2> getBlendFunc() {
|
||||
GLint func[2];
|
||||
glGetIntegerv(GL_BLEND_SRC, &func[0]);
|
||||
glGetIntegerv(GL_BLEND_DST, &func[1]);
|
||||
return {{ static_cast<GLenum>(func[0]), static_cast<GLenum>(func[1]) }};
|
||||
}
|
||||
|
||||
inline void setBlendFunc(const std::array<GLenum, 2>& func) {
|
||||
MBGL_CHECK_ERROR(glBlendFunc(func[0], func[1]));
|
||||
}
|
||||
|
||||
|
||||
inline std::array<double, 2> getPixelZoom() {
|
||||
std::array<double, 2> zoom;
|
||||
glGetDoublev(GL_ZOOM_X, &zoom[0]);
|
||||
glGetDoublev(GL_ZOOM_Y, &zoom[1]);
|
||||
return zoom;
|
||||
}
|
||||
|
||||
inline void setPixelZoom(const std::array<double, 2>& func) {
|
||||
MBGL_CHECK_ERROR(glPixelZoom(func[0], func[1]));
|
||||
}
|
||||
|
||||
|
||||
inline std::array<double, 4> getRasterPos() {
|
||||
std::array<double, 4> pos;
|
||||
MBGL_CHECK_ERROR(glGetDoublev(GL_CURRENT_RASTER_POSITION, pos.data()));
|
||||
return pos;
|
||||
}
|
||||
|
||||
inline void setRasterPos(const std::array<double, 4>& pos) {
|
||||
MBGL_CHECK_ERROR(glRasterPos4d(pos[0], pos[1], pos[2], pos[3]));
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
using PreserveBlend = Preserve<bool, getBlend, setBlend>;
|
||||
using PreserveClearColor = Preserve<std::array<double, 4>, getClearColor, setClearColor>;
|
||||
using PreserveBlendFunc = Preserve<std::array<GLenum, 2>, getBlendFunc, setBlendFunc>;
|
||||
using PreservePixelZoom = Preserve<std::array<double, 2>, getPixelZoom, setPixelZoom>;
|
||||
using PreserveRasterPos = Preserve<std::array<double, 4>, getRasterPos, setRasterPos>;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -74,6 +74,11 @@ inline vec2<T> normal(const S1& a, const S2& b) {
|
||||
return { dx / c, dy / c };
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T perp(const T& a) {
|
||||
return T(-a.y, a.x);
|
||||
}
|
||||
|
||||
template <typename T, typename S1, typename S2>
|
||||
inline T dist(const S1& a, const S2& b) {
|
||||
T dx = b.x - a.x;
|
||||
@@ -93,6 +98,11 @@ inline T mag(const S& a) {
|
||||
return std::sqrt(a.x * a.x + a.y * a.y);
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
inline S unit(const S& a) {
|
||||
return a * (1 / mag(a));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T clamp(T value, T min, T max) {
|
||||
return value < min ? min : (value > max ? max : value);
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
#include <string>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#ifndef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#endif
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
||||
@@ -61,7 +61,13 @@ struct vec2 {
|
||||
template <typename O>
|
||||
inline typename std::enable_if<!std::is_arithmetic<O>::value, vec2>::type
|
||||
operator-(const O &o) const {
|
||||
return {x - o.x, y - o.y};
|
||||
return vec2<T>(x - o.x, y - o.y);
|
||||
}
|
||||
|
||||
template <typename O>
|
||||
inline typename std::enable_if<!std::is_arithmetic<O>::value, vec2>::type
|
||||
operator+(const O &o) const {
|
||||
return vec2<T>(x + o.x, y + o.y);
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Pod::Spec.new do |m|
|
||||
|
||||
m.name = 'MapboxGL'
|
||||
m.version = '0.2.15'
|
||||
m.version = '0.2.19'
|
||||
|
||||
m.summary = 'Open source vector map solution for iOS with full styling capabilities.'
|
||||
m.description = 'Open source OpenGL-based vector map solution for iOS with full styling capabilities and Cocoa bindings.'
|
||||
|
||||
@@ -54,7 +54,6 @@ mbgl::Settings_NSUserDefaults *settings = nullptr;
|
||||
|
||||
self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
|
||||
self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
self.mapView.viewControllerForLayoutGuides = self;
|
||||
self.mapView.showsUserLocation = YES;
|
||||
self.mapView.delegate = self;
|
||||
[self.view addSubview:self.mapView];
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>MBGL</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.2</string>
|
||||
<string>0.0.3</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
|
||||
@@ -9,18 +9,18 @@
|
||||
'product_extension': 'app',
|
||||
'mac_bundle': 1,
|
||||
'mac_bundle_resources': [
|
||||
'<!@(find ./img -type f)',
|
||||
'<!@(find ../ios/app/img -type f)',
|
||||
'./features.geojson',
|
||||
'./Settings.bundle/'
|
||||
],
|
||||
|
||||
'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)',
|
||||
'../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': [
|
||||
@@ -38,7 +38,7 @@
|
||||
'SDKROOT': 'iphoneos',
|
||||
'SUPPORTED_PLATFORMS': 'iphonesimulator iphoneos',
|
||||
'IPHONEOS_DEPLOYMENT_TARGET': '7.0',
|
||||
'INFOPLIST_FILE': 'app-info.plist',
|
||||
'INFOPLIST_FILE': '../ios/app/app-info.plist',
|
||||
'TARGETED_DEVICE_FAMILY': '1,2',
|
||||
'COMBINE_HIDPI_IMAGES': 'NO', # don't merge @2x.png images into .tiff files
|
||||
'CLANG_ENABLE_OBJC_ARC': 'YES',
|
||||
@@ -90,7 +90,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
map.setStyleURL(style);
|
||||
|
||||
int ret = view->run();
|
||||
view->run();
|
||||
|
||||
// Save settings
|
||||
mbgl::LatLng latLng = map.getLatLng();
|
||||
@@ -101,5 +101,5 @@ int main(int argc, char *argv[]) {
|
||||
settings.debug = map.getDebug();
|
||||
settings.save();
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ int main() {
|
||||
// Load style
|
||||
map.setStyleURL("asset://styles/bright-v7.json");
|
||||
|
||||
int ret = view.run();
|
||||
view.run();
|
||||
|
||||
[reachability stopNotifier];
|
||||
|
||||
@@ -146,5 +146,5 @@ int main() {
|
||||
settings.debug = map.getDebug();
|
||||
settings.save();
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
|
||||
'SDKROOT': 'macosx',
|
||||
'INFOPLIST_FILE': 'Info.plist',
|
||||
'INFOPLIST_FILE': '../macosx/Info.plist',
|
||||
'CLANG_ENABLE_OBJC_ARC': 'YES'
|
||||
},
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <mbgl/storage/http_request.hpp>
|
||||
#include <mbgl/storage/http_context.hpp>
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/util/uv.hpp>
|
||||
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/util/time.hpp>
|
||||
#include <mbgl/util/parsedate.h>
|
||||
|
||||
@@ -45,32 +45,33 @@ enum class ResponseStatus : uint8_t {
|
||||
|
||||
class HTTPNSURLContext;
|
||||
|
||||
class HTTPRequestImpl {
|
||||
class HTTPRequest : public RequestBase {
|
||||
public:
|
||||
HTTPRequestImpl(HTTPRequest *request, uv_loop_t *loop, std::shared_ptr<const Response> response);
|
||||
~HTTPRequestImpl();
|
||||
HTTPRequest(HTTPNSURLContext*,
|
||||
const Resource&,
|
||||
Callback,
|
||||
uv_loop_t*,
|
||||
std::shared_ptr<const Response>);
|
||||
~HTTPRequest();
|
||||
|
||||
void cancel();
|
||||
void cancelTimer();
|
||||
void cancel() override;
|
||||
void retry() override;
|
||||
|
||||
private:
|
||||
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;
|
||||
bool cancelled = false;
|
||||
NSURLSessionDataTask *task = nullptr;
|
||||
std::unique_ptr<Response> response;
|
||||
const std::shared_ptr<const Response> existingResponse;
|
||||
ResponseStatus status = ResponseStatus::PermanentError;
|
||||
uv_async_t *async = nullptr;
|
||||
uv::async async;
|
||||
uv::timer timer;
|
||||
int attempts = 0;
|
||||
uv_timer_t *timer = nullptr;
|
||||
enum : bool { PreemptImmediately, ExponentialBackoff } strategy = PreemptImmediately;
|
||||
|
||||
static const int maxAttempts = 4;
|
||||
@@ -78,18 +79,20 @@ private:
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
class HTTPNSURLContext : public HTTPContext<HTTPNSURLContext> {
|
||||
class HTTPNSURLContext : public HTTPContext {
|
||||
public:
|
||||
HTTPNSURLContext(uv_loop_t *loop);
|
||||
~HTTPNSURLContext();
|
||||
|
||||
RequestBase* createRequest(const Resource&,
|
||||
RequestBase::Callback,
|
||||
uv_loop_t*,
|
||||
std::shared_ptr<const Response>) override;
|
||||
|
||||
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 =
|
||||
@@ -115,34 +118,42 @@ HTTPNSURLContext::~HTTPNSURLContext() {
|
||||
userAgent = nullptr;
|
||||
}
|
||||
|
||||
RequestBase* HTTPNSURLContext::createRequest(const Resource& resource,
|
||||
RequestBase::Callback callback,
|
||||
uv_loop_t* loop,
|
||||
std::shared_ptr<const Response> response) {
|
||||
return new HTTPRequest(this, resource, callback, loop, response);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
HTTPRequestImpl::HTTPRequestImpl(HTTPRequest *request_, uv_loop_t *loop,
|
||||
std::shared_ptr<const Response> existingResponse_)
|
||||
: context(HTTPNSURLContext::Get(loop)),
|
||||
request(request_),
|
||||
HTTPRequest::HTTPRequest(HTTPNSURLContext* context_, const Resource& resource_, Callback callback_, uv_loop_t *loop, std::shared_ptr<const Response> existingResponse_)
|
||||
: RequestBase(resource_, callback_),
|
||||
context(context_),
|
||||
existingResponse(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();
|
||||
});
|
||||
|
||||
async(loop, [this] { handleResponse(); }),
|
||||
timer(loop) {
|
||||
context->addRequest(this);
|
||||
start();
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::start() {
|
||||
HTTPRequest::~HTTPRequest() {
|
||||
assert(!task);
|
||||
|
||||
// Stop the backoff timer to avoid re-triggering this request.
|
||||
timer.stop();
|
||||
|
||||
context->removeRequest(this);
|
||||
}
|
||||
|
||||
void HTTPRequest::start() {
|
||||
assert(!task);
|
||||
|
||||
attempts++;
|
||||
|
||||
@autoreleasepool {
|
||||
|
||||
NSMutableString *url = [[NSMutableString alloc] initWithString:@(request->resource.url.c_str())];
|
||||
NSMutableString *url = [[NSMutableString alloc] initWithString:@(resource.url.c_str())];
|
||||
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"mapbox_metrics_disabled"] == nil) {
|
||||
if ([url rangeOfString:@"?"].location == NSNotFound) {
|
||||
[url appendString:@"?"];
|
||||
@@ -174,13 +185,13 @@ void HTTPRequestImpl::start() {
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::handleResponse() {
|
||||
void HTTPRequest::handleResponse() {
|
||||
if (task) {
|
||||
[task release];
|
||||
task = nullptr;
|
||||
}
|
||||
|
||||
if (request) {
|
||||
if (!cancelled) {
|
||||
if (status == ResponseStatus::TemporaryError && attempts < maxAttempts) {
|
||||
strategy = ExponentialBackoff;
|
||||
return retry((1 << (attempts - 1)) * 1000);
|
||||
@@ -193,26 +204,21 @@ void HTTPRequestImpl::handleResponse() {
|
||||
|
||||
// Actually return the response.
|
||||
if (status == ResponseStatus::NotModified) {
|
||||
request->notify(std::move(response), FileCache::Hint::Refresh);
|
||||
notify(std::move(response), FileCache::Hint::Refresh);
|
||||
} else {
|
||||
request->notify(std::move(response), FileCache::Hint::Full);
|
||||
notify(std::move(response), FileCache::Hint::Full);
|
||||
}
|
||||
|
||||
context->removeRequest(request);
|
||||
request->ptr = nullptr;
|
||||
delete request;
|
||||
request = nullptr;
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::cancel() {
|
||||
context->removeRequest(request);
|
||||
request = nullptr;
|
||||
void HTTPRequest::cancel() {
|
||||
context->removeRequest(this);
|
||||
cancelled = true;
|
||||
|
||||
// Stop the backoff timer to avoid re-triggering this request.
|
||||
cancelTimer();
|
||||
timer.stop();
|
||||
|
||||
if (task) {
|
||||
[task cancel];
|
||||
@@ -223,29 +229,6 @@ void HTTPRequestImpl::cancel() {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -261,7 +244,7 @@ int64_t parseCacheControl(const char *value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::handleResult(NSData *data, NSURLResponse *res, NSError *error) {
|
||||
void HTTPRequest::handleResult(NSData *data, NSURLResponse *res, NSError *error) {
|
||||
if (error) {
|
||||
if ([error code] == NSURLErrorCancelled) {
|
||||
status = ResponseStatus::Canceled;
|
||||
@@ -361,73 +344,28 @@ void HTTPRequestImpl::handleResult(NSData *data, NSURLResponse *res, NSError *er
|
||||
response->message = "response class is not NSHTTPURLResponse";
|
||||
}
|
||||
|
||||
uv_async_send(async);
|
||||
async.send();
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::retry(uint64_t timeout) {
|
||||
void HTTPRequest::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);
|
||||
timer.stop();
|
||||
timer.start(timeout, 0, [this] { start(); });
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::retryImmediately() {
|
||||
void HTTPRequest::retry() {
|
||||
// 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) {
|
||||
if (strategy == PreemptImmediately) {
|
||||
// Triggers the timer upon the next event loop iteration.
|
||||
uv_timer_stop(timer);
|
||||
uv_timer_start(timer, restart, 0, 0);
|
||||
timer.stop();
|
||||
timer.start(0, 0, [this] { start(); });
|
||||
}
|
||||
}
|
||||
|
||||
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::Impl *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::shared_ptr<const Response> response) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
assert(!ptr);
|
||||
ptr = new HTTPRequestImpl(this, loop, response);
|
||||
}
|
||||
|
||||
void HTTPRequest::retryImmediately() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (ptr) {
|
||||
reinterpret_cast<HTTPRequestImpl *>(ptr)->retryImmediately();
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPRequest::cancel() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
delete this;
|
||||
std::unique_ptr<HTTPContext> HTTPContext::createContext(uv_loop_t* loop) {
|
||||
return util::make_unique<HTTPNSURLContext>(loop);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
13
platform/darwin/nsthread.mm
Normal file
13
platform/darwin/nsthread.mm
Normal file
@@ -0,0 +1,13 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
void makeThreadLowPriority() {
|
||||
[[NSThread currentThread] setThreadPriority:0.0];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <mbgl/storage/asset_request.hpp>
|
||||
#include <mbgl/storage/asset_context.hpp>
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/util/util.hpp>
|
||||
@@ -6,27 +7,19 @@
|
||||
|
||||
#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;
|
||||
#include <limits>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class AssetRequestImpl {
|
||||
class AssetRequest : public RequestBase {
|
||||
MBGL_STORE_THREAD(tid)
|
||||
|
||||
public:
|
||||
AssetRequestImpl(AssetRequest *request, uv_loop_t *loop);
|
||||
~AssetRequestImpl();
|
||||
AssetRequest(const Resource&, Callback, uv_loop_t*, const std::string& assetRoot);
|
||||
~AssetRequest();
|
||||
|
||||
void cancel() override;
|
||||
|
||||
static void fileOpened(uv_fs_t *req);
|
||||
static void fileStated(uv_fs_t *req);
|
||||
@@ -35,8 +28,7 @@ public:
|
||||
static void notifyError(uv_fs_t *req);
|
||||
static void cleanup(uv_fs_t *req);
|
||||
|
||||
|
||||
AssetRequest *request = nullptr;
|
||||
std::string assetRoot;
|
||||
bool canceled = false;
|
||||
uv_fs_t req;
|
||||
uv_file fd = -1;
|
||||
@@ -44,33 +36,40 @@ public:
|
||||
std::unique_ptr<Response> response;
|
||||
};
|
||||
|
||||
AssetRequestImpl::~AssetRequestImpl() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (request) {
|
||||
request->ptr = nullptr;
|
||||
class AssetFSContext : public AssetContext {
|
||||
RequestBase* createRequest(const Resource& resource,
|
||||
RequestBase::Callback callback,
|
||||
uv_loop_t* loop,
|
||||
const std::string& assetRoot) override {
|
||||
return new AssetRequest(resource, callback, loop, assetRoot);
|
||||
}
|
||||
};
|
||||
|
||||
AssetRequest::~AssetRequest() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
}
|
||||
|
||||
AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop) : request(request_) {
|
||||
AssetRequest::AssetRequest(const Resource& resource_, Callback callback_, uv_loop_t* loop, const std::string& assetRoot_)
|
||||
: RequestBase(resource_, callback_),
|
||||
assetRoot(assetRoot_) {
|
||||
req.data = this;
|
||||
|
||||
const auto &url = request->resource.url;
|
||||
const auto &url = 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 = request->source->assetRoot + "/" + url.substr(8);
|
||||
path = assetRoot + "/" + url.substr(8);
|
||||
}
|
||||
|
||||
uv_fs_open(loop, &req, path.c_str(), O_RDONLY, S_IRUSR, fileOpened);
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileOpened(uv_fs_t *req) {
|
||||
void AssetRequest::fileOpened(uv_fs_t *req) {
|
||||
assert(req->data);
|
||||
auto self = reinterpret_cast<AssetRequestImpl *>(req->data);
|
||||
auto self = reinterpret_cast<AssetRequest *>(req->data);
|
||||
MBGL_VERIFY_THREAD(self->tid);
|
||||
|
||||
if (req->result < 0) {
|
||||
@@ -93,9 +92,9 @@ void AssetRequestImpl::fileOpened(uv_fs_t *req) {
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileStated(uv_fs_t *req) {
|
||||
void AssetRequest::fileStated(uv_fs_t *req) {
|
||||
assert(req->data);
|
||||
auto self = reinterpret_cast<AssetRequestImpl *>(req->data);
|
||||
auto self = reinterpret_cast<AssetRequest *>(req->data);
|
||||
MBGL_VERIFY_THREAD(self->tid);
|
||||
|
||||
if (req->result != 0 || self->canceled) {
|
||||
@@ -121,9 +120,7 @@ void AssetRequestImpl::fileStated(uv_fs_t *req) {
|
||||
#else
|
||||
response->message = uv_strerror(UV_EFBIG);
|
||||
#endif
|
||||
assert(self->request);
|
||||
self->request->notify(std::move(response), FileCache::Hint::No);
|
||||
delete self->request;
|
||||
self->notify(std::move(response), FileCache::Hint::No);
|
||||
|
||||
uv_fs_req_cleanup(req);
|
||||
uv_fs_close(req->loop, req, self->fd, fileClosed);
|
||||
@@ -148,9 +145,9 @@ void AssetRequestImpl::fileStated(uv_fs_t *req) {
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileRead(uv_fs_t *req) {
|
||||
void AssetRequest::fileRead(uv_fs_t *req) {
|
||||
assert(req->data);
|
||||
auto self = reinterpret_cast<AssetRequestImpl *>(req->data);
|
||||
auto self = reinterpret_cast<AssetRequest *>(req->data);
|
||||
MBGL_VERIFY_THREAD(self->tid);
|
||||
|
||||
if (req->result < 0 || self->canceled) {
|
||||
@@ -160,18 +157,16 @@ void AssetRequestImpl::fileRead(uv_fs_t *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;
|
||||
self->notify(std::move(self->response), FileCache::Hint::No);
|
||||
}
|
||||
|
||||
uv_fs_req_cleanup(req);
|
||||
uv_fs_close(req->loop, req, self->fd, fileClosed);
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileClosed(uv_fs_t *req) {
|
||||
void AssetRequest::fileClosed(uv_fs_t *req) {
|
||||
assert(req->data);
|
||||
auto self = reinterpret_cast<AssetRequestImpl *>(req->data);
|
||||
auto self = reinterpret_cast<AssetRequest *>(req->data);
|
||||
MBGL_VERIFY_THREAD(self->tid);
|
||||
(void(self)); // Silence unused variable error in Release mode
|
||||
|
||||
@@ -182,70 +177,37 @@ void AssetRequestImpl::fileClosed(uv_fs_t *req) {
|
||||
cleanup(req);
|
||||
}
|
||||
|
||||
void AssetRequestImpl::notifyError(uv_fs_t *req) {
|
||||
void AssetRequest::notifyError(uv_fs_t *req) {
|
||||
assert(req->data);
|
||||
auto self = reinterpret_cast<AssetRequestImpl *>(req->data);
|
||||
auto self = reinterpret_cast<AssetRequest *>(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;
|
||||
self->notify(std::move(response), FileCache::Hint::No);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::cleanup(uv_fs_t *req) {
|
||||
void AssetRequest::cleanup(uv_fs_t *req) {
|
||||
assert(req->data);
|
||||
auto self = reinterpret_cast<AssetRequestImpl *>(req->data);
|
||||
auto self = reinterpret_cast<AssetRequest *>(req->data);
|
||||
MBGL_VERIFY_THREAD(self->tid);
|
||||
uv_fs_req_cleanup(req);
|
||||
delete self;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
AssetRequest::AssetRequest(DefaultFileSource::Impl *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::shared_ptr<const 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);
|
||||
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 *)&req);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
std::unique_ptr<AssetContext> AssetContext::createContext(uv_loop_t*) {
|
||||
return util::make_unique<AssetFSContext>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,45 +1,40 @@
|
||||
#include <mbgl/storage/asset_request.hpp>
|
||||
#include <mbgl/storage/thread_context.hpp>
|
||||
#include <mbgl/storage/asset_context.hpp>
|
||||
#include <mbgl/android/jni.hpp>
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/util/util.hpp>
|
||||
#include <mbgl/util/uv.hpp>
|
||||
|
||||
#include <uv.h>
|
||||
#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 <map>
|
||||
#include <cassert>
|
||||
#include <forward_list>
|
||||
|
||||
namespace algo = boost::algorithm;
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class AssetZipContext : public ThreadContext<AssetZipContext> {
|
||||
class AssetZipContext : public AssetContext {
|
||||
public:
|
||||
AssetZipContext(uv_loop_t *loop);
|
||||
~AssetZipContext();
|
||||
|
||||
RequestBase* createRequest(const Resource& resource,
|
||||
RequestBase::Callback callback,
|
||||
uv_loop_t* loop,
|
||||
const std::string& assetRoot) override;
|
||||
|
||||
uv_zip_t *getHandle(const std::string &path);
|
||||
void returnHandle(const std::string &path, uv_zip_t *zip);
|
||||
|
||||
private:
|
||||
// A list of resuable uv_zip handles to avoid creating and destroying them all the time.
|
||||
std::map<std::string, std::forward_list<uv_zip_t *>> handles;
|
||||
uv_loop_t *loop;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
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_) {
|
||||
AssetZipContext::AssetZipContext(uv_loop_t *loop_) : loop(loop_) {
|
||||
}
|
||||
|
||||
uv_zip_t *AssetZipContext::getHandle(const std::string &path) {
|
||||
@@ -70,20 +65,18 @@ AssetZipContext::~AssetZipContext() {
|
||||
handles.clear();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
class AssetRequestImpl {
|
||||
class AssetRequest : public RequestBase {
|
||||
MBGL_STORE_THREAD(tid)
|
||||
|
||||
public:
|
||||
AssetRequestImpl(AssetRequest *request, uv_loop_t *loop);
|
||||
~AssetRequestImpl();
|
||||
AssetRequest(AssetZipContext&, const Resource&, Callback, const std::string& assetRoot);
|
||||
~AssetRequest();
|
||||
|
||||
void cancel();
|
||||
void cancel() override;
|
||||
|
||||
private:
|
||||
AssetZipContext &context;
|
||||
AssetRequest *request = nullptr;
|
||||
bool cancelled = false;
|
||||
const std::string root;
|
||||
const std::string path;
|
||||
std::unique_ptr<Response> response;
|
||||
@@ -101,21 +94,18 @@ private:
|
||||
void notifyError(const char *message);
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
AssetRequestImpl::~AssetRequestImpl() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (request) {
|
||||
request->ptr = nullptr;
|
||||
}
|
||||
RequestBase* AssetZipContext::createRequest(const Resource& resource,
|
||||
RequestBase::Callback callback,
|
||||
uv_loop_t*,
|
||||
const std::string& assetRoot) {
|
||||
return new AssetRequest(*this, resource, callback, assetRoot);
|
||||
}
|
||||
|
||||
AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop)
|
||||
: context(*AssetZipContext::Get(loop)),
|
||||
request(request_),
|
||||
root(request->source->assetRoot),
|
||||
path(std::string { "assets/" } + request->resource.url.substr(8)) {
|
||||
AssetRequest::AssetRequest(AssetZipContext& context_, const Resource& resource_, Callback callback_, const std::string& assetRoot_)
|
||||
: RequestBase(resource_, callback_),
|
||||
context(context_),
|
||||
root(assetRoot_),
|
||||
path(std::string { "assets/" } + resource.url.substr(8)) {
|
||||
auto zip = context.getHandle(root);
|
||||
if (zip) {
|
||||
archiveOpened(zip);
|
||||
@@ -124,18 +114,19 @@ AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop)
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::openZipArchive() {
|
||||
AssetRequest::~AssetRequest() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
}
|
||||
|
||||
void AssetRequest::openZipArchive() {
|
||||
uv_fs_t *req = new uv_fs_t();
|
||||
req->data = this;
|
||||
|
||||
assert(request);
|
||||
assert(request->source);
|
||||
|
||||
// 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, root.c_str(), O_RDONLY, S_IRUSR, [](uv_fs_t *fsReq) {
|
||||
if (fsReq->result < 0) {
|
||||
auto impl = reinterpret_cast<AssetRequestImpl *>(fsReq->data);
|
||||
auto impl = reinterpret_cast<AssetRequest *>(fsReq->data);
|
||||
impl->notifyError(uv::getFileRequestError(fsReq));
|
||||
delete impl;
|
||||
} else {
|
||||
@@ -143,7 +134,7 @@ void AssetRequestImpl::openZipArchive() {
|
||||
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);
|
||||
auto impl = reinterpret_cast<AssetRequest *>(openZip->data);
|
||||
if (openZip->result < 0) {
|
||||
impl->notifyError(openZip->message);
|
||||
delete openZip;
|
||||
@@ -163,20 +154,20 @@ void AssetRequestImpl::openZipArchive() {
|
||||
#define INVOKE_MEMBER(name) \
|
||||
[](uv_zip_t *zip_) { \
|
||||
assert(zip_->data); \
|
||||
reinterpret_cast<AssetRequestImpl *>(zip_->data)->name(zip_); \
|
||||
reinterpret_cast<AssetRequest *>(zip_->data)->name(zip_); \
|
||||
}
|
||||
|
||||
void AssetRequestImpl::archiveOpened(uv_zip_t *zip) {
|
||||
void AssetRequest::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) {
|
||||
void AssetRequest::fileStated(uv_zip_t *zip) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (!request || zip->result < 0) {
|
||||
if (cancelled || zip->result < 0) {
|
||||
// Stat failed, probably because the file doesn't exist.
|
||||
if (zip->result < 0) {
|
||||
notifyError(zip->message);
|
||||
@@ -206,14 +197,14 @@ void AssetRequestImpl::fileStated(uv_zip_t *zip) {
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileOpened(uv_zip_t *zip) {
|
||||
void AssetRequest::fileOpened(uv_zip_t *zip) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (zip->result < 0) {
|
||||
// Opening failed.
|
||||
notifyError(zip->message);
|
||||
cleanup(zip);
|
||||
} else if (!request) {
|
||||
} else if (cancelled) {
|
||||
// The request was canceled. Close the file again.
|
||||
uv_zip_fclose(context.loop, zip, zip->file, INVOKE_MEMBER(fileClosed));
|
||||
} else {
|
||||
@@ -221,23 +212,21 @@ void AssetRequestImpl::fileOpened(uv_zip_t *zip) {
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileRead(uv_zip_t *zip) {
|
||||
void AssetRequest::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) {
|
||||
} else if (!cancelled) {
|
||||
response->status = Response::Successful;
|
||||
request->notify(std::move(response), FileCache::Hint::No);
|
||||
delete request;
|
||||
assert(request == nullptr);
|
||||
notify(std::move(response), FileCache::Hint::No);
|
||||
}
|
||||
|
||||
uv_zip_fclose(context.loop, zip, zip->file, INVOKE_MEMBER(fileClosed));
|
||||
}
|
||||
|
||||
void AssetRequestImpl::fileClosed(uv_zip_t *zip) {
|
||||
void AssetRequest::fileClosed(uv_zip_t *zip) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (zip->result < 0) {
|
||||
@@ -247,66 +236,32 @@ void AssetRequestImpl::fileClosed(uv_zip_t *zip) {
|
||||
cleanup(zip);
|
||||
}
|
||||
|
||||
void AssetRequestImpl::cleanup(uv_zip_t *zip) {
|
||||
void AssetRequest::cleanup(uv_zip_t *zip) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
context.returnHandle(root, zip);
|
||||
delete this;
|
||||
}
|
||||
|
||||
void AssetRequestImpl::notifyError(const char *message) {
|
||||
void AssetRequest::notifyError(const char *message) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (request) {
|
||||
if (!cancelled) {
|
||||
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);
|
||||
notify(std::move(response), FileCache::Hint::No);
|
||||
} else {
|
||||
// The request was already canceled and deleted.
|
||||
}
|
||||
}
|
||||
|
||||
void AssetRequestImpl::cancel() {
|
||||
request = nullptr;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
AssetRequest::AssetRequest(DefaultFileSource::Impl *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::shared_ptr<const 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);
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
if (ptr) {
|
||||
reinterpret_cast<AssetRequestImpl *>(ptr)->cancel();
|
||||
}
|
||||
|
||||
delete this;
|
||||
std::unique_ptr<AssetContext> AssetContext::createContext(uv_loop_t* loop) {
|
||||
return util::make_unique<AssetZipContext>(loop);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,27 +1,22 @@
|
||||
#include <mbgl/platform/default/glfw_view.hpp>
|
||||
#include <mbgl/platform/gl.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/util/gl_helper.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <pthread.h>
|
||||
|
||||
pthread_once_t loadGLExtensions = PTHREAD_ONCE_INIT;
|
||||
|
||||
GLFWView::GLFWView(bool fullscreen_) : fullscreen(fullscreen_) {
|
||||
#ifdef NVIDIA
|
||||
glDiscardFramebufferEXT = reinterpret_cast<PFNGLDISCARDFRAMEBUFFEREXTPROC>(glfwGetProcAddress("glDiscardFramebufferEXT"));
|
||||
#endif
|
||||
}
|
||||
|
||||
GLFWView::~GLFWView() {
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
void glfwError(int error, const char *description) {
|
||||
mbgl::Log::Error(mbgl::Event::OpenGL, "GLFW error (%i): %s", error, description);
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void GLFWView::initialize(mbgl::Map *map_) {
|
||||
View::initialize(map_);
|
||||
GLFWView::GLFWView(bool fullscreen_) : fullscreen(fullscreen_) {
|
||||
#ifdef NVIDIA
|
||||
glDiscardFramebufferEXT = reinterpret_cast<PFNGLDISCARDFRAMEBUFFEREXTPROC>(glfwGetProcAddress("glDiscardFramebufferEXT"));
|
||||
#endif
|
||||
|
||||
glfwSetErrorCallback(glfwError);
|
||||
|
||||
@@ -63,10 +58,6 @@ void GLFWView::initialize(mbgl::Map *map_) {
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
int width, height;
|
||||
glfwGetWindowSize(window, &width, &height);
|
||||
onResize(window, width, height);
|
||||
|
||||
glfwSetCursorPosCallback(window, onMouseMove);
|
||||
glfwSetMouseButtonCallback(window, onMouseClick);
|
||||
glfwSetWindowSizeCallback(window, onResize);
|
||||
@@ -160,6 +151,19 @@ void GLFWView::initialize(mbgl::Map *map_) {
|
||||
glfwMakeContextCurrent(nullptr);
|
||||
}
|
||||
|
||||
GLFWView::~GLFWView() {
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
void GLFWView::initialize(mbgl::Map *map_) {
|
||||
View::initialize(map_);
|
||||
|
||||
int width, height;
|
||||
glfwGetWindowSize(window, &width, &height);
|
||||
onResize(window, width, height);
|
||||
}
|
||||
|
||||
void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, int mods) {
|
||||
GLFWView *view = reinterpret_cast<GLFWView *>(glfwGetWindowUserPointer(window));
|
||||
|
||||
@@ -221,7 +225,7 @@ void GLFWView::onResize(GLFWwindow *window, int width, int height ) {
|
||||
int fbWidth, fbHeight;
|
||||
glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
|
||||
|
||||
view->resize(width, height, static_cast<float>(fbWidth) / static_cast<float>(width), fbWidth, fbHeight);
|
||||
view->map->resize(width, height, static_cast<float>(fbWidth) / static_cast<float>(width));
|
||||
}
|
||||
|
||||
void GLFWView::onMouseClick(GLFWwindow *window, int button, int action, int modifiers) {
|
||||
@@ -264,21 +268,10 @@ void GLFWView::onMouseMove(GLFWwindow *window, double x, double y) {
|
||||
view->lastY = y;
|
||||
}
|
||||
|
||||
int GLFWView::run() {
|
||||
map->start();
|
||||
|
||||
void GLFWView::run() {
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
glfwWaitEvents();
|
||||
}
|
||||
|
||||
map->stop([]() {
|
||||
glfwWaitEvents();
|
||||
});
|
||||
|
||||
// Terminate here to save binary shaders
|
||||
map->terminate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GLFWView::activate() {
|
||||
@@ -293,9 +286,8 @@ void GLFWView::notify() {
|
||||
glfwPostEmptyEvent();
|
||||
}
|
||||
|
||||
void GLFWView::invalidate() {
|
||||
assert(map);
|
||||
map->render();
|
||||
void GLFWView::invalidate(std::function<void()> render) {
|
||||
render();
|
||||
glfwSwapBuffers(window);
|
||||
fps();
|
||||
}
|
||||
@@ -342,15 +334,20 @@ void showDebugImage(std::string name, const char *data, size_t width, size_t hei
|
||||
glfwGetFramebufferSize(debugWindow, &fbWidth, &fbHeight);
|
||||
float scale = static_cast<float>(fbWidth) / static_cast<float>(width);
|
||||
|
||||
MBGL_CHECK_ERROR(glPixelZoom(scale, -scale));
|
||||
MBGL_CHECK_ERROR(glRasterPos2f(-1.0f, 1.0f));
|
||||
MBGL_CHECK_ERROR(glDrawPixels(width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, data));
|
||||
{
|
||||
gl::PreservePixelZoom pixelZoom;
|
||||
gl::PreserveRasterPos rasterPos;
|
||||
|
||||
MBGL_CHECK_ERROR(glPixelZoom(scale, -scale));
|
||||
MBGL_CHECK_ERROR(glRasterPos2f(-1.0f, 1.0f));
|
||||
MBGL_CHECK_ERROR(glDrawPixels(width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, data));
|
||||
}
|
||||
|
||||
glfwSwapBuffers(debugWindow);
|
||||
|
||||
glfwMakeContextCurrent(currentWindow);
|
||||
}
|
||||
|
||||
|
||||
void showColorDebugImage(std::string name, const char *data, size_t logicalWidth, size_t logicalHeight, size_t width, size_t height) {
|
||||
glfwInit();
|
||||
|
||||
@@ -374,14 +371,22 @@ void showColorDebugImage(std::string name, const char *data, size_t logicalWidth
|
||||
float xScale = static_cast<float>(fbWidth) / static_cast<float>(width);
|
||||
float yScale = static_cast<float>(fbHeight) / static_cast<float>(height);
|
||||
|
||||
MBGL_CHECK_ERROR(glClearColor(0.8, 0.8, 0.8, 1));
|
||||
MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT));
|
||||
MBGL_CHECK_ERROR(glEnable(GL_BLEND));
|
||||
MBGL_CHECK_ERROR(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
{
|
||||
gl::PreserveClearColor clearColor;
|
||||
gl::PreserveBlend blend;
|
||||
gl::PreserveBlendFunc blendFunc;
|
||||
gl::PreservePixelZoom pixelZoom;
|
||||
gl::PreserveRasterPos rasterPos;
|
||||
|
||||
MBGL_CHECK_ERROR(glClearColor(0.8, 0.8, 0.8, 1));
|
||||
MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT));
|
||||
MBGL_CHECK_ERROR(glEnable(GL_BLEND));
|
||||
MBGL_CHECK_ERROR(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
MBGL_CHECK_ERROR(glPixelZoom(xScale, -yScale));
|
||||
MBGL_CHECK_ERROR(glRasterPos2f(-1.0f, 1.0f));
|
||||
MBGL_CHECK_ERROR(glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, data));
|
||||
}
|
||||
|
||||
MBGL_CHECK_ERROR(glPixelZoom(xScale, -yScale));
|
||||
MBGL_CHECK_ERROR(glRasterPos2f(-1.0f, 1.0f));
|
||||
MBGL_CHECK_ERROR(glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, data));
|
||||
glfwSwapBuffers(debugWindow);
|
||||
|
||||
glfwMakeContextCurrent(currentWindow);
|
||||
|
||||
@@ -41,7 +41,9 @@ namespace mbgl {
|
||||
|
||||
HeadlessView::HeadlessView(uint16_t width, uint16_t height, float pixelRatio)
|
||||
: display(std::make_shared<HeadlessDisplay>()) {
|
||||
activate();
|
||||
resize(width, height, pixelRatio);
|
||||
deactivate();
|
||||
}
|
||||
|
||||
HeadlessView::HeadlessView(std::shared_ptr<HeadlessDisplay> display_,
|
||||
@@ -49,7 +51,9 @@ HeadlessView::HeadlessView(std::shared_ptr<HeadlessDisplay> display_,
|
||||
uint16_t height,
|
||||
float pixelRatio)
|
||||
: display(display_) {
|
||||
activate();
|
||||
resize(width, height, pixelRatio);
|
||||
deactivate();
|
||||
}
|
||||
|
||||
void HeadlessView::loadExtensions() {
|
||||
@@ -150,30 +154,17 @@ bool HeadlessView::isActive() {
|
||||
return std::this_thread::get_id() == thread;
|
||||
}
|
||||
|
||||
void HeadlessView::resize(const uint16_t width, const uint16_t height, const float pixelRatio) {
|
||||
std::lock_guard<std::mutex> lock(prospectiveMutex);
|
||||
prospective = { width, height, pixelRatio };
|
||||
}
|
||||
|
||||
HeadlessView::Dimensions::Dimensions(uint16_t width_, uint16_t height_, float pixelRatio_)
|
||||
: width(width_), height(height_), pixelRatio(pixelRatio_) {
|
||||
}
|
||||
|
||||
void HeadlessView::discard() {
|
||||
assert(isActive());
|
||||
|
||||
{ // Obtain the new values.
|
||||
std::lock_guard<std::mutex> lock(prospectiveMutex);
|
||||
if (current.pixelWidth() == prospective.pixelWidth() && current.pixelHeight() == prospective.pixelHeight()) {
|
||||
return;
|
||||
}
|
||||
current = prospective;
|
||||
}
|
||||
void HeadlessView::resize(const uint16_t width, const uint16_t height, const float pixelRatio) {
|
||||
dimensions = { width, height, pixelRatio };
|
||||
|
||||
clearBuffers();
|
||||
|
||||
const unsigned int w = current.width * current.pixelRatio;
|
||||
const unsigned int h = current.height * current.pixelRatio;
|
||||
const unsigned int w = dimensions.width * dimensions.pixelRatio;
|
||||
const unsigned int h = dimensions.height * dimensions.pixelRatio;
|
||||
|
||||
// Create depth/stencil buffer
|
||||
MBGL_CHECK_ERROR(glGenRenderbuffersEXT(1, &fboDepthStencil));
|
||||
@@ -208,15 +199,13 @@ void HeadlessView::discard() {
|
||||
}
|
||||
throw std::runtime_error(error.str());
|
||||
}
|
||||
|
||||
View::resize(current.width, current.height, current.pixelRatio, w, h);
|
||||
}
|
||||
|
||||
std::unique_ptr<StillImage> HeadlessView::readStillImage() {
|
||||
assert(isActive());
|
||||
|
||||
const unsigned int w = current.pixelWidth();
|
||||
const unsigned int h = current.pixelHeight();
|
||||
const unsigned int w = dimensions.pixelWidth();
|
||||
const unsigned int h = dimensions.pixelHeight();
|
||||
|
||||
auto image = util::make_unique<StillImage>();
|
||||
image->width = w;
|
||||
@@ -305,7 +294,6 @@ void HeadlessView::activate() {
|
||||
#endif
|
||||
|
||||
loadExtensions();
|
||||
discard();
|
||||
}
|
||||
|
||||
void HeadlessView::deactivate() {
|
||||
@@ -328,9 +316,8 @@ void HeadlessView::deactivate() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void HeadlessView::invalidate() {
|
||||
assert(map);
|
||||
map->render();
|
||||
void HeadlessView::invalidate(std::function<void()> render) {
|
||||
render();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#include <mbgl/storage/http_request.hpp>
|
||||
#include <mbgl/storage/http_context.hpp>
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
|
||||
#include <mbgl/util/time.hpp>
|
||||
#include <mbgl/util/util.hpp>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
@@ -53,14 +54,20 @@ enum class ResponseStatus : int8_t {
|
||||
NotModified,
|
||||
};
|
||||
|
||||
class HTTPRequestImpl;
|
||||
class HTTPRequest;
|
||||
|
||||
class HTTPCURLContext : public HTTPContext<HTTPCURLContext> {
|
||||
class HTTPCURLContext : public HTTPContext {
|
||||
MBGL_STORE_THREAD(tid)
|
||||
|
||||
public:
|
||||
HTTPCURLContext(uv_loop_t *loop);
|
||||
~HTTPCURLContext();
|
||||
|
||||
RequestBase* createRequest(const Resource&,
|
||||
RequestBase::Callback,
|
||||
uv_loop_t*,
|
||||
std::shared_ptr<const Response>) override;
|
||||
|
||||
static int handleSocket(CURL *handle, curl_socket_t s, int action, void *userp, void *socketp);
|
||||
static void perform(uv_poll_t *req, int status, int events);
|
||||
static int startTimeout(CURLM *multi, long timeout_ms, void *userp);
|
||||
@@ -74,7 +81,8 @@ public:
|
||||
void returnHandle(CURL *handle);
|
||||
void checkMultiInfo();
|
||||
|
||||
public:
|
||||
uv_loop_t *loop = nullptr;
|
||||
|
||||
// Used as the CURL timer function to periodically check for socket updates.
|
||||
uv_timer_t *timeout = nullptr;
|
||||
|
||||
@@ -90,17 +98,21 @@ public:
|
||||
std::queue<CURL *> handles;
|
||||
};
|
||||
|
||||
|
||||
class HTTPRequestImpl {
|
||||
class HTTPRequest : public RequestBase {
|
||||
MBGL_STORE_THREAD(tid)
|
||||
|
||||
public:
|
||||
HTTPRequestImpl(HTTPRequest *request, uv_loop_t *loop, std::shared_ptr<const Response> response);
|
||||
~HTTPRequestImpl();
|
||||
HTTPRequest(HTTPCURLContext*,
|
||||
const Resource&,
|
||||
Callback,
|
||||
uv_loop_t*,
|
||||
std::shared_ptr<const Response>);
|
||||
~HTTPRequest();
|
||||
|
||||
void cancel() override;
|
||||
void retry() override;
|
||||
|
||||
void handleResult(CURLcode code);
|
||||
void abandon();
|
||||
void retryImmediately();
|
||||
|
||||
private:
|
||||
static size_t headerCallback(char *const buffer, const size_t size, const size_t nmemb, void *userp);
|
||||
@@ -115,9 +127,8 @@ private:
|
||||
void finish(ResponseStatus status);
|
||||
void start();
|
||||
|
||||
private:
|
||||
HTTPCURLContext *context = nullptr;
|
||||
HTTPRequest *request = nullptr;
|
||||
bool cancelled = false;
|
||||
|
||||
// Will store the current response.
|
||||
std::unique_ptr<Response> response;
|
||||
@@ -175,10 +186,9 @@ private:
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
template<> pthread_key_t ThreadContext<HTTPCURLContext>::key{};
|
||||
template<> pthread_once_t ThreadContext<HTTPCURLContext>::once = PTHREAD_ONCE_INIT;
|
||||
|
||||
HTTPCURLContext::HTTPCURLContext(uv_loop_t *loop_) : HTTPContext(loop_) {
|
||||
HTTPCURLContext::HTTPCURLContext(uv_loop_t *loop_)
|
||||
: HTTPContext(loop_),
|
||||
loop(loop_) {
|
||||
if (curl_global_init(CURL_GLOBAL_ALL)) {
|
||||
throw std::runtime_error("Could not init cURL");
|
||||
}
|
||||
@@ -197,6 +207,11 @@ HTTPCURLContext::HTTPCURLContext(uv_loop_t *loop_) : HTTPContext(loop_) {
|
||||
}
|
||||
|
||||
HTTPCURLContext::~HTTPCURLContext() {
|
||||
while (!handles.empty()) {
|
||||
curl_easy_cleanup(handles.front());
|
||||
handles.pop();
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi);
|
||||
multi = nullptr;
|
||||
|
||||
@@ -207,6 +222,13 @@ HTTPCURLContext::~HTTPCURLContext() {
|
||||
uv::close(timeout);
|
||||
}
|
||||
|
||||
RequestBase* HTTPCURLContext::createRequest(const Resource& resource,
|
||||
RequestBase::Callback callback,
|
||||
uv_loop_t* loop_,
|
||||
std::shared_ptr<const Response> response) {
|
||||
return new HTTPRequest(this, resource, callback, loop_, response);
|
||||
}
|
||||
|
||||
CURL *HTTPCURLContext::getHandle() {
|
||||
if (!handles.empty()) {
|
||||
auto handle = handles.front();
|
||||
@@ -230,7 +252,7 @@ void HTTPCURLContext::checkMultiInfo() {
|
||||
while ((message = curl_multi_info_read(multi, &pending))) {
|
||||
switch (message->msg) {
|
||||
case CURLMSG_DONE: {
|
||||
HTTPRequestImpl *baton = nullptr;
|
||||
HTTPRequest *baton = nullptr;
|
||||
curl_easy_getinfo(message->easy_handle, CURLINFO_PRIVATE, (char *)&baton);
|
||||
assert(baton);
|
||||
baton->handleResult(message->data.result);
|
||||
@@ -425,13 +447,12 @@ static CURLcode sslctx_function(CURL * /* curl */, void *sslctx, void * /* parm
|
||||
}
|
||||
#endif
|
||||
|
||||
HTTPRequestImpl::HTTPRequestImpl(HTTPRequest *request_, uv_loop_t *loop, std::shared_ptr<const Response> response_)
|
||||
: context(HTTPCURLContext::Get(loop)),
|
||||
request(request_),
|
||||
HTTPRequest::HTTPRequest(HTTPCURLContext* context_, const Resource& resource_, Callback callback_, uv_loop_t*, std::shared_ptr<const Response> response_)
|
||||
: RequestBase(resource_, callback_),
|
||||
context(context_),
|
||||
existingResponse(response_),
|
||||
handle(context->getHandle()) {
|
||||
assert(request);
|
||||
context->addRequest(request);
|
||||
context->addRequest(this);
|
||||
|
||||
// Zero out the error buffer.
|
||||
memset(error, 0, sizeof(error));
|
||||
@@ -462,7 +483,7 @@ HTTPRequestImpl::HTTPRequestImpl(HTTPRequest *request_, uv_loop_t *loop, std::sh
|
||||
handleError(curl_easy_setopt(handle, CURLOPT_CAINFO, "ca-bundle.crt"));
|
||||
#endif
|
||||
handleError(curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1));
|
||||
handleError(curl_easy_setopt(handle, CURLOPT_URL, request->resource.url.c_str()));
|
||||
handleError(curl_easy_setopt(handle, CURLOPT_URL, resource.url.c_str()));
|
||||
handleError(curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, writeCallback));
|
||||
handleError(curl_easy_setopt(handle, CURLOPT_WRITEDATA, this));
|
||||
handleError(curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, headerCallback));
|
||||
@@ -474,28 +495,10 @@ HTTPRequestImpl::HTTPRequestImpl(HTTPRequest *request_, uv_loop_t *loop, std::sh
|
||||
start();
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::abandon() {
|
||||
if (request) {
|
||||
context->removeRequest(request);
|
||||
request = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::start() {
|
||||
// Count up the attempts.
|
||||
attempts++;
|
||||
|
||||
// Start requesting the information.
|
||||
handleError(curl_multi_add_handle(context->multi, handle));
|
||||
}
|
||||
|
||||
HTTPRequestImpl::~HTTPRequestImpl() {
|
||||
HTTPRequest::~HTTPRequest() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (request) {
|
||||
context->removeRequest(request);
|
||||
request->ptr = nullptr;
|
||||
}
|
||||
context->removeRequest(this);
|
||||
|
||||
handleError(curl_multi_remove_handle(context->multi, handle));
|
||||
context->returnHandle(handle);
|
||||
@@ -514,11 +517,23 @@ HTTPRequestImpl::~HTTPRequestImpl() {
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPRequest::cancel() {
|
||||
delete this;
|
||||
}
|
||||
|
||||
void HTTPRequest::start() {
|
||||
// Count up the attempts.
|
||||
attempts++;
|
||||
|
||||
// Start requesting the information.
|
||||
handleError(curl_multi_add_handle(context->multi, handle));
|
||||
}
|
||||
|
||||
// This function is called when we have new data for a request. We just append it to the string
|
||||
// containing the previous data.
|
||||
size_t HTTPRequestImpl::writeCallback(void *const contents, const size_t size, const size_t nmemb, void *userp) {
|
||||
size_t HTTPRequest::writeCallback(void *const contents, const size_t size, const size_t nmemb, void *userp) {
|
||||
assert(userp);
|
||||
auto impl = reinterpret_cast<HTTPRequestImpl *>(userp);
|
||||
auto impl = reinterpret_cast<HTTPRequest *>(userp);
|
||||
MBGL_VERIFY_THREAD(impl->tid);
|
||||
|
||||
if (!impl->response) {
|
||||
@@ -560,9 +575,9 @@ int64_t parseCacheControl(const char *value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t HTTPRequestImpl::headerCallback(char *const buffer, const size_t size, const size_t nmemb, void *userp) {
|
||||
size_t HTTPRequest::headerCallback(char *const buffer, const size_t size, const size_t nmemb, void *userp) {
|
||||
assert(userp);
|
||||
auto baton = reinterpret_cast<HTTPRequestImpl *>(userp);
|
||||
auto baton = reinterpret_cast<HTTPRequest *>(userp);
|
||||
MBGL_VERIFY_THREAD(baton->tid);
|
||||
|
||||
if (!baton->response) {
|
||||
@@ -589,8 +604,7 @@ size_t HTTPRequestImpl::headerCallback(char *const buffer, const size_t size, co
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
void HTTPRequestImpl::retry(uint64_t timeout) {
|
||||
void HTTPRequest::retry(uint64_t timeout) {
|
||||
handleError(curl_multi_remove_handle(context->multi, handle));
|
||||
|
||||
response.reset();
|
||||
@@ -602,7 +616,7 @@ void HTTPRequestImpl::retry(uint64_t timeout) {
|
||||
uv_timer_start(timer, restart, timeout, 0);
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::retryImmediately() {
|
||||
void HTTPRequest::retry() {
|
||||
// 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) {
|
||||
@@ -613,12 +627,12 @@ void HTTPRequestImpl::retryImmediately() {
|
||||
}
|
||||
|
||||
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
|
||||
void HTTPRequestImpl::restart(uv_timer_t *timer, int) {
|
||||
void HTTPRequest::restart(uv_timer_t *timer, int) {
|
||||
#else
|
||||
void HTTPRequestImpl::restart(uv_timer_t *timer) {
|
||||
void HTTPRequest::restart(uv_timer_t *timer) {
|
||||
#endif
|
||||
// Restart the request.
|
||||
auto baton = reinterpret_cast<HTTPRequestImpl *>(timer->data);
|
||||
auto baton = reinterpret_cast<HTTPRequest *>(timer->data);
|
||||
|
||||
// Get rid of the timer.
|
||||
baton->timer = nullptr;
|
||||
@@ -627,7 +641,7 @@ void HTTPRequestImpl::restart(uv_timer_t *timer) {
|
||||
baton->start();
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::finish(ResponseStatus status) {
|
||||
void HTTPRequest::finish(ResponseStatus status) {
|
||||
if (status == ResponseStatus::TemporaryError && attempts < maxAttempts) {
|
||||
strategy = ExponentialBackoff;
|
||||
return retry((1 << (attempts - 1)) * 1000);
|
||||
@@ -640,19 +654,18 @@ void HTTPRequestImpl::finish(ResponseStatus status) {
|
||||
|
||||
// Actually return the response.
|
||||
if (status == ResponseStatus::NotModified) {
|
||||
request->notify(std::move(response), FileCache::Hint::Refresh);
|
||||
notify(std::move(response), FileCache::Hint::Refresh);
|
||||
} else {
|
||||
request->notify(std::move(response), FileCache::Hint::Full);
|
||||
notify(std::move(response), FileCache::Hint::Full);
|
||||
}
|
||||
|
||||
delete request;
|
||||
delete this;
|
||||
}
|
||||
|
||||
void HTTPRequestImpl::handleResult(CURLcode code) {
|
||||
void HTTPRequest::handleResult(CURLcode code) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (!request) {
|
||||
if (cancelled) {
|
||||
// In this case, it doesn't make sense to even process the response even further since
|
||||
// the request was canceled anyway.
|
||||
delete this;
|
||||
@@ -720,44 +733,8 @@ void HTTPRequestImpl::handleResult(CURLcode code) {
|
||||
throw std::runtime_error("Response hasn't been handled");
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
HTTPRequest::HTTPRequest(DefaultFileSource::Impl *source_, const Resource &resource_)
|
||||
: SharedRequestBase(source_, resource_) {
|
||||
}
|
||||
|
||||
HTTPRequest::~HTTPRequest() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (ptr) {
|
||||
reinterpret_cast<HTTPRequestImpl *>(ptr)->abandon();
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPRequest::start(uv_loop_t *loop, std::shared_ptr<const Response> response) {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
assert(!ptr);
|
||||
ptr = new HTTPRequestImpl(this, loop, response);
|
||||
}
|
||||
|
||||
void HTTPRequest::retryImmediately() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (ptr) {
|
||||
reinterpret_cast<HTTPRequestImpl *>(ptr)->retryImmediately();
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPRequest::cancel() {
|
||||
MBGL_VERIFY_THREAD(tid);
|
||||
|
||||
if (ptr) {
|
||||
delete reinterpret_cast<HTTPRequestImpl *>(ptr);
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
delete this;
|
||||
std::unique_ptr<HTTPContext> HTTPContext::createContext(uv_loop_t* loop) {
|
||||
return util::make_unique<HTTPCURLContext>(loop);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -62,12 +62,12 @@ std::string unifyMapboxURLs(const std::string &url) {
|
||||
using namespace mapbox::sqlite;
|
||||
|
||||
SQLiteCache::SQLiteCache(const std::string& path_)
|
||||
: thread(util::make_unique<util::Thread<Impl>>("SQLite Cache", path_)) {
|
||||
: thread(util::make_unique<util::Thread<Impl>>("SQLite Cache", util::ThreadPriority::Low, path_)) {
|
||||
}
|
||||
|
||||
SQLiteCache::~SQLiteCache() = default;
|
||||
|
||||
SQLiteCache::Impl::Impl(const std::string& path_)
|
||||
SQLiteCache::Impl::Impl(uv_loop_t*, const std::string& path_)
|
||||
: path(path_) {
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ void SQLiteCache::get(const Resource &resource, Callback callback) {
|
||||
// Will try to load the URL from the SQLite database and call the callback when done.
|
||||
// Note that the callback is probably going to invoked from another thread, so the caller
|
||||
// must make sure that it can run in that thread.
|
||||
thread->invokeWithResult(&Impl::get, callback, resource);
|
||||
thread->invokeWithResult(&Impl::get, std::move(callback), resource);
|
||||
}
|
||||
|
||||
std::unique_ptr<Response> SQLiteCache::Impl::get(const Resource &resource) {
|
||||
@@ -183,9 +183,9 @@ void SQLiteCache::put(const Resource &resource, std::shared_ptr<const Response>
|
||||
// storing a new response or updating the currently stored response, potentially setting a new
|
||||
// expiry date.
|
||||
if (hint == Hint::Full) {
|
||||
thread->invoke(&Impl::put, resource, std::move(response));
|
||||
thread->invoke(&Impl::put, resource, response);
|
||||
} else if (hint == Hint::Refresh) {
|
||||
thread->invoke(&Impl::refresh, resource, int64_t(response->expires));
|
||||
thread->invoke(&Impl::refresh, resource, response->expires);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include <mbgl/storage/sqlite_cache.hpp>
|
||||
|
||||
typedef struct uv_loop_s uv_loop_t;
|
||||
|
||||
namespace mapbox {
|
||||
namespace sqlite {
|
||||
class Database;
|
||||
@@ -14,7 +16,7 @@ namespace mbgl {
|
||||
|
||||
class SQLiteCache::Impl {
|
||||
public:
|
||||
Impl(const std::string &path = ":memory:");
|
||||
Impl(uv_loop_t*, const std::string &path = ":memory:");
|
||||
~Impl();
|
||||
|
||||
std::unique_ptr<Response> get(const Resource&);
|
||||
|
||||
11
platform/default/thread.cpp
Normal file
11
platform/default/thread.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
void makeThreadLowPriority() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
10
platform/ios/MGLFileCache.h
Normal file
10
platform/ios/MGLFileCache.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <mbgl/storage/sqlite_cache.hpp>
|
||||
|
||||
@interface MGLFileCache : NSObject
|
||||
|
||||
+ (mbgl::SQLiteCache *)obtainSharedCacheWithObject:(NSObject *)object;
|
||||
+ (void)releaseSharedCacheForObject:(NSObject *)object;
|
||||
|
||||
@end
|
||||
83
platform/ios/MGLFileCache.mm
Normal file
83
platform/ios/MGLFileCache.mm
Normal file
@@ -0,0 +1,83 @@
|
||||
#import "MGLFileCache.h"
|
||||
|
||||
@interface MGLFileCache ()
|
||||
|
||||
@property (nonatomic) MGLFileCache *sharedInstance;
|
||||
@property (nonatomic) mbgl::SQLiteCache *sharedCache;
|
||||
@property (nonatomic) NSHashTable *retainers;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MGLFileCache
|
||||
|
||||
const std::string &defaultCacheDatabasePath() {
|
||||
static const std::string path = []() -> std::string {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
if ([paths count] == 0) {
|
||||
// Disable the cache if we don't have a location to write.
|
||||
return "";
|
||||
}
|
||||
|
||||
NSString *libraryDirectory = [paths objectAtIndex:0];
|
||||
return [[libraryDirectory stringByAppendingPathComponent:@"cache.db"] UTF8String];
|
||||
}();
|
||||
return path;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_retainers = [NSHashTable weakObjectsHashTable];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static dispatch_once_t onceToken;
|
||||
static MGLFileCache *_sharedInstance;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_sharedInstance = [[self alloc] init];
|
||||
});
|
||||
return _sharedInstance;
|
||||
}
|
||||
|
||||
- (void)teardown {
|
||||
if (self.sharedCache) {
|
||||
delete self.sharedCache;
|
||||
self.sharedCache = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self.retainers removeAllObjects];
|
||||
[self teardown];
|
||||
}
|
||||
|
||||
+ (mbgl::SQLiteCache *)obtainSharedCacheWithObject:(NSObject *)object {
|
||||
return [[MGLFileCache sharedInstance] obtainSharedCacheWithObject:object];
|
||||
}
|
||||
|
||||
- (mbgl::SQLiteCache *)obtainSharedCacheWithObject:(NSObject *)object {
|
||||
assert([[NSThread currentThread] isMainThread]);
|
||||
if (!self.sharedCache) {
|
||||
self.sharedCache = new mbgl::SQLiteCache(defaultCacheDatabasePath());
|
||||
}
|
||||
[self.retainers addObject:object];
|
||||
return self.sharedCache;
|
||||
}
|
||||
|
||||
+ (void)releaseSharedCacheForObject:(NSObject *)object {
|
||||
return [[MGLFileCache sharedInstance] releaseSharedCacheForObject:object];
|
||||
}
|
||||
|
||||
- (void)releaseSharedCacheForObject:(NSObject *)object {
|
||||
assert([[NSThread currentThread] isMainThread]);
|
||||
if ([self.retainers containsObject:object]) {
|
||||
[self.retainers removeObject:object];
|
||||
}
|
||||
if ([self.retainers count] == 0) {
|
||||
[self teardown];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,8 @@
|
||||
|
||||
#import "MGLMetricsLocationManager.h"
|
||||
#import "NSProcessInfo+MGLAdditions.h"
|
||||
#import "NSBundle+MGLAdditions.h"
|
||||
#import "NSException+MGLAdditions.h"
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
@@ -17,6 +19,7 @@ NSString *const MGLEventTypeMapLoad = @"map.load";
|
||||
NSString *const MGLEventTypeMapTap = @"map.click";
|
||||
NSString *const MGLEventTypeMapDragEnd = @"map.dragend";
|
||||
NSString *const MGLEventTypeLocation = @"location";
|
||||
NSString *const MGLEventTypeVisit = @"visit";
|
||||
|
||||
NSString *const MGLEventKeyLatitude = @"lat";
|
||||
NSString *const MGLEventKeyLongitude = @"lng";
|
||||
@@ -29,6 +32,8 @@ NSString *const MGLEventKeyVerticalAccuracy = @"verticalAccuracy";
|
||||
NSString *const MGLEventKeyPushEnabled = @"enabled.push";
|
||||
NSString *const MGLEventKeyEmailEnabled = @"enabled.email";
|
||||
NSString *const MGLEventKeyGestureID = @"gesture";
|
||||
NSString *const MGLEventKeyArrivalDate = @"arrivalDate";
|
||||
NSString *const MGLEventKeyDepartureDate = @"departureDate";
|
||||
|
||||
NSString *const MGLEventGestureSingleTap = @"SingleTap";
|
||||
NSString *const MGLEventGestureDoubleTap = @"DoubleTap";
|
||||
@@ -62,6 +67,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
|
||||
@property (atomic) NSString *token;
|
||||
@property (atomic) NSString *appName;
|
||||
@property (atomic) NSString *appVersion;
|
||||
@property (atomic) NSString *appBuildNumber;
|
||||
@property (atomic) NSString *instanceID;
|
||||
@property (atomic) NSString *advertiserId;
|
||||
@property (atomic) NSString *vendorId;
|
||||
@@ -74,12 +80,13 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
|
||||
@property (atomic) NSDateFormatter *rfc3339DateFormatter;
|
||||
@property (atomic) CGFloat scale;
|
||||
@property (atomic) NSURLSession *session;
|
||||
@property (atomic) NSData *digicertCert;
|
||||
@property (atomic) NSData *geoTrustCert;
|
||||
|
||||
|
||||
// The isPaused state tracker is only ever accessed from the main thread.
|
||||
// The paused state tracker is only ever accessed from the main thread.
|
||||
//
|
||||
@property (nonatomic) BOOL isPaused;
|
||||
@property (nonatomic, getter=isPaused) BOOL paused;
|
||||
|
||||
// The timer is only ever accessed from the main thread.
|
||||
//
|
||||
@@ -105,19 +112,19 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
|
||||
// Must be called from the main thread. Only called internally.
|
||||
//
|
||||
- (instancetype) init {
|
||||
assert([[NSThread currentThread] isMainThread]);
|
||||
MGLAssertIsMainThread();
|
||||
|
||||
self = [super init];
|
||||
if (self) {
|
||||
|
||||
// Put Settings bundle into memory
|
||||
NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
|
||||
if(!settingsBundle) {
|
||||
NSString *appSettingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
|
||||
if(!appSettingsBundle) {
|
||||
NSLog(@"Could not find Settings.bundle");
|
||||
} else {
|
||||
// Dynamic Settings.bundle loading based on:
|
||||
// http://stackoverflow.com/questions/510216/can-you-make-the-settings-in-settings-bundle-default-even-if-you-dont-open-the
|
||||
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]];
|
||||
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[appSettingsBundle stringByAppendingPathComponent:@"Root.plist"]];
|
||||
NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"];
|
||||
NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
|
||||
for(NSDictionary *prefSpecification in preferences) {
|
||||
@@ -136,22 +143,23 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
|
||||
// Configure Events Infrastructure
|
||||
// ===============================
|
||||
|
||||
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
|
||||
_paused = YES;
|
||||
[self resumeMetricsCollection];
|
||||
NSBundle *resourceBundle = [NSBundle bundleWithPath:[NSBundle mgl_resourceBundlePath]];
|
||||
|
||||
// Load Local Copy of Server's Public Key
|
||||
NSString *cerPath = nil;
|
||||
NSArray *bundles = [NSBundle allFrameworks];
|
||||
for (int lc = 0; lc < bundles.count; lc++) {
|
||||
NSBundle *b = [bundles objectAtIndex:lc];
|
||||
cerPath = [[NSBundle mainBundle] pathForResource:@"api_mapbox_com-geotrust" ofType:@"der"];
|
||||
if (cerPath != nil) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
cerPath = [resourceBundle pathForResource:@"api_mapbox_com-geotrust" ofType:@"der"];
|
||||
if (cerPath != nil) {
|
||||
_geoTrustCert = [NSData dataWithContentsOfFile:cerPath];
|
||||
}
|
||||
|
||||
cerPath = nil;
|
||||
cerPath = [resourceBundle pathForResource:@"api_mapbox_com-digicert" ofType:@"der"];
|
||||
if (cerPath != nil) {
|
||||
_digicertCert = [NSData dataWithContentsOfFile:cerPath];
|
||||
}
|
||||
|
||||
// Events Control
|
||||
_eventQueue = [[NSMutableArray alloc] init];
|
||||
_flushAt = 20;
|
||||
@@ -201,24 +209,21 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
|
||||
|
||||
// Enable Battery Monitoring
|
||||
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
|
||||
|
||||
_isPaused = NO;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
// Can be called from any thread. Called implicitly from any
|
||||
// public class convenience methods.
|
||||
// public class convenience methods. May return nil if this feature is disabled.
|
||||
//
|
||||
+ (instancetype)sharedManager {
|
||||
static dispatch_once_t onceToken;
|
||||
static MGLMapboxEvents *_sharedManager;
|
||||
dispatch_once(&onceToken, ^{
|
||||
if ( ! NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent) {
|
||||
if ( ! NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent &&
|
||||
[[NSUserDefaults standardUserDefaults] objectForKey:@"mapbox_metrics_disabled"] == nil) {
|
||||
void (^setupBlock)() = ^{
|
||||
_sharedManager = [[self alloc] init];
|
||||
// setup dedicated location manager on first use
|
||||
[MGLMetricsLocationManager sharedManager];
|
||||
};
|
||||
if ( ! [[NSThread currentThread] isMainThread]) {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
@@ -233,47 +238,73 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
|
||||
return _sharedManager;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self pauseMetricsCollection];
|
||||
}
|
||||
|
||||
// Must be called from the main thread.
|
||||
//
|
||||
+ (void) setToken:(NSString *)token {
|
||||
assert([[NSThread currentThread] isMainThread]);
|
||||
MGLAssertIsMainThread();
|
||||
[MGLMapboxEvents sharedManager].token = token;
|
||||
}
|
||||
|
||||
// Must be called from the main thread.
|
||||
//
|
||||
+ (void) setAppName:(NSString *)appName {
|
||||
assert([[NSThread currentThread] isMainThread]);
|
||||
MGLAssertIsMainThread();
|
||||
[MGLMapboxEvents sharedManager].appName = appName;
|
||||
}
|
||||
|
||||
// Must be called from the main thread.
|
||||
//
|
||||
+ (void) setAppVersion:(NSString *)appVersion {
|
||||
assert([[NSThread currentThread] isMainThread]);
|
||||
MGLAssertIsMainThread();
|
||||
[MGLMapboxEvents sharedManager].appVersion = appVersion;
|
||||
}
|
||||
|
||||
// Must be called from the main thread.
|
||||
//
|
||||
+ (void) pauseMetricsCollection {
|
||||
assert([[NSThread currentThread] isMainThread]);
|
||||
if ([MGLMapboxEvents sharedManager].isPaused) {
|
||||
return;
|
||||
}
|
||||
[MGLMapboxEvents sharedManager].isPaused = YES;
|
||||
[MGLMetricsLocationManager stopUpdatingLocation];
|
||||
+ (void) setAppBuildNumber:(NSString *)appBuildNumber {
|
||||
MGLAssertIsMainThread();
|
||||
[MGLMapboxEvents sharedManager].appBuildNumber = appBuildNumber;
|
||||
}
|
||||
|
||||
+ (void)pauseMetricsCollection {
|
||||
[[MGLMapboxEvents sharedManager] pauseMetricsCollection];
|
||||
}
|
||||
|
||||
// Must be called from the main thread.
|
||||
//
|
||||
+ (void) resumeMetricsCollection {
|
||||
assert([[NSThread currentThread] isMainThread]);
|
||||
if (![MGLMapboxEvents sharedManager].isPaused) {
|
||||
- (void)pauseMetricsCollection {
|
||||
MGLAssertIsMainThread();
|
||||
if (self.paused) {
|
||||
return;
|
||||
}
|
||||
[MGLMapboxEvents sharedManager].isPaused = NO;
|
||||
[MGLMetricsLocationManager startUpdatingLocation];
|
||||
self.paused = YES;
|
||||
[_session invalidateAndCancel];
|
||||
_session = nil;
|
||||
MGLMetricsLocationManager *sharedLocationManager = [MGLMetricsLocationManager sharedManager];
|
||||
[sharedLocationManager stopUpdatingLocation];
|
||||
[sharedLocationManager stopMonitoringVisits];
|
||||
}
|
||||
|
||||
+ (void)resumeMetricsCollection {
|
||||
[[MGLMapboxEvents sharedManager] resumeMetricsCollection];
|
||||
}
|
||||
|
||||
// Must be called from the main thread.
|
||||
//
|
||||
- (void)resumeMetricsCollection {
|
||||
MGLAssertIsMainThread();
|
||||
if (!self.isPaused) {
|
||||
return;
|
||||
}
|
||||
self.paused = NO;
|
||||
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
|
||||
MGLMetricsLocationManager *sharedLocationManager = [MGLMetricsLocationManager sharedManager];
|
||||
[sharedLocationManager startUpdatingLocation];
|
||||
[sharedLocationManager startMonitoringVisits];
|
||||
}
|
||||
|
||||
// Can be called from any thread. Can be called rapidly from
|
||||
@@ -301,14 +332,8 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
|
||||
return;
|
||||
}
|
||||
|
||||
// Add Metrics Disabled App Wide Check
|
||||
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"mapbox_metrics_disabled"] != nil) {
|
||||
[_eventQueue removeAllObjects];
|
||||
return;
|
||||
}
|
||||
|
||||
// Metrics Collection Has Been Paused
|
||||
if (_isPaused) {
|
||||
if (_paused) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -462,8 +487,8 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
|
||||
// Can be called from any thread.
|
||||
//
|
||||
- (NSString *) getUserAgent {
|
||||
if (self.appName != nil && self.appVersion != nil && ([self.userAgent rangeOfString:self.appName].location == NSNotFound)) {
|
||||
self.userAgent = [NSString stringWithFormat:@"%@/%@ %@", self.appName, self.appVersion, self.userAgent];
|
||||
if (self.appName != nil && self.appVersion != nil && self.appBuildNumber != nil && ([self.userAgent rangeOfString:self.appName].location == NSNotFound)) {
|
||||
self.userAgent = [NSString stringWithFormat:@"%@/%@/%@ %@", self.appName, self.appVersion, self.appBuildNumber, self.userAgent];
|
||||
}
|
||||
return self.userAgent;
|
||||
}
|
||||
@@ -686,6 +711,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
|
||||
long numKeys = SecTrustGetCertificateCount(serverTrust);
|
||||
|
||||
BOOL found = false;
|
||||
// Try GeoTrust Cert First
|
||||
for (int lc = 0; lc < numKeys; lc++) {
|
||||
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc);
|
||||
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
|
||||
@@ -700,8 +726,24 @@ NSString *const MGLEventGestureRotateStart = @"Rotation";
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// The certificate wasn't found in the certificate chain; cancel the connection
|
||||
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
|
||||
// Fallback to Digicert Cert
|
||||
for (int lc = 0; lc < numKeys; lc++) {
|
||||
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc);
|
||||
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
|
||||
|
||||
// Compare Remote Key With Local Version
|
||||
if ([remoteCertificateData isEqualToData:_digicertCert]) {
|
||||
// Found the certificate; continue connecting
|
||||
completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// The certificate wasn't found in GeoTrust nor Digicert. Cancel the connection.
|
||||
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
@interface MGLMetricsLocationManager() <CLLocationManagerDelegate>
|
||||
|
||||
@property (nonatomic) CLLocationManager *locationManager;
|
||||
@property (atomic) NSDateFormatter *rfc3339DateFormatter;
|
||||
|
||||
@end
|
||||
|
||||
@@ -14,8 +15,18 @@
|
||||
- (instancetype) init {
|
||||
if (self = [super init]) {
|
||||
_locationManager = [[CLLocationManager alloc] init];
|
||||
_locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
|
||||
_locationManager.distanceFilter = 10;
|
||||
[_locationManager setDelegate:self];
|
||||
|
||||
_rfc3339DateFormatter = [[NSDateFormatter alloc] init];
|
||||
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
|
||||
|
||||
[_rfc3339DateFormatter setLocale:enUSPOSIXLocale];
|
||||
[_rfc3339DateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"];
|
||||
// Clear Any System TimeZone Cache
|
||||
[NSTimeZone resetSystemTimeZone];
|
||||
[_rfc3339DateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -29,12 +40,26 @@
|
||||
return sharedManager;
|
||||
}
|
||||
|
||||
+ (void) startUpdatingLocation {
|
||||
[[MGLMetricsLocationManager sharedManager].locationManager startUpdatingLocation];
|
||||
- (void)startUpdatingLocation {
|
||||
[self.locationManager startUpdatingLocation];
|
||||
}
|
||||
|
||||
+ (void) stopUpdatingLocation {
|
||||
[[MGLMetricsLocationManager sharedManager].locationManager stopUpdatingLocation];
|
||||
- (void)stopUpdatingLocation {
|
||||
[self.locationManager stopUpdatingLocation];
|
||||
}
|
||||
|
||||
- (void)startMonitoringVisits {
|
||||
// -[CLLocationManager startMonitoringVisits] is only available in iOS 8+.
|
||||
if ([self.locationManager respondsToSelector:@selector(startMonitoringVisits)]) {
|
||||
[self.locationManager startMonitoringVisits];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stopMonitoringVisits {
|
||||
// -[CLLocationManager stopMonitoringVisits] is only available in iOS 8+.
|
||||
if ([self.locationManager respondsToSelector:@selector(stopMonitoringVisits)]) {
|
||||
[self.locationManager stopMonitoringVisits];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark CLLocationManagerDelegate
|
||||
@@ -53,6 +78,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)locationManager:(CLLocationManager *)manager didVisit:(CLVisit *)visit {
|
||||
[MGLMapboxEvents pushEvent:MGLEventTypeVisit withAttributes:@{
|
||||
MGLEventKeyLatitude: @(visit.coordinate.latitude),
|
||||
MGLEventKeyLongitude: @(visit.coordinate.longitude),
|
||||
MGLEventKeyHorizontalAccuracy: @(visit.horizontalAccuracy),
|
||||
MGLEventKeyArrivalDate: [[NSDate distantPast] isEqualToDate:visit.arrivalDate] ? [NSNull null] : [_rfc3339DateFormatter stringFromDate:visit.arrivalDate],
|
||||
MGLEventKeyDepartureDate: [[NSDate distantFuture] isEqualToDate:visit.departureDate] ? [NSNull null] : [_rfc3339DateFormatter stringFromDate:visit.departureDate]
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
|
||||
NSString *newStatus = nil;
|
||||
switch (status) {
|
||||
@@ -64,18 +99,21 @@
|
||||
break;
|
||||
case kCLAuthorizationStatusDenied:
|
||||
newStatus = @"User Explcitly Denied";
|
||||
[MGLMetricsLocationManager stopUpdatingLocation];
|
||||
[self stopUpdatingLocation];
|
||||
[self stopMonitoringVisits];
|
||||
break;
|
||||
case kCLAuthorizationStatusAuthorized:
|
||||
newStatus = @"User Has Authorized / Authorized Always";
|
||||
[MGLMetricsLocationManager startUpdatingLocation];
|
||||
[self startUpdatingLocation];
|
||||
[self startMonitoringVisits];
|
||||
break;
|
||||
// case kCLAuthorizationStatusAuthorizedAlways:
|
||||
// newStatus = @"Not Determined";
|
||||
// break;
|
||||
// case kCLAuthorizationStatusAuthorizedAlways:
|
||||
// newStatus = @"Not Determined";
|
||||
// break;
|
||||
case kCLAuthorizationStatusAuthorizedWhenInUse:
|
||||
newStatus = @"User Has Authorized When In Use Only";
|
||||
[MGLMetricsLocationManager startUpdatingLocation];
|
||||
[self startUpdatingLocation];
|
||||
[self startMonitoringVisits];
|
||||
break;
|
||||
default:
|
||||
newStatus = @"Unknown";
|
||||
|
||||
@@ -30,6 +30,7 @@ const CGFloat MGLTrackingDotRingWidth = 24.0;
|
||||
self.annotation.mapView = mapView;
|
||||
_mapView = mapView;
|
||||
[self setupLayers];
|
||||
self.accessibilityLabel = @"User location";
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
7
platform/ios/NSBundle+MGLAdditions.h
Normal file
7
platform/ios/NSBundle+MGLAdditions.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NSBundle (MGLAdditions)
|
||||
|
||||
+ (NSString *)mgl_resourceBundlePath;
|
||||
|
||||
@end
|
||||
16
platform/ios/NSBundle+MGLAdditions.m
Normal file
16
platform/ios/NSBundle+MGLAdditions.m
Normal file
@@ -0,0 +1,16 @@
|
||||
#import "NSBundle+MGLAdditions.h"
|
||||
|
||||
#import "MGLMapView.h"
|
||||
|
||||
@implementation NSBundle (MGLAdditions)
|
||||
|
||||
+ (NSString *)mgl_resourceBundlePath
|
||||
{
|
||||
NSString *resourceBundlePath = [[NSBundle bundleForClass:[MGLMapView class]] pathForResource:@"MapboxGL" ofType:@"bundle"];
|
||||
|
||||
if ( ! resourceBundlePath) resourceBundlePath = [[NSBundle mainBundle] bundlePath];
|
||||
|
||||
return resourceBundlePath;
|
||||
}
|
||||
|
||||
@end
|
||||
3
platform/ios/NSException+MGLAdditions.h
Normal file
3
platform/ios/NSException+MGLAdditions.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#define MGLAssertIsMainThread() NSAssert([[NSThread currentThread] isMainThread], @"-[%@ %@] must be accessed on the main thread, not %@", [self class], NSStringFromSelector(_cmd), [NSThread currentThread])
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.0 KiB |
BIN
platform/ios/resources/api_mapbox_com-digicert.der
Normal file
BIN
platform/ios/resources/api_mapbox_com-digicert.der
Normal file
Binary file not shown.
15
scripts/android/install.sh
Executable file
15
scripts/android/install.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
source ./scripts/travis_helper.sh
|
||||
|
||||
mapbox_time "checkout_mason" \
|
||||
git submodule update --init .mason
|
||||
|
||||
export MASON_PLATFORM=android
|
||||
export MASON_ANDROID_ABI=${ANDROID_ABI}
|
||||
|
||||
mapbox_time "android_toolchain" \
|
||||
./scripts/android/toolchain.sh
|
||||
61
scripts/android/run.sh
Executable file
61
scripts/android/run.sh
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
BUILDTYPE=${BUILDTYPE:-Release}
|
||||
TESTMUNK=${TESTMUNK:-no}
|
||||
export HOST=android
|
||||
export MASON_PLATFORM=android
|
||||
export MASON_ANDROID_ABI=${ANDROID_ABI:-arm-v7}
|
||||
|
||||
source ./scripts/travis_helper.sh
|
||||
|
||||
# Add Mason to PATH
|
||||
export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason"
|
||||
|
||||
################################################################################
|
||||
# Build
|
||||
################################################################################
|
||||
|
||||
mapbox_time "checkout_styles" \
|
||||
git submodule update --init styles
|
||||
|
||||
mkdir -p ./android/java/MapboxGLAndroidSDKTestApp/src/main/res/raw
|
||||
echo "${MAPBOX_ACCESS_TOKEN}" > ./android/java/MapboxGLAndroidSDKTestApp/src/main/res/raw/token.txt
|
||||
|
||||
mapbox_time "compile_library" \
|
||||
make android-lib -j${JOBS} BUILDTYPE=${BUILDTYPE}
|
||||
|
||||
mapbox_time "build_apk" \
|
||||
make android -j${JOBS} BUILDTYPE=${BUILDTYPE}
|
||||
|
||||
################################################################################
|
||||
# Deploy
|
||||
################################################################################
|
||||
|
||||
if [ ! -z "${AWS_ACCESS_KEY_ID}" ] && [ ! -z "${AWS_SECRET_ACCESS_KEY}" ] ; then
|
||||
# Install and add awscli to PATH for uploading the results
|
||||
mapbox_time "install_awscli" \
|
||||
pip install --user awscli
|
||||
export PATH="`python -m site --user-base`/bin:${PATH}"
|
||||
|
||||
mapbox_time_start "deploy_results"
|
||||
echo "Deploying results..."
|
||||
|
||||
S3_PREFIX=s3://mapbox/mapbox-gl-native/android/build/${TRAVIS_JOB_NUMBER}
|
||||
APK_OUTPUTS=./android/java/MapboxGLAndroidSDKTestApp/build/outputs/apk
|
||||
|
||||
# Upload either the debug or the release build
|
||||
if [ ${BUILDTYPE} == "Debug" ] ; then
|
||||
aws s3 cp \
|
||||
${APK_OUTPUTS}/MapboxGLAndroidSDKTestApp-debug.apk \
|
||||
${S3_PREFIX}/MapboxGLAndroidSDKTestApp-debug.apk
|
||||
elif [ ${BUILDTYPE} == "Release" ] ; then
|
||||
aws s3 cp \
|
||||
${APK_OUTPUTS}/MapboxGLAndroidSDKTestApp-release-unsigned.apk \
|
||||
${S3_PREFIX}/MapboxGLAndroidSDKTestApp-release-unsigned.apk
|
||||
fi
|
||||
|
||||
mapbox_time_finish
|
||||
fi
|
||||
26
scripts/android/toolchain.sh
Executable file
26
scripts/android/toolchain.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
export MASON_PLATFORM=android
|
||||
export MASON_ANDROID_ABI=${MASON_ANDROID_ABI:-arm-v7}
|
||||
export PATH="`pwd`/.mason:${PATH}"
|
||||
export MASON_DIR="`pwd`/.mason"
|
||||
|
||||
export PATH=`mason env PATH`
|
||||
|
||||
echo MASON_PLATFORM=\"${MASON_PLATFORM}\"
|
||||
echo MASON_ANDROID_ABI=\"${MASON_ANDROID_ABI}\"
|
||||
echo CXX=\"`which $(mason env CXX)`\"
|
||||
echo CC=\"`which $(mason env CC)`\"
|
||||
echo LD=\"`which $(mason env LD)`\"
|
||||
echo LINK=\"`which $(mason env CXX)`\"
|
||||
echo AR=\"`which $(mason env AR)`\"
|
||||
echo RANLIB=\"`which $(mason env RANLIB)`\"
|
||||
echo STRIP=\"`which $(mason env STRIP)`\"
|
||||
echo LDFLAGS=\"`mason env LDFLAGS` \${LDFLAGS:-}\"
|
||||
echo CFLAGS=\"`mason env CFLAGS` \${CFLAGS:-}\"
|
||||
echo CXXFLAGS=\"`mason env CXXFLAGS` \${CXXFLAGS:-}\"
|
||||
echo CPPFLAGS=\"`mason env CPPFLAGS` \${CPPFLAGS:-}\"
|
||||
echo JNIDIR=\"`mason env JNIDIR`\"
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
./scripts/local_mason.sh
|
||||
|
||||
export MASON_PLATFORM=android
|
||||
|
||||
export PATH=`.mason/mason env PATH`
|
||||
|
||||
echo MASON_PLATFORM=\"android\"
|
||||
echo MASON_ANDROID_ABI=\"${MASON_ANDROID_ABI}\"
|
||||
|
||||
echo CXX=\"`which $(.mason/mason env CXX)`\"
|
||||
echo CC=\"`which $(.mason/mason env CC)`\"
|
||||
echo LD=\"`which $(.mason/mason env LD)`\"
|
||||
echo LINK=\"`which $(.mason/mason env CXX)`\"
|
||||
echo AR=\"`which $(.mason/mason env AR)`\"
|
||||
echo RANLIB=\"`which $(.mason/mason env RANLIB)`\"
|
||||
echo STRIP=\"`which $(.mason/mason env STRIP)`\"
|
||||
echo LDFLAGS=\"`.mason/mason env LDFLAGS` ${LDFLAGS}\"
|
||||
echo CFLAGS=\"`.mason/mason env CFLAGS` ${CFLAGS}\"
|
||||
echo CPPFLAGS=\"`.mason/mason env CPPFLAGS` ${CPPFLAGS}\"
|
||||
echo JNIDIR=\"`.mason/mason env JNIDIR`\"
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then
|
||||
export DISPLAY=:99.0
|
||||
|
||||
if [[ ${MASON_PLATFORM} != "android" ]]; then
|
||||
sh -e /etc/init.d/xvfb start
|
||||
fi
|
||||
|
||||
# use g++ that supports c++11
|
||||
if [[ ${CXX} == "g++" ]]; then
|
||||
export CXX="g++-4.8"
|
||||
export CC="gcc-4.8"
|
||||
fi
|
||||
|
||||
# If building in debug then turn on sanitizers.
|
||||
# They should both work with latest g++/clang++
|
||||
# but it's not worth a standalone matrix so here
|
||||
# we just test address->gcc and thread->clang for
|
||||
# some limited coverage
|
||||
# if [[ ${BUILDTYPE} == "Debug" ]]; then
|
||||
# if [[ ${CXX} == "g++" ]]; then
|
||||
# export CXXFLAGS="-fsanitize=address -g ${CXXFLAGS}"
|
||||
# export CFLAGS="-fsanitize=address -g ${CFLAGS}"
|
||||
# export LDFLAGS="-fsanitize=address ${LDFLAGS}"
|
||||
# elif [[ ${CXX} == "clang++" ]]; then
|
||||
# export CXXFLAGS="-fsanitize=thread -g -fPIC ${CXXFLAGS}"
|
||||
# export CFLAGS="-fsanitize=thread -g ${CFLAGS}"
|
||||
# export LDFLAGS="-fsanitize=thread -pie ${LDFLAGS}"
|
||||
# fi
|
||||
# fi
|
||||
fi
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
mason install node 0.10.35
|
||||
export PATH="`mason prefix node 0.10.35`/bin":"$PATH"
|
||||
@@ -16,10 +16,10 @@ security unlock-keychain -p travis ios-build.keychain
|
||||
security set-keychain-settings -t 3600 -l ~/Library/Keychains/ios-build.keychain
|
||||
|
||||
# Add certificates to keychain and allow codesign to access them
|
||||
security import ./scripts/ios_travis/apple.crt -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
|
||||
security import ./scripts/ios_travis/ios-dist.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
|
||||
security import ./scripts/ios_travis/ios-dist.p12 -k ~/Library/Keychains/ios-build.keychain -P $IOS_KEY_PASSWORD -T /usr/bin/codesign
|
||||
security import ./scripts/ios/apple.crt -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
|
||||
security import ./scripts/ios/ios-dist.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
|
||||
security import ./scripts/ios/ios-dist.p12 -k ~/Library/Keychains/ios-build.keychain -P $IOS_KEY_PASSWORD -T /usr/bin/codesign
|
||||
|
||||
# Put the provisioning profile in place
|
||||
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
|
||||
cp "./scripts/ios_travis/$IOS_PROFILE_NAME.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/
|
||||
cp "./scripts/ios/$IOS_PROFILE_NAME.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/
|
||||
13
scripts/ios/after_failure.sh
Executable file
13
scripts/ios/after_failure.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -u
|
||||
|
||||
ls $KIF_SCREENSHOTS/
|
||||
|
||||
REPO_NAME=$(basename $TRAVIS_REPO_SLUG)
|
||||
|
||||
aws s3 cp $KIF_SCREENSHOTS/ s3://mapbox/$REPO_NAME/ios/tests/$TRAVIS_JOB_NUMBER/ --acl public-read --recursive > /dev/null
|
||||
|
||||
echo http://mapbox.s3.amazonaws.com/$REPO_NAME/ios/tests/$TRAVIS_JOB_NUMBER/index.html
|
||||
15
scripts/ios/install.sh
Executable file
15
scripts/ios/install.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
source ./scripts/travis_helper.sh
|
||||
|
||||
mapbox_time "checkout_mason" \
|
||||
git submodule update --init .mason
|
||||
export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason"
|
||||
|
||||
mapbox_time "install_xcpretty" \
|
||||
gem install xcpretty --no-rdoc --no-ri --no-document --quiet
|
||||
|
||||
mkdir -p ${KIF_SCREENSHOTS}
|
||||
@@ -4,11 +4,19 @@ set -e
|
||||
set -o pipefail
|
||||
set -u
|
||||
|
||||
source ./scripts/travis_helper.sh
|
||||
|
||||
NAME=MapboxGL
|
||||
OUTPUT=build/ios/pkg
|
||||
IOS_SDK_VERSION=`xcrun --sdk iphoneos --show-sdk-version`
|
||||
LIBUV_VERSION=0.10.28
|
||||
|
||||
if [[ ${#} -eq 0 ]]; then
|
||||
BUILD_FOR_DEVICE=true
|
||||
else
|
||||
BUILD_FOR_DEVICE=false
|
||||
fi
|
||||
|
||||
function step { >&2 echo -e "\033[1m\033[36m* $@\033[0m"; }
|
||||
function finish { >&2 echo -en "\033[0m"; }
|
||||
trap finish EXIT
|
||||
@@ -31,33 +39,43 @@ step "Creating build files..."
|
||||
export MASON_PLATFORM=ios
|
||||
export BUILDTYPE=${BUILDTYPE:-Release}
|
||||
export HOST=ios
|
||||
make Xcode/mbgl
|
||||
|
||||
step "Building iOS targets..."
|
||||
xcodebuild -sdk iphoneos${IOS_SDK_VERSION} \
|
||||
ARCHS="arm64 armv7 armv7s" \
|
||||
-project ./build/ios/mbgl.xcodeproj \
|
||||
-configuration ${BUILDTYPE} \
|
||||
-target everything \
|
||||
-jobs `sysctl -n hw.ncpu` | xcpretty -c
|
||||
make Xcode/ios
|
||||
|
||||
if [[ "${BUILD_FOR_DEVICE}" == true ]]; then
|
||||
step "Building iOS device targets..."
|
||||
xcodebuild -sdk iphoneos${IOS_SDK_VERSION} \
|
||||
ARCHS="arm64 armv7 armv7s" \
|
||||
ONLY_ACTIVE_ARCH=NO \
|
||||
-project ./build/ios/mbgl.xcodeproj \
|
||||
-configuration ${BUILDTYPE} \
|
||||
-target everything \
|
||||
-jobs ${JOBS} | xcpretty -c
|
||||
fi
|
||||
|
||||
step "Building iOS Simulator targets..."
|
||||
xcodebuild -sdk iphonesimulator${IOS_SDK_VERSION} \
|
||||
ARCHS="x86_64 i386" \
|
||||
ONLY_ACTIVE_ARCH=NO \
|
||||
-project ./build/ios/mbgl.xcodeproj \
|
||||
-configuration ${BUILDTYPE} \
|
||||
-target everything \
|
||||
-jobs `sysctl -n hw.ncpu` | xcpretty -c
|
||||
-jobs ${JOBS} | xcpretty -c
|
||||
|
||||
|
||||
step "Building static library..."
|
||||
LIBS=(core.a platform-ios.a asset-fs.a cache-sqlite.a http-nsurl.a)
|
||||
libtool -static -no_warning_for_no_symbols \
|
||||
-o ${OUTPUT}/static/lib${NAME}.a \
|
||||
${LIBS[@]/#/build/${BUILDTYPE}-iphoneos/libmbgl-} \
|
||||
${LIBS[@]/#/build/${BUILDTYPE}-iphonesimulator/libmbgl-} \
|
||||
`find mason_packages/ios-${IOS_SDK_VERSION} -type f -name libuv.a`
|
||||
if [[ "${BUILD_FOR_DEVICE}" == true ]]; then
|
||||
libtool -static -no_warning_for_no_symbols \
|
||||
-o ${OUTPUT}/static/lib${NAME}.a \
|
||||
${LIBS[@]/#/build/${BUILDTYPE}-iphoneos/libmbgl-} \
|
||||
${LIBS[@]/#/build/${BUILDTYPE}-iphonesimulator/libmbgl-} \
|
||||
`find mason_packages/ios-${IOS_SDK_VERSION} -type f -name libuv.a`
|
||||
else
|
||||
libtool -static -no_warning_for_no_symbols \
|
||||
-o ${OUTPUT}/static/lib${NAME}.a \
|
||||
${LIBS[@]/#/build/${BUILDTYPE}-iphonesimulator/libmbgl-} \
|
||||
`find mason_packages/ios-${IOS_SDK_VERSION} -type f -name libuv.a`
|
||||
fi
|
||||
echo "Created ${OUTPUT}/static/lib${NAME}.a"
|
||||
|
||||
|
||||
35
scripts/ios/run.sh
Executable file
35
scripts/ios/run.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -u
|
||||
|
||||
BUILDTYPE=${BUILDTYPE:-Release}
|
||||
|
||||
source ./scripts/travis_helper.sh
|
||||
|
||||
# Add Mason to PATH
|
||||
export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason"
|
||||
|
||||
PUBLISH_TAG=($(git show -s --format=%B | sed -n 's/.*\[publish \([a-z]\{1,\}\)-v\([0-9.]\{1,\}\)\].*/\1 \2/p'))
|
||||
PUBLISH_PLATFORM=${PUBLISH_TAG[0],-}
|
||||
PUBLISH_VERSION=${PUBLISH_TAG[1],-}
|
||||
|
||||
|
||||
################################################################################
|
||||
# Build
|
||||
################################################################################
|
||||
|
||||
if [[ ${PUBLISH_PLATFORM} = 'ios' ]]; then
|
||||
# build & package iOS
|
||||
mapbox_time "package_ios" \
|
||||
make ipackage
|
||||
|
||||
# publish iOS build
|
||||
mapbox_time "deploy_ios" \
|
||||
./scripts/ios/publish.sh "${PUBLISH_VERSION}"
|
||||
else
|
||||
# build & test iOS
|
||||
mapbox_time "run_ios_tests" \
|
||||
make itest
|
||||
fi
|
||||
16
scripts/ios/test.sh
Executable file
16
scripts/ios/test.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -u
|
||||
|
||||
xcodebuild \
|
||||
-project ./test/ios/ios-tests.xcodeproj \
|
||||
-scheme 'Mapbox GL Tests' \
|
||||
-sdk iphonesimulator \
|
||||
-destination 'platform=iOS Simulator,name=iPhone 5s,OS=7.1' \
|
||||
-destination 'platform=iOS Simulator,name=iPhone 5s,OS=latest' \
|
||||
-destination 'platform=iOS Simulator,name=iPad 2,OS=7.1' \
|
||||
-destination 'platform=iOS Simulator,name=iPad 2,OS=latest' \
|
||||
test \
|
||||
| xcpretty
|
||||
13
scripts/linux/install.sh
Executable file
13
scripts/linux/install.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
source ./scripts/travis_helper.sh
|
||||
|
||||
mapbox_time "checkout_mason" \
|
||||
git submodule update --init .mason
|
||||
export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason"
|
||||
|
||||
mapbox_time "install_mesa" \
|
||||
mason install mesa 10.4.3
|
||||
75
scripts/linux/run.sh
Executable file
75
scripts/linux/run.sh
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
BUILDTYPE=${BUILDTYPE:-Release}
|
||||
|
||||
source ./scripts/travis_helper.sh
|
||||
|
||||
# Add Mason to PATH
|
||||
export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason"
|
||||
|
||||
# Set the core file limit to unlimited so a core file is generated upon crash
|
||||
ulimit -c unlimited -S
|
||||
|
||||
################################################################################
|
||||
# X Server setup
|
||||
################################################################################
|
||||
|
||||
# Start the mock X server
|
||||
if [ -f /etc/init.d/xvfb ] ; then
|
||||
mapbox_time "start_xvfb" \
|
||||
sh -e /etc/init.d/xvfb start
|
||||
sleep 2 # sometimes, xvfb takes some time to start up
|
||||
fi
|
||||
|
||||
# Make sure we're connecting to xvfb
|
||||
export DISPLAY=:99.0
|
||||
|
||||
# Make sure we're loading the 10.4.3 libs we installed manually
|
||||
export LD_LIBRARY_PATH="`mason prefix mesa 10.4.3`/lib:${LD_LIBRARY_PATH:-}"
|
||||
|
||||
mapbox_time "glxinfo" \
|
||||
glxinfo
|
||||
|
||||
################################################################################
|
||||
# Build
|
||||
################################################################################
|
||||
|
||||
mapbox_time "checkout_styles" \
|
||||
git submodule update --init styles
|
||||
|
||||
mapbox_time "compile_program" \
|
||||
make linux -j${JOBS} BUILDTYPE=${BUILDTYPE}
|
||||
|
||||
mapbox_time "compile_tests" \
|
||||
make test -j${JOBS} BUILDTYPE=${BUILDTYPE}
|
||||
|
||||
################################################################################
|
||||
# Test
|
||||
################################################################################
|
||||
|
||||
mapbox_time "checkout_test_suite" \
|
||||
git submodule update --init test/suite
|
||||
|
||||
mapbox_time "run_tests" \
|
||||
make test-* BUILDTYPE=${BUILDTYPE}
|
||||
|
||||
mapbox_time "compare_results" \
|
||||
./scripts/compare_images.sh
|
||||
|
||||
################################################################################
|
||||
# Deploy
|
||||
################################################################################
|
||||
|
||||
if [ ! -z "${AWS_ACCESS_KEY_ID}" ] && [ ! -z "${AWS_SECRET_ACCESS_KEY}" ] ; then
|
||||
# Install and add awscli to PATH for uploading the results
|
||||
mapbox_time "install_awscli" \
|
||||
pip install --user awscli
|
||||
export PATH="`python -m site --user-base`/bin:${PATH}"
|
||||
|
||||
mapbox_time_start "deploy_results"
|
||||
(cd ./test/suite/ && ./bin/deploy_results.sh)
|
||||
mapbox_time_finish
|
||||
fi
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
git submodule update --init .mason
|
||||
PATH=`pwd`/.mason:$PATH
|
||||
export MASON_DIR=`pwd`/.mason
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
cd bin
|
||||
$1 install --clang=1
|
||||
cd ../
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user