Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,4 @@ scripts/templates/vs2019/emptyExample.vcxproj.user
libs/openFrameworksCompiled/project/android/build-*/


examples/utils/urlFileLoaderExample/bin/data
Empty file.
13 changes: 13 additions & 0 deletions examples/utils/urlFileLoaderExample/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "ofMain.h"
#include "ofApp.h"

//========================================================================
int main() {
ofGLWindowSettings settings;
settings.setSize(720, 240);
settings.windowMode = OF_WINDOW;

auto window = ofCreateWindow(settings);
ofRunApp(window, std::make_shared<ofApp>());
ofRunMainLoop();
}
36 changes: 36 additions & 0 deletions examples/utils/urlFileLoaderExample/src/ofApp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup() {
ofSetWindowTitle("URL file loader progress");
ofSetBackgroundColor(30);

const std::string url = "https://raw.githubusercontent.com/openframeworks/openFrameworks/master/examples/graphics/fontShapesExample/bin/data/Batang.ttf";
ofHttpRequest request(url, ofToDataPath("Batang.ttf"), true);
request.progressCallback = [this](const ofHttpRequest &, float value) {
progress.store(value);
};
request.done = [this](const ofHttpResponse & response) {
status = response.status;
finished = true;
};
loader.handleRequestAsync(request);
}

//--------------------------------------------------------------
void ofApp::draw() {
const float value = progress.load();
const float width = ofGetWidth() - 80.0f;

ofSetColor(90);
ofDrawRectangle(40, 100, width, 24);
ofSetColor(70, 180, 255);
ofDrawRectangle(40, 100, width * value, 24);

ofSetColor(255);
ofDrawBitmapString("Downloading Batang.ttf", 40, 70);
ofDrawBitmapString(ofToString(value * 100.0f, 1) + "%", 40, 150);
if (finished) {
ofDrawBitmapString("Finished with HTTP status " + ofToString(status), 40, 185);
}
}
17 changes: 17 additions & 0 deletions examples/utils/urlFileLoaderExample/src/ofApp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include "ofMain.h"

#include <atomic>

class ofApp : public ofBaseApp {
public:
void setup() override;
void draw() override;

private:
ofURLFileLoader loader;
std::atomic<float> progress{ 0.0f };
bool finished = false;
int status = 0;
};
24 changes: 9 additions & 15 deletions libs/openFrameworks/utils/ofURLFileLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,18 +348,12 @@ size_t readBody_cb(void * ptr, size_t size, size_t nmemb, void * userdata) {
}
return 0; /* no more data left to deliver */
}
int progress_cb(void* ptr, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) {
auto & request = *static_cast<ofHttpRequest*>(ptr);
if (request.progressCallback) {
float progress = 0.0f;
if (request.method == ofHttpRequest::GET && dltotal > 0) {
progress = (float)dlnow / (float)dltotal;
// note: we may want to support upload and download for POST
} else if ((request.method == ofHttpRequest::PUT || request.method == ofHttpRequest::POST) && ultotal > 0) {
progress = (float)ulnow / (float)ultotal;
}

request.progressCallback(request, progress);
int transferProgress_cb(void * userdata, curl_off_t downloadTotal, curl_off_t downloaded, curl_off_t uploadTotal, curl_off_t uploaded) {
const auto & request = *static_cast<const ofHttpRequest *>(userdata);
if (request.method == ofHttpRequest::GET && downloadTotal > 0) {
request.progressCallback(request, static_cast<float>(downloaded) / static_cast<float>(downloadTotal));
} else if ((request.method == ofHttpRequest::PUT || request.method == ofHttpRequest::POST) && uploadTotal > 0) {
request.progressCallback(request, static_cast<float>(uploaded) / static_cast<float>(uploadTotal));
}
return 0;
}
Expand Down Expand Up @@ -536,13 +530,13 @@ ofHttpResponse ofURLFileLoaderImpl::handleRequest(const ofHttpRequest & request)
// start request and receive response
ofHttpResponse response(request, 0, "");
CURLcode err = CURLE_OK;

if (request.progressCallback) {
curl_easy_setopt(curl.get(), CURLOPT_XFERINFOFUNCTION, progress_cb);
curl_easy_setopt(curl.get(), CURLOPT_XFERINFOFUNCTION, transferProgress_cb);
curl_easy_setopt(curl.get(), CURLOPT_XFERINFODATA, &request);
curl_easy_setopt(curl.get(), CURLOPT_NOPROGRESS, 0L);
}

if (request.saveTo) {
ofFile saveTo(request.name, ofFile::WriteOnly, true);
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &saveTo);
Expand Down
3 changes: 2 additions & 1 deletion libs/openFrameworks/utils/ofURLFileLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class ofHttpRequest {
std::string body; ///< POST body data
std::string contentType; ///< POST data mime type
std::function<void(const ofHttpResponse &)> done;
std::function<void(const ofHttpRequest &, float)> progressCallback = nullptr; ///< pass a function for progress of download
/// the URL loader's worker thread. range [0, 1]
std::function<void(const ofHttpRequest &, float)> progressCallback = nullptr; // it reports upload/download progress. Asynchronous requests invoke this callback
size_t timeoutSeconds = 0;
bool headerOnly = false;

Expand Down
Loading