summaryrefslogtreecommitdiff
path: root/src/mbgl/util/worker.cpp
blob: 371766f096133c500f55b2e4a20000b444b5920c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <mbgl/util/worker.hpp>
#include <mbgl/util/work_task.hpp>
#include <mbgl/util/work_request.hpp>
#include <mbgl/platform/platform.hpp>
#include <mbgl/map/vector_tile.hpp>
#include <mbgl/annotation/annotation_tile.hpp>
#include <mbgl/util/pbf.hpp>
#include <mbgl/renderer/raster_bucket.hpp>

#include <cassert>
#include <future>

namespace mbgl {

class Worker::Impl {
public:
    Impl() = default;

    void parseRasterTile(std::unique_ptr<RasterBucket> bucket,
                         const std::shared_ptr<const std::string> data,
                         std::function<void(TileParseResult)> callback) {
        std::unique_ptr<util::Image> image(new util::Image(*data));
        if (!(*image)) {
            callback(TileParseResult("error parsing raster image"));
        }

        if (!bucket->setImage(std::move(image))) {
            callback(TileParseResult("error setting raster image to bucket"));
        }

        TileParseResultBuckets result;
        result.buckets.emplace_back("raster", std::move(bucket));
        result.state = TileData::State::parsed;

        callback(std::move(result));
    }

    void parseVectorTile(TileWorker* worker,
                         const std::shared_ptr<const std::string> data,
                         std::function<void(TileParseResult)> callback) {
        try {
            pbf tilePBF(reinterpret_cast<const unsigned char*>(data->data()), data->size());
            callback(worker->parseAllLayers(VectorTile(tilePBF)));
        } catch (const std::exception& ex) {
            callback(TileParseResult(ex.what()));
        }
    }

    void parsePendingVectorTileLayers(TileWorker* worker,
                                      std::function<void(TileParseResult)> callback) {
        try {
            callback(worker->parsePendingLayers());
        } catch (const std::exception& ex) {
            callback(TileParseResult(ex.what()));
        }
    }

    void parseLiveTile(TileWorker* worker,
                       const AnnotationTile* tile,
                       std::function<void(TileParseResult)> callback) {
        try {
            callback(worker->parseAllLayers(*tile));
        } catch (const std::exception& ex) {
            callback(TileParseResult(ex.what()));
        }
    }

    void redoPlacement(TileWorker* worker,
                       const std::unordered_map<std::string, std::unique_ptr<Bucket>>* buckets,
                       float angle,
                       float pitch,
                       bool collisionDebug,
                       std::function<void()> callback) {
        worker->redoPlacement(buckets, angle, pitch, collisionDebug);
        callback();
    }
};

Worker::Worker(std::size_t count) {
    util::ThreadContext context = { "Worker", util::ThreadType::Worker, util::ThreadPriority::Low };
    for (std::size_t i = 0; i < count; i++) {
        threads.emplace_back(std::make_unique<util::Thread<Impl>>(context));
    }
}

Worker::~Worker() = default;

std::unique_ptr<WorkRequest>
Worker::parseRasterTile(std::unique_ptr<RasterBucket> bucket,
                        const std::shared_ptr<const std::string> data,
                        std::function<void(TileParseResult)> callback) {
    current = (current + 1) % threads.size();
    return threads[current]->invokeWithCallback(&Worker::Impl::parseRasterTile, callback, bucket,
                                                data);
}

std::unique_ptr<WorkRequest>
Worker::parseVectorTile(TileWorker& worker,
                        const std::shared_ptr<const std::string> data,
                        std::function<void(TileParseResult)> callback) {
    current = (current + 1) % threads.size();
    return threads[current]->invokeWithCallback(&Worker::Impl::parseVectorTile, callback, &worker,
                                                data);
}

std::unique_ptr<WorkRequest>
Worker::parsePendingVectorTileLayers(TileWorker& worker,
                                     std::function<void(TileParseResult)> callback) {
    current = (current + 1) % threads.size();
    return threads[current]->invokeWithCallback(&Worker::Impl::parsePendingVectorTileLayers,
                                                callback, &worker);
}

std::unique_ptr<WorkRequest> Worker::parseLiveTile(TileWorker& worker,
                                                   const AnnotationTile& tile,
                                                   std::function<void(TileParseResult)> callback) {
    current = (current + 1) % threads.size();
    return threads[current]->invokeWithCallback(&Worker::Impl::parseLiveTile, callback, &worker,
                                                &tile);
}

std::unique_ptr<WorkRequest>
Worker::redoPlacement(TileWorker& worker,
                      const std::unordered_map<std::string, std::unique_ptr<Bucket>>& buckets,
                      float angle,
                      float pitch,
                      bool collisionDebug,
                      std::function<void()> callback) {
    current = (current + 1) % threads.size();
    return threads[current]->invokeWithCallback(&Worker::Impl::redoPlacement, callback, &worker,
                                                &buckets, angle, pitch, collisionDebug);
}

} // end namespace mbgl