Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse event data without json #1001

Merged
merged 4 commits into from
Dec 22, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package com.mapbox.maps.extension.observable

import com.google.gson.Gson
import com.mapbox.bindgen.Value
import com.mapbox.maps.Event
import com.mapbox.maps.MapEvents
import com.mapbox.maps.ObservableInterface
import com.mapbox.maps.Observer
import com.mapbox.maps.extension.observable.eventdata.*
import com.mapbox.maps.extension.observable.eventdata.ResourceEventData

private val gson by lazy {
Gson()
}
import com.mapbox.maps.extension.observable.model.*
import java.util.*

/**
* Subscribes an Observer for of event type "resource-request".
Expand Down Expand Up @@ -301,124 +299,329 @@ fun ObservableInterface.unsubscribeSourceRemoved(observer: Observer) =
* Get the parsed event data for resource-request event.
* @return a parsed ResourceEventData object.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getResourceEventData(): ResourceEventData {
val json = data.toJson()
return gson.fromJson(json, ResourceEventData::class.java)
val map = data.contents as Map<String, Value>
val requestMap = map.nonNullMap(REQUEST)
val responseMap = map.nullableMap(RESPONSE)
val errorMap = responseMap?.nullableMap(ERROR)
return ResourceEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END),
dataSource = DataSourceType.valueOf(map.nonNullString(DATA_SOURCE).toUpperCase(Locale.US).replace("-", "_")),
request = Request(
loadingMethod = requestMap.nonNullList(LOADING_METHOD),
url = requestMap.nonNullString(URL),
kind = RequestType.valueOf(requestMap.nonNullString(KIND).toUpperCase(Locale.US).replace("-", "_")),
priority = RequestPriority.valueOf(requestMap.nonNullString(PRIORITY).toUpperCase(Locale.US))
),
response = if (responseMap == null) null else Response(
eTag = responseMap.nullableString(E_TAG),
mustRevalidate = responseMap.nonNullBoolean(MUST_REVALIDATE),
noContent = responseMap.nonNullBoolean(NO_CONTENT),
modified = responseMap.nullableString(MODIFIED),
source = ResponseSourceType.valueOf(responseMap.nonNullString(SOURCE).toUpperCase(Locale.US).replace("-", "_")),
notModified = responseMap.nonNullBoolean(NOT_MODIFIED),
expires = responseMap.nullableString(EXPIRES),
size = responseMap.nonNullInt(SIZE),
error = if (errorMap == null) null else Error(
reason = ResponseErrorReason.valueOf(errorMap.nonNullString(REASON).toUpperCase(Locale.US).replace("-", "_")),
message = errorMap.nonNullString(MESSAGE)
)
),
cancelled = map.nonNullBoolean(CANCELLED)
)
}

/**
* Get the parsed event data for map loaded event.
* @return a parsed MapLoadedEventData object.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getMapLoadedEventData(): MapLoadedEventData {
val json = data.toJson()
return gson.fromJson(json, MapLoadedEventData::class.java)
val map = data.contents as Map<String, Value>
return MapLoadedEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END)
)
}

/**
* Get the parsed event data for map loading error event.
* @return a parsed MapLoadingErrorEventData object.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getMapLoadingErrorEventData(): MapLoadingErrorEventData {
val json = data.toJson()
return gson.fromJson(json, MapLoadingErrorEventData::class.java)
val map = data.contents as Map<String, Value>
val tileIDMap = map.nullableMap(TILE_ID)
return MapLoadingErrorEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END),
type = MapLoadErrorType.valueOf(map.nonNullString(TYPE).toUpperCase(Locale.US)),
message = map.nonNullString(MESSAGE),
sourceId = map.nullableString(SOURCE_ID),
tileId = if (tileIDMap == null) null else TileID(
zoom = tileIDMap.nonNullLong(Z),
x = tileIDMap.nonNullLong(X),
y = tileIDMap.nonNullLong(Y)
)
)
}

/**
* Get the parsed event data for map idle event.
* @return a parsed MapIdleEventData object.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getMapIdleEventData(): MapIdleEventData {
val json = data.toJson()
return gson.fromJson(json, MapIdleEventData::class.java)
val map = data.contents as Map<String, Value>
return MapIdleEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END)
)
}

/**
* Get the parsed event data for style data loaded event.
* @return a parsed StyleDataLoadedEventData object.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getStyleDataLoadedEventData(): StyleDataLoadedEventData {
val json = data.toJson()
return gson.fromJson(json, StyleDataLoadedEventData::class.java)
val map = data.contents as Map<String, Value>
return StyleDataLoadedEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END),
type = StyleDataType.valueOf(map.nonNullString(TYPE).toUpperCase(Locale.US))
)
}

/**
* Get the parsed event data for style loaded event.
* @return a parsed StyleLoadedEventData object.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getStyleLoadedEventData(): StyleLoadedEventData {
val json = data.toJson()
return gson.fromJson(json, StyleLoadedEventData::class.java)
val map = data.contents as Map<String, Value>
return StyleLoadedEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END),
)
}

/**
* Get the parsed event data for source data loaded event.
* @return a parsed SourceDataLoadedEventData object.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getSourceDataLoadedEventData(): SourceDataLoadedEventData {
val json = data.toJson()
return gson.fromJson(json, SourceDataLoadedEventData::class.java)
val map = data.contents as Map<String, Value>
val tileIDMap = map.nullableMap(TILE_ID)

return SourceDataLoadedEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END),
id = map.nonNullString(ID),
type = SourceDataType.valueOf(map.nonNullString(TYPE).toUpperCase(Locale.US)),
loaded = map.nullableBoolean(LOADED),
tileID = if (tileIDMap == null) null else TileID(
zoom = tileIDMap.nonNullLong(Z),
x = tileIDMap.nonNullLong(X),
y = tileIDMap.nonNullLong(Y)
)
)
}

/**
* Get the parsed event data for style missing event.
* @return a parsed StyleImageMissingEventData.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getStyleImageMissingEventData(): StyleImageMissingEventData {
val json = data.toJson()
return gson.fromJson(json, StyleImageMissingEventData::class.java)
val map = data.contents as Map<String, Value>
return StyleImageMissingEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END),
id = map.nonNullString(ID)
)
}

/**
* Get the parsed event data for style image unused event.
* @return a parsed StyleImageUnusedEventData.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getStyleImageUnusedEventData(): StyleImageUnusedEventData {
val json = data.toJson()
return gson.fromJson(json, StyleImageUnusedEventData::class.java)
val map = data.contents as Map<String, Value>
return StyleImageUnusedEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END),
id = map.nonNullString(ID)
)
}

/**
* Get the parsed event data for source added event.
* @return a parsed IDStringEventData.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getSourceAddedEventData(): SourceAddedEventData {
val json = data.toJson()
return gson.fromJson(json, SourceAddedEventData::class.java)
val map = data.contents as Map<String, Value>
return SourceAddedEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END),
id = map.nonNullString(ID)
)
}

/**
* Get the parsed event data for source removed event.
* @return a parsed SourceRemovedEventData.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getSourceRemovedEventData(): SourceRemovedEventData {
val json = data.toJson()
return gson.fromJson(json, SourceRemovedEventData::class.java)
val map = data.contents as Map<String, Value>
return SourceRemovedEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END),
id = map.nonNullString(ID)
)
}

/**
* Get the parsed event data for render frame started event.
* @return a parsed RenderFrameStartedEventData.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getRenderFrameStartedEventData(): RenderFrameStartedEventData {
val json = data.toJson()
return gson.fromJson(json, RenderFrameStartedEventData::class.java)
val map = data.contents as Map<String, Value>
return RenderFrameStartedEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END)
)
}

/**
* Get the parsed event data for render frame finished event.
* @return a parsed RenderFrameFinishedEventData.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getRenderFrameFinishedEventData(): RenderFrameFinishedEventData {
val json = data.toJson()
return gson.fromJson(json, RenderFrameFinishedEventData::class.java)
val map = data.contents as Map<String, Value>
return RenderFrameFinishedEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END),
renderMode = RenderMode.valueOf(map.nonNullString(RENDER_MODE).toUpperCase(Locale.US)),
Chaoba marked this conversation as resolved.
Show resolved Hide resolved
needsRepaint = map.nonNullBoolean(NEEDS_REPAINT),
placementChanged = map.nonNullBoolean(PLACEMENT_CHANGED)
)
}

/**
* Get the parsed event data for camera changed event.
* @return a parsed CameraChangedEventData.
*/
@Suppress("UNCHECKED_CAST")
fun Event.getCameraChangedEventData(): CameraChangedEventData {
val json = data.toJson()
return gson.fromJson(json, CameraChangedEventData::class.java)
}
val map = data.contents as Map<String, Value>
return CameraChangedEventData(
begin = map.nonNullLong(BEGIN),
end = map.nullableLong(END)
)
}

internal fun Map<String, Value>.nonNullLong(name: String): Long {
alexander-kulikovskii marked this conversation as resolved.
Show resolved Hide resolved
return this[name]!!.contents as Long
}

internal fun Map<String, Value>.nullableLong(name: String): Long? {
return this[name]?.contents as Long?
}

internal fun Map<String, Value>.nonNullString(name: String): String {
return this[name]!!.contents as String
}

internal fun Map<String, Value>.nullableString(name: String): String? {
return this[name]?.contents as String?
}

internal fun Map<String, Value>.nonNullInt(name: String): Int {
return (this[name]!!.contents as Long).toInt()
alexander-kulikovskii marked this conversation as resolved.
Show resolved Hide resolved
}

internal fun Map<String, Value>.nullableInt(name: String): Int? {
return (this[name]?.contents as Int?)?.toInt()
}

internal fun Map<String, Value>.nonNullBoolean(name: String): Boolean {
return this[name]!!.contents as Boolean
}

internal fun Map<String, Value>.nullableBoolean(name: String): Boolean? {
return this[name]?.contents as Boolean?
}

@Suppress("UNCHECKED_CAST")
internal fun Map<String, Value>.nonNullMap(name: String): Map<String, Value> {
return this[name]!!.contents as Map<String, Value>
}

@Suppress("UNCHECKED_CAST")
internal fun Map<String, Value>.nullableMap(name: String): Map<String, Value>? {
return this[name]?.contents as Map<String, Value>?
}

@Suppress("UNCHECKED_CAST")
internal fun Map<String, Value>.nonNullList(name: String): List<String> {
return (this[name]!!.contents as List<Value>).map { it.toString() }
}

// Base type
private const val BEGIN = "begin"
private const val END = "end"

// MapLoadingErrorEventData
private const val TYPE = "type"
private const val MESSAGE = "message"
private const val SOURCE_ID = "source-id"
private const val TILE_ID = "tile-id"

// TileID
private const val X = "x"
private const val Y = "y"
private const val Z = "z"

// ResourceEventData
private const val DATA_SOURCE = "data-source"
private const val REQUEST = "request"
private const val RESPONSE = "response"
private const val CANCELLED = "cancelled"

// Request
private const val LOADING_METHOD = "loading-method"
private const val URL = "url"
private const val KIND = "kind"
private const val PRIORITY = "priority"

// Response
private const val E_TAG = "etag"
private const val MUST_REVALIDATE = "must-revalidate"
private const val NO_CONTENT = "no-content"
private const val MODIFIED = "modified"
private const val SOURCE = "source"
private const val NOT_MODIFIED = "not-modified"
private const val EXPIRES = "expires"
private const val SIZE = "size"
private const val ERROR = "error"

// Error
private const val REASON = "reason"

// SourceDataLoadedEventData
private const val ID = "id"
private const val LOADED = "loaded"

// RenderFrameFinishedEventData(
private const val RENDER_MODE = "render-mode"
private const val NEEDS_REPAINT = "needs-repaint"
private const val PLACEMENT_CHANGED = "placement-changed"
Loading