summaryrefslogtreecommitdiff
path: root/json-instagram/src/exampleApp.h
blob: 021e2413f44d0d061fe1d2f96d67958c2ff5d5e9 (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
#pragma once


#include "ofMain.h"
#include "ofxJSONElement.h"

long ofToLong(const string& intString);

class instagramLoader : public ofThread{

	public:

		float interval; //time between refreshes in seconds

	    int count;  // threaded fucntions that share data need to use lock (mutex)
	                // and unlock in order to write to that data
	                // otherwise it's possible to get crashes.
	                //
	                // also no opengl specific stuff will work in a thread...
	                // threads can't create textures, or draw stuff on the screen
	                // since opengl is single thread safe

		//--------------------------
		std::string url;
		ofxJSONElement response;
		std::map<std::string,ofImage> images;
		deque<std::string> to_update;

		instagramLoader(){
			count = 0;
			url = "https://api.instagram.com/v1/tags/tycleeson/media/recent?client_id=c1d74d701fdf4ddd9f8d30ee9e8f944b";
		}

		void set_interval(float _interval){
			interval=_interval;
		}

		void start(){
            startThread(true, false);   // blocking, verbose
        }

        void stop(){
            stopThread();
        }

		//--------------------------
		void threadedFunction(){

			cout  << "Api: " << url<<endl;

			while( isThreadRunning() != 0 ){

				cout<<"."<<std::flush;
			
				if (!response.open(url)) {
					cout  << "Failed to parse JSON\n" << endl;
				}
				else {	//int numImages = MIN(5,response["data"].size());
					
					
					for(int i=0; i< response["data"].size(); i++) {
						//cout  << "response " <<response["data"][i]["caption"]["id"].asString()<< endl;
						
						if (images.find(response["data"][i]["caption"]["id"].asString())==images.end()){
							std::string url = response["data"][i]["images"]["standard_resolution"]["url"].asString();
							std::string id = response["data"][i]["caption"]["id"].asString();
							cout<<"fetching "<<id<<":"<<url<<endl;
							
							ofImage img;
							img.setUseTexture(false);
							img.loadImage(url);
							if( lock() ){
								images[id]=img;
								to_update.push_back(id);
								unlock();
							}
						}
					}			
				}
				ofSleepMillis(interval * 1000);
			}
		}

		//--------------------------
		void draw(){
			if( lock() ){
				if (to_update.size()){
					std::string im = to_update.front();

					const ofPixels& pix = images[im].getPixelsRef();
					images[im].getTextureReference().allocate(
							 pix.getWidth()
							,pix.getHeight()
							,ofGetGlInternalFormat(pix)
					);
					
					images[im].setUseTexture(true);
					images[im].update();

					to_update.pop_front();

					int drawcount=0;
					for (map<string,ofImage>::iterator i=images.begin();i!=images.end();++i){
						if(i->second.isUsingTexture()){
							drawcount++;
						}
					}
					cout<<"loaded "<<im<<" "<<ofToLong(im)%(long)(ofGetWidth()-images[im].getWidth()+1)<<","<<ofToLong(im)%(long)(ofGetHeight()-images[im].getHeight()+1)<<endl;
				}
				for (map<string,ofImage>::iterator i=images.begin();i!=images.end();++i){
					if(i->second.isUsingTexture()){
						i->second.draw(ofToLong(i->first)%(long)(ofGetWidth()-i->second.getWidth()+1),ofToLong(i->first)%(long)(ofGetHeight()-i->second.getHeight()+1));
					}
				}
				unlock();
			}
		}


};

class exampleApp : public ofBaseApp {
public:
    void setup();
    void update();
    void draw();
    instagramLoader loader;
    
};