framework2

Форк
0
1123 строки · 29.6 Кб
1
#include "ofUtils.h"
2
// FIXME: split ofUtils in two files, one which uses urlparser / ofImage, other without for smaller apps.
3
#include "ofImage.h"
4
#include "ofLog.h"
5
#include "ofAppBaseWindow.h"
6
#include "ofMainLoop.h"
7
#include "ofAppRunner.h"
8
#include "ofEvents.h"
9
#include "ofGLUtils.h"
10
#include "ofMath.h"
11
#include "ofPixels.h"
12

13
#include <chrono>
14
#include <numeric>
15
#include <locale>
16
#include "uriparser/Uri.h"
17

18
#ifdef TARGET_WIN32	 // For ofLaunchBrowser.
19
	#include <shellapi.h>
20
    #ifndef _MSC_VER
21
        #include <unistd.h> // this if for MINGW / _getcwd
22
		#include <sys/param.h> // for MAXPATHLEN
23
	// FIXME: else
24
    #endif
25
	#ifdef _MSC_VER
26
		#include <direct.h>
27
	#endif
28
	#include <mmsystem.h>
29
#endif
30

31
#if defined(TARGET_OF_IOS) || defined(TARGET_OSX ) || defined(TARGET_LINUX) || defined(TARGET_EMSCRIPTEN)
32
	#include <sys/time.h>
33
#endif
34

35
#ifdef TARGET_OSX
36
	#ifndef TARGET_OF_IOS
37
		#include <mach-o/dyld.h>
38
		#include <sys/param.h> // for MAXPATHLEN
39
	#endif
40
	#include <mach/clock.h>
41
	#include <mach/mach.h>
42
#endif
43

44
#ifdef TARGET_OF_IOS
45
#include "ofxiOSExtras.h"
46
#endif
47

48
#ifdef TARGET_ANDROID
49
#include "ofxAndroidUtils.h"
50
#endif
51

52
#ifndef MAXPATHLEN
53
	#define MAXPATHLEN 1024
54
#endif
55

56
using std::vector;
57
using std::string;
58
using std::setfill;
59

60
namespace of{
61
namespace priv{
62
	void initutils(){
63
        ofResetElapsedTimeCounter();
64
        of::random::Engine::construct();
65
    }
66

67
	void endutils(){
68
//#ifdef TARGET_OSX
69
//        mach_port_deallocate(mach_task_self(), cs);
70
//#endif
71
    }
72

73
	class Clock{
74
	public:
75
		Clock(){
76
		#ifdef TARGET_OSX
77
			host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cs);
78
		#endif
79
		}
80

81
		//--------------------------------------
82
		void setTimeModeSystem(){
83
			mode = ofTime::System;
84
			loopListener.unsubscribe();
85
		}
86

87
		//--------------------------------------
88
		void setTimeModeFixedRate(uint64_t stepNanos, ofMainLoop & mainLoop){
89
			fixedRateTime = getMonotonicTimeForMode(ofTime::System);
90
			mode = ofTime::FixedRate;
91
			fixedRateStep = stepNanos;
92
			loopListener = mainLoop.loopEvent.newListener([this]{
93
				fixedRateTime.nanoseconds += fixedRateStep;
94
				while(fixedRateTime.nanoseconds>1000000000){
95
					fixedRateTime.nanoseconds -= 1000000000;
96
					fixedRateTime.seconds += 1;
97
				}
98
			});
99
		}
100

101
		//--------------------------------------
102
		ofTime getCurrentTime(){
103
			return getMonotonicTimeForMode(mode);
104
		}
105

106
		//--------------------------------------
107
		std::chrono::nanoseconds getElapsedTime(){
108
			return getCurrentTime() - startTime;
109
		}
110

111
		//--------------------------------------
112
		void resetElapsedTimeCounter(){
113
			startTime = getMonotonicTimeForMode(ofTime::System);
114
		}
115

116
	private:
117

118
		//--------------------------------------
119
		ofTime getMonotonicTimeForMode(ofTime::Mode mode){
120
			ofTime t;
121
			t.mode = mode;
122
			if(mode == ofTime::System){
123
			#if (defined(TARGET_LINUX) && !defined(TARGET_RASPBERRY_PI_LEGACY)) || defined(TARGET_EMSCRIPTEN)
124
				struct timespec now;
125
				clock_gettime(CLOCK_MONOTONIC, &now);
126
				t.seconds = now.tv_sec;
127
				t.nanoseconds = now.tv_nsec;
128
			#elif defined(TARGET_OSX)
129
				mach_timespec_t now;
130
				clock_get_time(cs, &now);
131
				t.seconds = now.tv_sec;
132
				t.nanoseconds = now.tv_nsec;
133
			#elif defined( TARGET_WIN32 )
134
				LARGE_INTEGER freq;
135
				LARGE_INTEGER counter;
136
				QueryPerformanceFrequency(&freq);
137
				QueryPerformanceCounter(&counter);
138
				t.seconds = counter.QuadPart/freq.QuadPart;
139
				t.nanoseconds = (counter.QuadPart % freq.QuadPart)*1000000000/freq.QuadPart;
140
			#else
141
				struct timeval now;
142
				gettimeofday( &now, nullptr );
143
				t.seconds = now.tv_sec;
144
				t.nanoseconds = now.tv_usec * 1000;
145
			#endif
146
			}else{
147
				t = fixedRateTime;
148
			}
149
			return t;
150
		}
151
		uint64_t fixedRateStep = 1666667;
152
		ofTime fixedRateTime;
153
		ofTime startTime;
154
		ofTime::Mode mode = ofTime::System;
155
		ofEventListener loopListener;
156
	#ifdef TARGET_OSX
157
		clock_serv_t cs;
158
	#endif
159
	};
160

161
	Clock & getClock(){
162
		static Clock * clock = new Clock;
163
		return *clock;
164
	}
165
}
166
}
167

168

169
//--------------------------------------
170
uint64_t ofTime::getAsMilliseconds() const{
171
	auto seconds = std::chrono::seconds(this->seconds);
172
	auto nanoseconds = std::chrono::nanoseconds(this->nanoseconds);
173
	return (std::chrono::duration_cast<std::chrono::milliseconds>(seconds) +
174
			std::chrono::duration_cast<std::chrono::milliseconds>(nanoseconds)).count();
175
}
176

177
//--------------------------------------
178
uint64_t ofTime::getAsMicroseconds() const{
179
	auto seconds = std::chrono::seconds(this->seconds);
180
	auto nanoseconds = std::chrono::nanoseconds(this->nanoseconds);
181
	return (std::chrono::duration_cast<std::chrono::microseconds>(seconds) +
182
			std::chrono::duration_cast<std::chrono::microseconds>(nanoseconds)).count();
183
}
184

185
//--------------------------------------
186
uint64_t ofTime::getAsNanoseconds() const{
187
	auto seconds = std::chrono::seconds(this->seconds);
188
	auto nanoseconds = std::chrono::nanoseconds(this->nanoseconds);
189
	return (std::chrono::duration_cast<std::chrono::nanoseconds>(seconds) + nanoseconds).count();
190
}
191

192
//--------------------------------------
193
double ofTime::getAsSeconds() const{
194
	return seconds + nanoseconds / 1000000000.;
195
}
196

197
#ifndef TARGET_WIN32
198
timespec ofTime::getAsTimespec() const{
199
	timespec ret;
200
	ret.tv_sec = seconds;
201
	ret.tv_nsec = nanoseconds;
202
	return ret;
203
}
204
#endif
205

206
//--------------------------------------
207
std::chrono::time_point<std::chrono::nanoseconds> ofTime::getAsTimePoint() const{
208
	auto seconds = std::chrono::seconds(this->seconds);
209
	auto nanoseconds = std::chrono::nanoseconds(this->nanoseconds);
210
	return std::chrono::time_point<std::chrono::nanoseconds>(
211
				std::chrono::duration_cast<std::chrono::nanoseconds>(seconds) + nanoseconds);
212
}
213

214
//--------------------------------------
215
std::chrono::nanoseconds ofTime::operator-(const ofTime& other) const{
216
	auto seconds = std::chrono::seconds(this->seconds) - std::chrono::seconds(other.seconds);
217
	auto nanoseconds = std::chrono::nanoseconds(this->nanoseconds) - std::chrono::nanoseconds(other.nanoseconds);
218
	return std::chrono::duration_cast<std::chrono::nanoseconds>(seconds) + nanoseconds;
219
}
220

221
//--------------------------------------
222
bool ofTime::operator<(const ofTime & other) const{
223
	return seconds < other.seconds || (seconds == other.seconds && nanoseconds < other.nanoseconds);
224
}
225

226
//--------------------------------------
227
bool ofTime::operator>(const ofTime & other) const{
228
	return seconds > other.seconds || (seconds == other.seconds && nanoseconds > other.nanoseconds);
229
}
230

231
//--------------------------------------
232
bool ofTime::operator<=(const ofTime & other) const{
233
	return seconds <= other.seconds || (seconds == other.seconds && nanoseconds <= other.nanoseconds);
234
}
235

236
//--------------------------------------
237
bool ofTime::operator>=(const ofTime & other) const{
238
	return seconds >= other.seconds || (seconds == other.seconds && nanoseconds >= other.nanoseconds);
239
}
240

241
//--------------------------------------
242
uint64_t ofGetFixedStepForFps(double fps){
243
	return 1000000000 / fps;
244
}
245

246
//--------------------------------------
247
void ofSetTimeModeSystem(){
248
	auto mainLoop = ofGetMainLoop();
249
	if(!mainLoop){
250
		ofLogError("ofSetSystemTimeMode") << "ofMainLoop is not initialized yet, can't set time mode";
251
		return;
252
	}
253
	auto window = mainLoop->getCurrentWindow();
254
	if(!window){
255
		ofLogError("ofSetSystemTimeMode") << "No window setup yet can't set time mode";
256
		return;
257
	}
258
	window->events().setTimeModeSystem();
259
	of::priv::getClock().setTimeModeSystem();
260
}
261

262
//--------------------------------------
263
void ofSetTimeModeFixedRate(uint64_t stepNanos){
264
	auto mainLoop = ofGetMainLoop();
265
	if(!mainLoop){
266
		ofLogError("ofSetSystemTimeMode") << "ofMainLoop is not initialized yet, can't set time mode";
267
		return;
268
	}
269
	auto window = mainLoop->getCurrentWindow();
270
	if(!window){
271
		ofLogError("ofSetSystemTimeMode") << "No window setup yet can't set time mode";
272
		return;
273
	}
274
	window->events().setTimeModeFixedRate(stepNanos);
275
	of::priv::getClock().setTimeModeFixedRate(stepNanos, *mainLoop);
276
}
277

278
//--------------------------------------
279
void ofSetTimeModeFiltered(float alpha){
280
	auto mainLoop = ofGetMainLoop();
281
	if(!mainLoop){
282
		ofLogError("ofSetSystemTimeMode") << "ofMainLoop is not initialized yet, can't set time mode";
283
		return;
284
	}
285
	auto window = mainLoop->getCurrentWindow();
286
	if(!window){
287
		ofLogError("ofSetSystemTimeMode") << "No window setup yet can't set time mode";
288
		return;
289
	}
290
	window->events().setTimeModeFiltered(alpha);
291
	of::priv::getClock().setTimeModeSystem();
292
}
293

294
//--------------------------------------
295
ofTime ofGetCurrentTime(){
296
	return of::priv::getClock().getCurrentTime();
297
}
298

299

300
//--------------------------------------
301
uint64_t ofGetElapsedTimeMillis(){
302
	return std::chrono::duration_cast<std::chrono::milliseconds>(of::priv::getClock().getElapsedTime()).count();
303
}
304

305
//--------------------------------------
306
uint64_t ofGetElapsedTimeMicros(){
307
	return std::chrono::duration_cast<std::chrono::microseconds>(of::priv::getClock().getElapsedTime()).count();
308
}
309

310
//--------------------------------------
311
float ofGetElapsedTimef(){
312
	return std::chrono::duration<double>(of::priv::getClock().getElapsedTime()).count();
313
}
314

315
//--------------------------------------
316
void ofResetElapsedTimeCounter(){
317
	of::priv::getClock().resetElapsedTimeCounter();
318
}
319

320
//--------------------------------------
321
uint64_t ofGetSystemTime( ) {
322
	return of::priv::getClock().getCurrentTime().getAsMilliseconds();
323
}
324

325
//--------------------------------------
326
uint64_t ofGetSystemTimeMillis( ) {
327
	return of::priv::getClock().getCurrentTime().getAsMilliseconds();
328
}
329

330
//--------------------------------------
331
uint64_t ofGetSystemTimeMicros( ) {
332
	return of::priv::getClock().getCurrentTime().getAsMicroseconds();
333
}
334

335
//--------------------------------------------------
336
uint64_t ofGetUnixTime(){
337
	return static_cast<uint64_t>(time(nullptr));
338
}
339

340
uint64_t ofGetUnixTimeMillis() {
341
    auto elapsed = std::chrono::system_clock::now().time_since_epoch();
342
    return std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
343
}
344

345
//--------------------------------------
346
void ofSleepMillis(int millis){
347
	#ifdef TARGET_WIN32
348
		Sleep(millis);
349
	#elif defined(TARGET_LINUX)
350
		timespec interval = {millis/1000, millis%1000*1000000};
351
		timespec rem = {0,0};
352
		clock_nanosleep(CLOCK_MONOTONIC,0,&interval,&rem);
353
	#elif !defined(TARGET_EMSCRIPTEN)
354
		usleep(millis * 1000);
355
	#endif
356
}
357

358
//default ofGetTimestampString returns in this format: 2011-01-15-18-29-35-299
359
//--------------------------------------------------
360
string ofGetTimestampString(){
361

362
	string timeFormat = "%Y-%m-%d-%H-%M-%S-%i";
363

364
	return ofGetTimestampString(timeFormat);
365
}
366

367
//specify the string format - eg: %Y-%m-%d-%H-%M-%S-%i ( 2011-01-15-18-29-35-299 )
368
//--------------------------------------------------
369
string ofGetTimestampString(const string& timestampFormat){
370
	std::stringstream str;
371
	auto now = std::chrono::system_clock::now();
372
	auto t = std::chrono::system_clock::to_time_t(now);    std::chrono::duration<double> s = now - std::chrono::system_clock::from_time_t(t);
373
    int ms = s.count() * 1000;
374
	auto tm = *std::localtime(&t);
375
	constexpr int bufsize = 256;
376
	char buf[bufsize];
377

378
	// Beware! an invalid timestamp string crashes windows apps.
379
	// so we have to filter out %i (which is not supported by vs)
380
	// earlier.
381
	auto tmpTimestampFormat = timestampFormat;
382
	ofStringReplace(tmpTimestampFormat, "%i", ofToString(ms, 3, '0'));
383

384
	if (strftime(buf,bufsize, tmpTimestampFormat.c_str(),&tm) != 0){
385
		str << buf;
386
	}
387
	auto ret = str.str();
388

389

390
    return ret;
391
}
392

393
//--------------------------------------------------
394
int ofGetSeconds(){
395
	time_t 	curr;
396
	tm 		local;
397
	time(&curr);
398
	local	=*(localtime(&curr));
399
	return local.tm_sec;
400
}
401

402
//--------------------------------------------------
403
int ofGetMinutes(){
404
	time_t 	curr;
405
	tm 		local;
406
	time(&curr);
407
	local	=*(localtime(&curr));
408
	return local.tm_min;
409
}
410

411
//--------------------------------------------------
412
int ofGetHours(){
413
	time_t 	curr;
414
	tm 		local;
415
	time(&curr);
416
	local	=*(localtime(&curr));
417
	return local.tm_hour;
418
}
419

420
//--------------------------------------------------
421
int ofGetYear(){
422
	time_t    curr;
423
	tm       local;
424
	time(&curr);
425
	local   =*(localtime(&curr));
426
	int year = local.tm_year + 1900;
427
	return year;
428
}
429

430
//--------------------------------------------------
431
int ofGetMonth(){
432
	time_t    curr;
433
	tm       local;
434
	time(&curr);
435
	local   =*(localtime(&curr));
436
	int month = local.tm_mon + 1;
437
	return month;
438
}
439

440
//--------------------------------------------------
441
int ofGetDay(){
442
	time_t    curr;
443
	tm       local;
444
	time(&curr);
445
	local   =*(localtime(&curr));
446
	return local.tm_mday;
447
}
448

449
//--------------------------------------------------
450
int ofGetWeekday(){
451
	time_t    curr;
452
	tm       local;
453
	time(&curr);
454
	local   =*(localtime(&curr));
455
	return local.tm_wday;
456
}
457

458
//----------------------------------------
459
template<>
460
string ofFromString(const string& value){
461
	return value;
462
}
463

464
//----------------------------------------
465
template<>
466
const char * ofFromString(const string& value){
467
	return value.c_str();
468
}
469

470
//----------------------------------------
471
template <>
472
string ofToHex(const string& value) {
473
	std::ostringstream out;
474
	// how many bytes are in the string
475
	std::size_t numBytes = value.size();
476
	for(std::size_t i = 0; i < numBytes; i++) {
477
		// print each byte as a 2-character wide hex value
478
		out << setfill('0') << std::setw(2) << std::hex << (unsigned int) ((unsigned char)value[i]);
479
	}
480
	return out.str();
481
}
482

483
//----------------------------------------
484
string ofToHex(const char* value) {
485
	// this function is necessary if you want to print a string
486
	// using a syntax like ofToHex("test")
487
	return ofToHex((string) value);
488
}
489

490
//----------------------------------------
491
int ofToInt(const string& intString) {
492
	return ofTo<int>(intString);
493
}
494

495
//----------------------------------------
496
int ofHexToInt(const string& intHexString) {
497
	int x = 0;
498
	std::istringstream cur(intHexString);
499
	cur >> std::hex >> x;
500
	return x;
501
}
502

503
//----------------------------------------
504
char ofHexToChar(const string& charHexString) {
505
	int x = 0;
506
	std::istringstream cur(charHexString);
507
	cur >> std::hex >> x;
508
	return (char) x;
509
}
510

511
//----------------------------------------
512
float ofHexToFloat(const string& floatHexString) {
513
	union intFloatUnion {
514
		uint32_t i;
515
		float f;
516
	} myUnion;
517
	myUnion.i = 0;
518
	std::istringstream cur(floatHexString);
519
	cur >> std::hex >> myUnion.i;
520
	return myUnion.f;
521
}
522

523
//----------------------------------------
524
string ofHexToString(const string& stringHexString) {
525
	std::stringstream out;
526
	std::stringstream stream(stringHexString);
527
	// a hex string has two characters per byte
528
	std::size_t numBytes = stringHexString.size() / 2;
529
	for(std::size_t i = 0; i < numBytes; i++) {
530
		string curByte;
531
		// grab two characters from the hex string
532
		stream >> std::setw(2) >> curByte;
533
		// prepare to parse the two characters
534
		std::stringstream curByteStream(curByte);
535
		int cur = 0;
536
		// parse the two characters as a hex-encoded int
537
		curByteStream >> std::hex >> cur;
538
		// add the int as a char to our output stream
539
		out << (char) cur;
540
	}
541
	return out.str();
542
}
543

544
//----------------------------------------
545
float ofToFloat(const string& floatString) {
546
	return ofTo<float>(floatString);
547
}
548

549
//----------------------------------------
550
double ofToDouble(const string& doubleString) {
551
	return ofTo<double>(doubleString);
552
}
553

554
//----------------------------------------
555
int64_t ofToInt64(const string& intString) {
556
	return ofTo<int64_t>(intString);
557
}
558

559
//----------------------------------------
560
bool ofToBool(const string& boolString) {
561
	auto lower = ofToLower(boolString);
562
	if(lower == "true") {
563
		return true;
564
	}
565
	if(lower == "false") {
566
		return false;
567
	}
568
	bool x = false;
569
	std::istringstream cur(lower);
570
	cur >> x;
571
	return x;
572
}
573

574
//----------------------------------------
575
char ofToChar(const string& charString) {
576
	return ofTo<char>(charString);
577
}
578

579
//----------------------------------------
580
template <> string ofToBinary(const string& value) {
581
	std::stringstream out;
582
	std::size_t numBytes = value.size();
583
	for(std::size_t i = 0; i < numBytes; i++) {
584
		std::bitset<8> bitBuffer(value[i]);
585
		out << bitBuffer;
586
	}
587
	return out.str();
588
}
589

590
//----------------------------------------
591
string ofToBinary(const char* value) {
592
	// this function is necessary if you want to print a string
593
	// using a syntax like ofToBinary("test")
594
	return ofToBinary((string) value);
595
}
596

597
//----------------------------------------
598
int ofBinaryToInt(const string& value) {
599
	const int intSize = sizeof(int) * 8;
600
	std::bitset<intSize> binaryString(value);
601
	return (int) binaryString.to_ulong();
602
}
603

604
//----------------------------------------
605
char ofBinaryToChar(const string& value) {
606
	const int charSize = sizeof(char) * 8;
607
	std::bitset<charSize> binaryString(value);
608
	return (char) binaryString.to_ulong();
609
}
610

611
//----------------------------------------
612
float ofBinaryToFloat(const string& value) {
613
	const int floatSize = sizeof(float) * 8;
614
	std::bitset<floatSize> binaryString(value);
615
	union ulongFloatUnion {
616
			unsigned long result;
617
			float f;
618
	} myUFUnion;
619
	myUFUnion.result = binaryString.to_ulong();
620
	return myUFUnion.f;
621
}
622
//----------------------------------------
623
string ofBinaryToString(const string& value) {
624
	std::ostringstream out;
625
	std::stringstream stream(value);
626
	std::bitset<8> byteString;
627
	std::size_t numBytes = value.size() / 8;
628
	for(std::size_t i = 0; i < numBytes; i++) {
629
		stream >> byteString;
630
		out << (char) byteString.to_ulong();
631
	}
632
	return out.str();
633
}
634

635
//--------------------------------------------------
636
vector <string> ofSplitString(const string & source, const string & delimiter, bool ignoreEmpty, bool trim) {
637
	vector<string> result;
638
	if (delimiter.empty()) {
639
		result.push_back(source);
640
		return result;
641
	}
642
	string::const_iterator substart = source.begin(), subend;
643
	while (true) {
644
		subend = search(substart, source.end(), delimiter.begin(), delimiter.end());
645
		string sub(substart, subend);
646
		if(trim) {
647
			sub = ofTrim(sub);
648
		}
649
		if (!ignoreEmpty || !sub.empty()) {
650
			result.push_back(sub);
651
		}
652
		if (subend == source.end()) {
653
			break;
654
		}
655
		substart = subend + delimiter.size();
656
	}
657
	return result;
658
}
659

660
//--------------------------------------------------
661
string ofJoinString(const vector<string>& stringElements, const string& delimiter){
662
	string str;
663
	if(stringElements.empty()){
664
		return str;
665
	}
666
	auto numStrings = stringElements.size();
667
	string::size_type strSize = delimiter.size() * (numStrings - 1);
668
	for (const string &s : stringElements) {
669
		strSize += s.size();
670
	}
671
	str.reserve(strSize);
672
	str += stringElements[0];
673
	for (decltype(numStrings) i = 1; i < numStrings; ++i) {
674
		str += delimiter;
675
		str += stringElements[i];
676
	}
677
	return str;
678
}
679

680
//--------------------------------------------------
681
void ofStringReplace(string& input, const string& searchStr, const string& replaceStr){
682
	auto pos = input.find(searchStr);
683
	while(pos != std::string::npos){
684
		input.replace(pos, searchStr.size(), replaceStr);
685
		pos += replaceStr.size();
686
		std::string nextfind(input.begin() + pos, input.end());
687
		auto nextpos = nextfind.find(searchStr);
688
		if(nextpos==std::string::npos){
689
			break;
690
		}
691
		pos += nextpos;
692
	}
693
}
694

695
//--------------------------------------------------
696
bool ofIsStringInString(const string& haystack, const string& needle){
697
    return haystack.find(needle) != std::string::npos;
698
}
699

700
//--------------------------------------------------
701
std::size_t ofStringTimesInString(const string& haystack, const string& needle){
702
	const size_t step = needle.size();
703

704
	size_t count(0);
705
	size_t pos(0) ;
706

707
	while( (pos=haystack.find(needle, pos)) != std::string::npos) {
708
		pos +=step;
709
		++count ;
710
	}
711

712
	return count;
713
}
714

715

716
ofUTF8Iterator::ofUTF8Iterator(const string & str){
717
	try{
718
		utf8::replace_invalid(str.begin(),str.end(),back_inserter(src_valid));
719
	}catch(...){
720
	}
721
}
722

723
utf8::iterator<std::string::const_iterator> ofUTF8Iterator::begin() const{
724
	try {
725
		return utf8::iterator<std::string::const_iterator>(src_valid.begin(), src_valid.begin(), src_valid.end());
726
	}
727
	catch (...) {
728
		return utf8::iterator<std::string::const_iterator>();
729
	}
730
}
731

732
utf8::iterator<std::string::const_iterator> ofUTF8Iterator::end() const{
733
	try {
734
		return utf8::iterator<std::string::const_iterator>(src_valid.end(), src_valid.begin(), src_valid.end());
735
	}
736
	catch (...) {
737
		return utf8::iterator<std::string::const_iterator>();
738
	}
739
}
740

741
utf8::iterator<std::string::const_reverse_iterator> ofUTF8Iterator::rbegin() const {
742
	try {
743
		return utf8::iterator<std::string::const_reverse_iterator>(src_valid.rbegin(), src_valid.rbegin(), src_valid.rend());
744
	}
745
	catch (...) {
746
		return utf8::iterator<std::string::const_reverse_iterator>();
747
	}
748
}
749

750
utf8::iterator<std::string::const_reverse_iterator> ofUTF8Iterator::rend() const {
751
	try {
752
		return utf8::iterator<std::string::const_reverse_iterator>(src_valid.rbegin(), src_valid.rbegin(), src_valid.rend());
753
	}
754
	catch (...) {
755
		return utf8::iterator<std::string::const_reverse_iterator>();
756
	}
757
}
758

759

760
//--------------------------------------------------
761
// helper method to get locale from name
762
static std::locale getLocale(const string & locale) {
763
std::locale loc;
764
#if defined(TARGET_WIN32) && !_MSC_VER
765
	static bool printonce = true;
766
	if( printonce ){
767
		std::string current( setlocale(LC_ALL,NULL) );
768
		setlocale (LC_ALL,"");
769
		ofLogWarning("ofUtils") << "std::locale not supported. Using C locale: " << current ;
770
		printonce = false;
771
	}
772
#else
773
	try {
774
		loc = std::locale(locale.c_str());
775
	}
776
	catch (...) {
777
		ofLogWarning("ofUtils") << "Couldn't create locale " << locale << " using default, " << loc.name();
778
	}
779
#endif
780
	return loc;
781
}
782

783
//--------------------------------------------------
784
string ofToLower(const string & src, const string & locale){
785
	std::string dst;
786
	std::locale loc = getLocale(locale);
787
	try{
788
		for(auto c: ofUTF8Iterator(src)){
789
			utf8::append(std::tolower<wchar_t>(c, loc), back_inserter(dst));
790
		}
791
	}catch(...){
792
	}
793
	return dst;
794
}
795

796
//--------------------------------------------------
797
string ofToUpper(const string & src, const string & locale){
798
	std::string dst;
799
	std::locale loc = getLocale(locale);
800
	try{
801
		for(auto c: ofUTF8Iterator(src)){
802
			utf8::append(std::toupper<wchar_t>(c, loc), back_inserter(dst));
803
		}
804
	}catch(...){
805
	}
806
	return dst;
807
}
808

809
//--------------------------------------------------
810
string ofTrimFront(const string & src, const string& locale){
811
    auto dst = src;
812
    std::locale loc = getLocale(locale);
813
    dst.erase(dst.begin(),std::find_if_not(dst.begin(),dst.end(),[&](char & c){return std::isspace<char>(c,loc);}));
814
    return dst;
815
}
816

817
//--------------------------------------------------
818
string ofTrimBack(const string & src, const string& locale){
819
    auto dst = src;
820
    std::locale loc = getLocale(locale);
821
	dst.erase(std::find_if_not(dst.rbegin(),dst.rend(),[&](char & c){return std::isspace<char>(c,loc);}).base(), dst.end());
822
	return dst;
823
}
824

825
//--------------------------------------------------
826
string ofTrim(const string & src, const string& locale){
827
    return ofTrimFront(ofTrimBack(src));
828
}
829

830
//--------------------------------------------------
831
void ofAppendUTF8(string & str, uint32_t utf8){
832
	try{
833
		utf8::append(utf8, back_inserter(str));
834
	}catch(...){}
835
}
836

837
//--------------------------------------------------
838
void ofUTF8Append(string & str, uint32_t utf8){
839
	try{
840
		utf8::append(utf8, back_inserter(str));
841
	}catch(...){}
842
}
843

844
//--------------------------------------------------
845
void ofUTF8Insert(string & str, size_t pos, uint32_t utf8){
846
	std::string newText;
847
	size_t i = 0;
848
	for(auto c: ofUTF8Iterator(str)){
849
		if(i==pos){
850
			ofUTF8Append(newText, utf8);
851
		}
852
		ofUTF8Append(newText, c);
853
		i+=1;
854
	}
855
	if(i==pos){
856
		ofUTF8Append(newText, utf8);
857
	}
858
	str = newText;
859
}
860

861
//--------------------------------------------------
862
void ofUTF8Erase(string & str, size_t start, size_t len){
863
	std::string newText;
864
	size_t i = 0;
865
	for(auto c: ofUTF8Iterator(str)){
866
		if(i<start || i>=start + len){
867
			ofUTF8Append(newText, c);
868
		}
869
		i+=1;
870
	}
871
	str = newText;
872
}
873

874
//--------------------------------------------------
875
std::string ofUTF8Substring(const string & str, size_t start, size_t len){
876
	size_t i=0;
877
	std::string newText;
878
	for(auto c: ofUTF8Iterator(str)){
879
		if(i>=start){
880
			ofUTF8Append(newText, c);
881
		}
882
		i += 1;
883
		if(i==start + len){
884
			break;
885
		}
886
	}
887
	return newText;
888
}
889

890
//--------------------------------------------------
891
std::string ofUTF8ToString(uint32_t utf8){
892
	std::string str;
893
	ofUTF8Append(str, utf8);
894
	return str;
895
}
896

897
//--------------------------------------------------
898
size_t ofUTF8Length(const std::string & str){
899
	try{
900
		return utf8::distance(str.begin(), str.end());
901
	}catch(...){
902
		return 0;
903
	}
904
}
905

906
//--------------------------------------------------
907
void ofLaunchBrowser(const string& url, bool uriEncodeQuery){
908
	UriParserStateA state;
909
	UriUriA uri;
910
	state.uri = &uri;
911
	if(uriParseUriA(&state, url.c_str())!=URI_SUCCESS){
912
		ofLogError("ofUtils") << "ofLaunchBrowser(): malformed url \"" << url << "\"";
913
		uriFreeUriMembersA(&uri);
914
		return;
915
	}
916
	if(uriEncodeQuery) {
917
		uriNormalizeSyntaxA(&uri); // URI encodes during set
918
	}
919
	std::string scheme(uri.scheme.first, uri.scheme.afterLast);
920
	int size;
921
	uriToStringCharsRequiredA(&uri, &size);
922
	std::vector<char> buffer(size+1, 0);
923
	int written;
924
	uriToStringA(buffer.data(), &uri, url.size()*2, &written);
925
	std::string uriStr(buffer.data(), written-1);
926
	uriFreeUriMembersA(&uri);
927

928

929
	// http://support.microsoft.com/kb/224816
930
	// make sure it is a properly formatted url:
931
	//   some platforms, like Android, require urls to start with lower-case http/https
932
	//   Poco::URI automatically converts the scheme to lower case
933
	if(scheme != "http" && scheme != "https"){
934
		ofLogError("ofUtils") << "ofLaunchBrowser(): url does not begin with http:// or https://: \"" << uriStr << "\"";
935
		return;
936
	}
937

938
	#ifdef TARGET_WIN32
939
		ShellExecuteA(nullptr, "open", uriStr.c_str(),
940
                nullptr, nullptr, SW_SHOWNORMAL);
941
	#endif
942

943
	#ifdef TARGET_OSX
944
        // could also do with LSOpenCFURLRef
945
		string commandStr = "open \"" + uriStr + "\"";
946
		int ret = system(commandStr.c_str());
947
        if(ret!=0) {
948
			ofLogError("ofUtils") << "ofLaunchBrowser(): couldn't open browser, commandStr \"" << commandStr << "\"";
949
		}
950
	#endif
951

952
	#ifdef TARGET_LINUX
953
		string commandStr = "xdg-open \"" + uriStr + "\"";
954
		int ret = system(commandStr.c_str());
955
		if(ret!=0) {
956
			ofLogError("ofUtils") << "ofLaunchBrowser(): couldn't open browser, commandStr \"" << commandStr << "\"";
957
		}
958
	#endif
959

960
	#ifdef TARGET_OF_IOS
961
		ofxiOSLaunchBrowser(uriStr);
962
	#endif
963

964
	#ifdef TARGET_ANDROID
965
		ofxAndroidLaunchBrowser(uriStr);
966
	#endif
967

968
	#ifdef TARGET_EMSCRIPTEN
969
		ofLogError("ofUtils") << "ofLaunchBrowser() not implementeed in emscripten";
970
	#endif
971
}
972

973
//--------------------------------------------------
974
string ofGetVersionInfo(){
975
	std::stringstream sstr;
976
	sstr << OF_VERSION_MAJOR << "." << OF_VERSION_MINOR << "." << OF_VERSION_PATCH;
977

978
	if (!std::string(OF_VERSION_PRE_RELEASE).empty())
979
	{
980
		sstr << "-" << OF_VERSION_PRE_RELEASE;
981
	}
982

983
	return sstr.str();
984
}
985

986
unsigned int ofGetVersionMajor() {
987
	return OF_VERSION_MAJOR;
988
}
989

990
unsigned int ofGetVersionMinor() {
991
	return OF_VERSION_MINOR;
992
}
993

994
unsigned int ofGetVersionPatch() {
995
	return OF_VERSION_PATCH;
996
}
997

998
std::string ofGetVersionPreRelease() {
999
	return OF_VERSION_PRE_RELEASE;
1000
}
1001

1002

1003
//---- new to 006
1004
//from the forums http://www.openframeworks.cc/forum/viewtopic.php?t=1413
1005

1006
//--------------------------------------------------
1007
void ofSaveScreen(const string& filename) {
1008
   /*ofImage screen;
1009
   screen.allocate(ofGetWidth(), ofGetHeight(), OF_IMAGE_COLOR);
1010
   screen.grabScreen(0, 0, ofGetWidth(), ofGetHeight());
1011
   screen.save(filename);*/
1012
	ofPixels pixels;
1013
	ofGetGLRenderer()->saveFullViewport(pixels);
1014
	ofSaveImage(pixels,filename);
1015
}
1016

1017
//--------------------------------------------------
1018
void ofSaveViewport(const string& filename) {
1019
	// because ofSaveScreen doesn't related to viewports
1020
	/*ofImage screen;
1021
	ofRectangle view = ofGetCurrentViewport();
1022
	screen.allocate(view.width, view.height, OF_IMAGE_COLOR);
1023
	screen.grabScreen(0, 0, view.width, view.height);
1024
	screen.save(filename);*/
1025

1026
	ofPixels pixels;
1027
	ofGetGLRenderer()->saveFullViewport(pixels);
1028
	ofSaveImage(pixels,filename);
1029
}
1030

1031
//--------------------------------------------------
1032
int saveImageCounter = 0;
1033
void ofSaveFrame(bool bUseViewport){
1034
   string fileName = ofToString(saveImageCounter) + ".png";
1035
	if (bUseViewport){
1036
		ofSaveViewport(fileName);
1037
	} else {
1038
		ofSaveScreen(fileName);
1039
	}
1040
	saveImageCounter++;
1041
}
1042

1043
//--------------------------------------------------
1044
string ofSystem(const string& command){
1045
	FILE * ret = nullptr;
1046
#ifdef TARGET_WIN32
1047
	ret = _popen(command.c_str(),"r");
1048
#else
1049
	ret = popen(command.c_str(),"r");
1050
#endif
1051

1052
	string strret;
1053
	int c;
1054

1055
	if (ret == nullptr){
1056
		ofLogError("ofUtils") << "ofSystem(): error opening return file for command \"" << command  << "\"";
1057
	}else{
1058
		c = fgetc (ret);
1059
		while (c != EOF) {
1060
			strret += c;
1061
			c = fgetc (ret);
1062
		}
1063
#ifdef TARGET_WIN32
1064
		_pclose (ret);
1065
#else
1066
		pclose (ret);
1067
#endif
1068
	}
1069

1070
	return strret;
1071
}
1072

1073
//--------------------------------------------------
1074
ofTargetPlatform ofGetTargetPlatform(){
1075
#ifdef TARGET_LINUX
1076
    string arch = ofSystem("uname -m");
1077
    if(ofIsStringInString(arch,"x86_64")) {
1078
        return OF_TARGET_LINUX64;
1079
    } else if(ofIsStringInString(arch,"armv6l")) {
1080
        return OF_TARGET_LINUXARMV6L;
1081
    } else if(ofIsStringInString(arch,"armv7l")) {
1082
        return OF_TARGET_LINUXARMV7L;
1083
	} else if(ofIsStringInString(arch,"aarch64")) {
1084
		return OF_TARGET_LINUXAARCH64;		
1085
    } else {
1086
        return OF_TARGET_LINUX;
1087
    }
1088
#elif defined(TARGET_OSX)
1089
    return OF_TARGET_OSX;
1090
#elif defined(TARGET_WIN32)
1091
    #if (_MSC_VER)
1092
        return OF_TARGET_WINVS;
1093
    #else
1094
        return OF_TARGET_MINGW;
1095
    #endif
1096
#elif defined(TARGET_ANDROID)
1097
    return OF_TARGET_ANDROID;
1098
#elif defined(TARGET_OF_IOS)
1099
    return OF_TARGET_IOS;
1100
#elif defined(TARGET_EMSCRIPTEN)
1101
    return OF_TARGET_EMSCRIPTEN;
1102
#endif
1103
}
1104

1105
std::string ofGetEnv(const std::string & var, const std::string defaultValue){
1106
#ifdef TARGET_WIN32
1107
	const size_t BUFSIZE = 4096;
1108
	std::vector<char> pszOldVal(BUFSIZE, 0);
1109
	auto size = GetEnvironmentVariableA(var.c_str(), pszOldVal.data(), BUFSIZE);
1110
	if(size>0){
1111
		return std::string(pszOldVal.begin(), pszOldVal.begin()+size);
1112
	}else{
1113
		return defaultValue;
1114
	}
1115
#else
1116
	auto value = getenv(var.c_str());
1117
	if(value){
1118
		return value;
1119
	}else{
1120
		return defaultValue;
1121
	}
1122
#endif
1123
}
1124

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.