Compare commits
	
		
			4 Commits
		
	
	
		
			4ab7c4af18
			...
			8eff5ef1ea
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8eff5ef1ea | ||
| d3f91252b0 | |||
|  | dc02778445 | ||
|  | daec3d7f00 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1 +1,2 @@ | |||||||
| test/test | test/test | ||||||
|  | test/*.txt | ||||||
							
								
								
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @ -27,6 +27,7 @@ | |||||||
|         "bitset": "cpp", |         "bitset": "cpp", | ||||||
|         "algorithm": "cpp", |         "algorithm": "cpp", | ||||||
|         "string": "cpp", |         "string": "cpp", | ||||||
|         "string_view": "cpp" |         "string_view": "cpp", | ||||||
|  |         "fstream": "cpp" | ||||||
|     } |     } | ||||||
| } | } | ||||||
							
								
								
									
										28
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								README.md
									
									
									
									
									
								
							| @ -14,6 +14,7 @@ A C++ library for event-driven asynchronous multi-threaded programming. | |||||||
| - Typed events (on, emit, off) | - Typed events (on, emit, off) | ||||||
| - Event loops | - Event loops | ||||||
| - Multiple parallel execution loops | - Multiple parallel execution loops | ||||||
|  | - Asynchronous file IO | ||||||
| ## Installation | ## Installation | ||||||
| 
 | 
 | ||||||
| Just download the latest release and unzip it into your project.  | Just download the latest release and unzip it into your project.  | ||||||
| @ -25,6 +26,8 @@ Just download the latest release and unzip it into your project. | |||||||
| #include "asynco/lib/event.hpp"     // event | #include "asynco/lib/event.hpp"     // event | ||||||
| #include "asynco/lib/rotor.hpp"     // interval, timeout | #include "asynco/lib/rotor.hpp"     // interval, timeout | ||||||
| #include "asynco/lib/runner.hpp"    // for own loop | #include "asynco/lib/runner.hpp"    // for own loop | ||||||
|  | #include "asynco/lib/filesystem.hpp"// for async read and write files | ||||||
|  | 
 | ||||||
| using namespace marcelb; | using namespace marcelb; | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| @ -224,6 +227,31 @@ myclass.on("constructed", [] (int i) { | |||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
|  | 
 | ||||||
|  | Asynchronous file IO | ||||||
|  | 
 | ||||||
|  | ```c++ | ||||||
|  | string data_; | ||||||
|  | 
 | ||||||
|  | asynco_read("test.txt", [&data_] (string data, exception* error) { | ||||||
|  |     if (error) { | ||||||
|  |         cout << "Error " << error->what() << endl; | ||||||
|  |     } else { | ||||||
|  |         cout << "Data " << endl << data << endl; | ||||||
|  |         data_ = data; | ||||||
|  |         cout << "Data_" << data_ << endl; | ||||||
|  |     } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | asynco_write("test1.txt", "Hello night", [] (exception* error) { | ||||||
|  |     if (error) { | ||||||
|  |         cout << "Error " << error->what() << endl; | ||||||
|  |     } else { | ||||||
|  |         cout << "Write successfuly" << endl; | ||||||
|  |     } | ||||||
|  | }); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| ## License | ## License | ||||||
| 
 | 
 | ||||||
| [APACHE 2.0](http://www.apache.org/licenses/LICENSE-2.0/) | [APACHE 2.0](http://www.apache.org/licenses/LICENSE-2.0/) | ||||||
|  | |||||||
							
								
								
									
										111
									
								
								lib/filesystem.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								lib/filesystem.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | |||||||
|  | #ifndef _ASYNCO_FS_ | ||||||
|  | #define _ASYNCO_FS_ | ||||||
|  | 
 | ||||||
|  | #include "asynco.hpp" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include <fstream> | ||||||
|  | #include <iostream> | ||||||
|  | 
 | ||||||
|  | using namespace std; | ||||||
|  | 
 | ||||||
|  | namespace marcelb { | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Asynchronous file reading with callback after read complete | ||||||
|  | */ | ||||||
|  | template<typename Callback> | ||||||
|  | void asynco_read(string path, Callback&& callback) { | ||||||
|  |     asynco( [&path, callback] () { | ||||||
|  |         string content; | ||||||
|  |         try { | ||||||
|  |             string line; | ||||||
|  |             ifstream file (path); | ||||||
|  |             if (file.is_open()) { | ||||||
|  |                 line.clear(); | ||||||
|  |                 while ( getline (file,line) ) { | ||||||
|  |                     content += line + "\n"; | ||||||
|  |                 } | ||||||
|  |                 file.close(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             else { | ||||||
|  |                 throw runtime_error("Unable to open file");  | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             callback(content, nullptr); | ||||||
|  |         } catch(exception& error) { | ||||||
|  |             callback(content, &error); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Asynchronous file reading | ||||||
|  | */ | ||||||
|  | future<string> asynco_read(string path) { | ||||||
|  |     return asynco( [&path] () { | ||||||
|  |         string content; | ||||||
|  |         string line; | ||||||
|  |         ifstream file (path); | ||||||
|  |         if (file.is_open()) { | ||||||
|  |             line.clear(); | ||||||
|  |             while ( getline (file,line) ) { | ||||||
|  |                 content += line + "\n"; | ||||||
|  |             } | ||||||
|  |             file.close(); | ||||||
|  |             return content; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         else { | ||||||
|  |             throw runtime_error("Unable to open file");  | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Asynchronous file writing with callback after write complete | ||||||
|  | */ | ||||||
|  | template<typename Callback> | ||||||
|  | void asynco_write(string path, string content, Callback&& callback) { | ||||||
|  |     asynco( [&path, &content, callback] () { | ||||||
|  |         try { | ||||||
|  |             ofstream file (path); | ||||||
|  |             if (file.is_open()) { | ||||||
|  |                 file << content; | ||||||
|  |                 file.close(); | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 throw runtime_error("Unable to open file");  | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             callback(nullptr); | ||||||
|  |         } catch(exception& error) { | ||||||
|  |             callback(&error); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Asynchronous file writing with callback after write complete | ||||||
|  | */ | ||||||
|  | future<void> asynco_write(string path, string content) { | ||||||
|  |     return asynco( [&path, &content] () { | ||||||
|  |         ofstream file (path); | ||||||
|  |         if (file.is_open()) { | ||||||
|  |             file << content; | ||||||
|  |             file.close(); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw runtime_error("Unable to open file");  | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -22,6 +22,12 @@ int64_t rtime_ms() { | |||||||
|         .count(); |         .count(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int64_t rtime_us() { | ||||||
|  |     return chrono::duration_cast<chrono::microseconds>(chrono::system_clock::now() | ||||||
|  |         .time_since_epoch()) | ||||||
|  |         .count(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Intern class for timer async loop |  * Intern class for timer async loop | ||||||
| */ | */ | ||||||
| @ -38,7 +44,7 @@ class timer_core { | |||||||
|      * Timer constructor, receives a callback function and time |      * Timer constructor, receives a callback function and time | ||||||
|     */ |     */ | ||||||
|     timer_core( function<void()> _callback, int64_t _time, bool _repeat): |     timer_core( function<void()> _callback, int64_t _time, bool _repeat): | ||||||
|         callback(_callback), init(rtime_ms()), time(_time), repeat(_repeat), stop(false) { |         callback(_callback), init(rtime_us()), time(_time*1000), repeat(_repeat), stop(false) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
| @ -83,7 +89,7 @@ class rotor { | |||||||
|                 else if (expired(tcores[i])) { |                 else if (expired(tcores[i])) { | ||||||
|                     _asyncon.put_task(tcores[i]->callback); |                     _asyncon.put_task(tcores[i]->callback); | ||||||
|                     if (tcores[i]->repeat) { |                     if (tcores[i]->repeat) { | ||||||
|                         tcores[i]->init = rtime_ms(); |                         tcores[i]->init = rtime_us(); | ||||||
|                     } |                     } | ||||||
|                     else { |                     else { | ||||||
|                         remove(i); |                         remove(i); | ||||||
| @ -91,7 +97,7 @@ class rotor { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             this_thread::sleep_for(chrono::milliseconds(sampling)); |             this_thread::sleep_for(chrono::microseconds(sampling)); | ||||||
|         }  |         }  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -99,7 +105,7 @@ class rotor { | |||||||
|      * The method checks whether the time event has expired |      * The method checks whether the time event has expired | ||||||
|     */ |     */ | ||||||
|     bool expired(shared_ptr<timer_core> tcore) { |     bool expired(shared_ptr<timer_core> tcore) { | ||||||
|         return rtime_ms() - tcore->init >= tcore->time; |         return rtime_us() - tcore->init >= tcore->time; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /**
 |     /**
 | ||||||
|  | |||||||
							
								
								
									
										118
									
								
								test/test.cpp
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								test/test.cpp
									
									
									
									
									
								
							| @ -1,8 +1,9 @@ | |||||||
| #define NUM_OF_RUNNERS 2 | #define NUM_OF_RUNNERS 2 | ||||||
| 
 | 
 | ||||||
| #include "../lib/asynco.hpp" | // #include "../lib/asynco.hpp"
 | ||||||
| #include "../lib/event.hpp" | // #include "../lib/event.hpp"
 | ||||||
| #include "../lib/rotor.hpp" | // #include "../lib/rotor.hpp"
 | ||||||
|  | #include "../lib/filesystem.hpp" | ||||||
| 
 | 
 | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| @ -11,29 +12,29 @@ using namespace std; | |||||||
| using namespace marcelb; | using namespace marcelb; | ||||||
| using namespace this_thread; | using namespace this_thread; | ||||||
| 
 | 
 | ||||||
| void sleep_to (int _time) { | // void sleep_to (int _time) {
 | ||||||
|     promise<void> _promise; | //     promise<void> _promise;
 | ||||||
|     timeout t( [&]() { | //     timeout t( [&]() {
 | ||||||
|         _promise.set_value(); | //         _promise.set_value();
 | ||||||
|     }, _time); | //     }, _time);
 | ||||||
| 
 | 
 | ||||||
|     return _promise.get_future().get(); | //     return _promise.get_future().get();
 | ||||||
| } | // }
 | ||||||
| 
 | 
 | ||||||
| void promise_reject (int _time) { | // void promise_reject (int _time) {
 | ||||||
|     promise<void> _promise; | //     promise<void> _promise;
 | ||||||
|     timeout t( [&]() { | //     timeout t( [&]() {
 | ||||||
|         try { | //         try {
 | ||||||
|             // simulate except
 | //             // simulate except
 | ||||||
|             throw runtime_error("Error simulation"); | //             throw runtime_error("Error simulation");
 | ||||||
|             _promise.set_value(); | //             _promise.set_value();
 | ||||||
|         } catch (...) { | //         } catch (...) {
 | ||||||
|             _promise.set_exception(current_exception()); | //             _promise.set_exception(current_exception());
 | ||||||
|         } | //         }
 | ||||||
|     }, _time); | //     }, _time);
 | ||||||
| 
 | 
 | ||||||
|     return _promise.get_future().get(); | //     return _promise.get_future().get();
 | ||||||
| } | // }
 | ||||||
| 
 | 
 | ||||||
| void notLambdaFunction() { | void notLambdaFunction() { | ||||||
|     cout << "Call to not lambda function" << endl; |     cout << "Call to not lambda function" << endl; | ||||||
| @ -48,15 +49,15 @@ class clm { | |||||||
| 
 | 
 | ||||||
| // ------------------ EXTEND OWN CLASS WITH EVENTS -------------------
 | // ------------------ EXTEND OWN CLASS WITH EVENTS -------------------
 | ||||||
| 
 | 
 | ||||||
| class myOwnClass : public event<int> { | // class myOwnClass : public event<int> {
 | ||||||
|     public: | //     public:
 | ||||||
|     myOwnClass() : event() {}; | //     myOwnClass() : event() {};
 | ||||||
| }; | // };
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| int main () { | int main () { | ||||||
| 
 | 
 | ||||||
|     auto start = rtime_ms(); |     // auto start = rtime_ms();
 | ||||||
| 
 | 
 | ||||||
|     // --------------- TIME ASYNCHRONOUS FUNCTIONS --------------
 |     // --------------- TIME ASYNCHRONOUS FUNCTIONS --------------
 | ||||||
| 
 | 
 | ||||||
| @ -65,21 +66,25 @@ int main () { | |||||||
|     */ |     */ | ||||||
| 
 | 
 | ||||||
|     interval( [&] () { |     interval( [&] () { | ||||||
|         cout << "interval "  << rtime_ms() - start << endl; |         cout << "interval 1: "  << rtime_ms() - start << endl; | ||||||
|  |     }, 50); | ||||||
|  | 
 | ||||||
|  |     interval( [&] () { | ||||||
|  |         cout << "interval 1: "  << rtime_ms() - start << endl; | ||||||
|  |     }, 100); | ||||||
|  | 
 | ||||||
|  |     interval( [&] () { | ||||||
|  |         cout << "interval 2: " << rtime_ms() - start << endl; | ||||||
|     }, 200); |     }, 200); | ||||||
| 
 | 
 | ||||||
|     interval( [&] () { |     interval( [&] () { | ||||||
|         cout << "interval " << rtime_ms() - start << endl; |         cout << "interval 3: " << rtime_ms() - start << endl; | ||||||
|     }, 200); |     }, 300); | ||||||
| 
 |  | ||||||
|     interval( [&] () { |  | ||||||
|         cout << "interval " << rtime_ms() - start << endl; |  | ||||||
|     }, 200); |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     interval( [&] () { |     interval( [&] () { | ||||||
|         cout << "interval "  << rtime_ms() - start << endl; |         cout << "interval 4: "  << rtime_ms() - start << endl; | ||||||
|     }, 200); |     }, 400); | ||||||
| 
 | 
 | ||||||
|     // interval inter1 ([&]() {
 |     // interval inter1 ([&]() {
 | ||||||
|     //     cout << "interval prvi " << rtime_ms() - start << endl;
 |     //     cout << "interval prvi " << rtime_ms() - start << endl;
 | ||||||
| @ -274,6 +279,45 @@ int main () { | |||||||
|     //     cout << "Constructed " << i  << endl;
 |     //     cout << "Constructed " << i  << endl;
 | ||||||
|     // });
 |     // });
 | ||||||
| 
 | 
 | ||||||
|  |     string data_; | ||||||
|  | 
 | ||||||
|  |     // asynco_read("test.txt", [&data_] (string data, exception* error) {
 | ||||||
|  |     //     if (error) {
 | ||||||
|  |     //         cout << "Error " << error->what() << endl;
 | ||||||
|  |     //     } else {
 | ||||||
|  |     //         cout << "Data " << endl << data << endl;
 | ||||||
|  |     //         data_ = data;
 | ||||||
|  |     //         cout << "Data_" << data_ << endl;
 | ||||||
|  |     //     }
 | ||||||
|  |     // });
 | ||||||
|  | 
 | ||||||
|  |     // auto data = asynco_read("test4.txt");
 | ||||||
|  | 
 | ||||||
|  |     // try {
 | ||||||
|  |     //     data_ = wait(data);
 | ||||||
|  |     //     cout << "data" << data_ << endl;
 | ||||||
|  |     // } catch (exception& err) {
 | ||||||
|  |     //     cout << err.what() << endl;
 | ||||||
|  |     // }
 | ||||||
|  | 
 | ||||||
|  |     // asynco_write("test1.txt", "Hello night", [] (exception* error) {
 | ||||||
|  |     //     if (error) {
 | ||||||
|  |     //         cout << "Error " << error->what() << endl;
 | ||||||
|  |     //     } else {
 | ||||||
|  |     //         cout << "Write successfuly" << endl;
 | ||||||
|  |     //     }
 | ||||||
|  |     // });
 | ||||||
|  | 
 | ||||||
|  |     auto status = asynco_write("test1.txt", "Hello night"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     // try {
 | ||||||
|  |     //     wait(status);
 | ||||||
|  |     // } catch (exception& err) {
 | ||||||
|  |     //     cout << err.what() << endl;
 | ||||||
|  |     // }
 | ||||||
|  | 
 | ||||||
|  |     cout << "Sleep" << endl; | ||||||
|     sleep(100000); // only for testing
 |     sleep(100000); // only for testing
 | ||||||
| 
 | 
 | ||||||
|     return 0; |     return 0; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user