What is Omni?
Omni is an object oriented, cross-platform C++ framework, with recognizable paradigms like managed thread objects, delegates and events, and easy to understand interfaces, Omni enables you to get clean and stable C++ code to a wider market more efficiently while lowering code maintenance costs.
The framework is C++98 compliant1 using platform API's where the C++ STL or standard library can't accommodate2 and allows a developer the ability to customize the framework to their needs. Omni is built and tested to have compatibility on a wide array of platforms and is designed to be compilable "out of the box", that is, after a fresh install of an OS and compiler there's nothing extra to setup or install3; just reference the latest source in your build parameters and compile!
Omni is more than a library, it's a framework of classes and procedures designed to have easy to read structures and give a functional and reusable tool set with less bloat. On top of the various build parameters, you don't need to compile the entire framework and can elect to use the portions of the framework you want leaving the portions you don't. And with it's open design, a developer has the option to build or edit the framework to their specific needs. This gives the developer a more flexible framework to utilize and work with.
Omni aims to make the complex and unique challenges of C++ software development simple and intuitive.
What's the goal?
There are many goals Omni aims for, from simple designs to standards compliance. But one of the major goals of Omni is deterministic behaviour across platforms and compilers.
A compiler can choose to do what it might want at an assembly level to build a binary but it must conform to the C++ standard if it is to be C++ compliant. As such, while the compilers we built and tested against do indeed build conformant code, some (particularly older compilers) had issues with implicitness on certain classes. So while
Similarly, certain platform specific functionality (like threading or synchronization primitives) can vary on their input and output of operations from platform to platform. For example, on Windows platforms you could use a CRITICAL_SECTION to lock an area of code while on POSIX compliant systems (like Linux) you could use a pthread_mutex_t. The
Portions of Omni started before the C++11 standard was finalized, as such, one of the original design goals of Omni was to have as much "out of the box" compatibility as possible with as many platforms and compilers as could be deemed feasible. While the new standards do address some shortcomings of the previous standards libraries, "upgrade your compiler" comes with a completely different set of issues to consider, especially in cross-platform development.
Caveats like these are what can cause build issues and slow downs in production when trying to target your software for multiple platforms, and Omni can help alleviate these problems. Utilizing Omni and it's deterministic classes and functions, you don't have to waste the extra time playing detective to port your application between systems and can be sure the similar concepts (like that of a thread or mutex) are similar across platforms, ensuring you are aware of the consequences of the code across all supported platforms!
top
How did it start?
The framework spawned from an appreciation for events and delegates in .NET, a great appreciation for the C++ language and a deep understanding of the gap in functionally efficient cross platform programming constructs. Dissecting the .NET Framework Class Library and the Common Language Runtime (CLR) (specifically from a C# developers perspective) provided an ability to take the idioms and 'ease of use' of languages like C# and Java and wrap the same contexts in a cross platform framework, making use of standards compliant C++ and any specific system API's needed.
top
Where's it heading?
Omni is designed to afford a user of the framework more resources to develop while using less on design overhead and maintenance. From the delegate and event system to the timers and threads, Omni has begun to grow into a full cross platform framework with the intentions to provide simple to implement C++ code.
Currently the framework is still in Beta while the documentation and base classes are ironed out and finalized. Once the base classes have been vetted and thoroughly tested, goals for future development include sockets, database and extended file handling, XML and regex parsing, and UI (i.e. forms) development.
top
Why no pre-built libraries?
Choosing to develop with C++ can be a daunting undertaking considering the wide array of platforms and capabilities each support. Ensuring you have the right libraries and call the appropriate API for the system you want affects more than just design decisions, it affects its re-usability, maintainability and time to market to name just a few. While pre-compiled libraries are convenient, it can add an extra layer of confusion in the over all process.
Including the full source in your project allows you the control of how your projects will be built, including building your own 'Omni libraries' you can then customize and use as needed. You can visit the options page for more details on how you can customize the framework and you can visit the build section for more on compiling framework, as well for more information about which platforms are currently supported, you can visit the cross platform section.
top
Licensing
Omni has a permissive free license which allows any user of the code to easily integrate the framework as part of their works. This license was chosen to allow greater flexibility in how you see fit to use the code. Open source, closed source, government, finance, web, any area can easily be subject to any number of other licenses or other legal confusion, we'd rather avoid that and give you solid reusable code. We feel that Omni can help teach C++ by giving a familiar context to understand and providing the source in an easy to use format; a budding engineer can pick up the code and gain a deeper understanding for both C++ and system level programming. The license we've chosen helps us reach our goals of enabling and educating, both our users and ourselves.
top
If you have questions, comments or concerns about the framework or would like a further breakdown of a specific aspect please feel free to contact the Omni Q&A email
top
Example
The following is a simple demonstration of Omni to give an example of some of the feature sets the framework can provide. Like most examples this is not intended to demonstrate a "live" example of any real-world code, more of how Omni can be utilized and a demonstration of a few of the classes.
For more, you can visit the examples page or the
class index to browse the framework.
NOTES:
1.) C++98 ISO/IEC 14882:1998
2.) Some functionality is not in the standards library, other functionality is only in later versions and specifying certain compile options can allow the framework to be built with C++11/14/17 extensions enabled, as well as various other build options.
3.) Nothing extra to install except the necessary compiler and system libraries if not installed with the compiler or included with the platform.
top
Omni is an object oriented, cross-platform C++ framework, with recognizable paradigms like managed thread objects, delegates and events, and easy to understand interfaces, Omni enables you to get clean and stable C++ code to a wider market more efficiently while lowering code maintenance costs.
The framework is C++98 compliant1 using platform API's where the C++ STL or standard library can't accommodate2 and allows a developer the ability to customize the framework to their needs. Omni is built and tested to have compatibility on a wide array of platforms and is designed to be compilable "out of the box", that is, after a fresh install of an OS and compiler there's nothing extra to setup or install3; just reference the latest source in your build parameters and compile!
Omni is more than a library, it's a framework of classes and procedures designed to have easy to read structures and give a functional and reusable tool set with less bloat. On top of the various build parameters, you don't need to compile the entire framework and can elect to use the portions of the framework you want leaving the portions you don't. And with it's open design, a developer has the option to build or edit the framework to their specific needs. This gives the developer a more flexible framework to utilize and work with.
Omni aims to make the complex and unique challenges of C++ software development simple and intuitive.
What's the goal?
There are many goals Omni aims for, from simple designs to standards compliance. But one of the major goals of Omni is deterministic behaviour across platforms and compilers.
A compiler can choose to do what it might want at an assembly level to build a binary but it must conform to the C++ standard if it is to be C++ compliant. As such, while the compilers we built and tested against do indeed build conformant code, some (particularly older compilers) had issues with implicitness on certain classes. So while
std::bitset<8>(42).to_string() might build without error on one compiler, another could complain about the
to_string function; to which we had to adjust the code to read
std::bitset<8>(42).to_string<char, std::char_traits<char>, std::allocator<char> >().Similarly, certain platform specific functionality (like threading or synchronization primitives) can vary on their input and output of operations from platform to platform. For example, on Windows platforms you could use a CRITICAL_SECTION to lock an area of code while on POSIX compliant systems (like Linux) you could use a pthread_mutex_t. The
pthread_mutex_t is, by default, a non-recursive lock, so if the same thread were to call lock twice
in a row, a deadlock will occur and the application will hang. This differs from the CRITICAL_SECTION which is re-entrant,
so a thread can call lock twice in a row without a deadlock. In this specific instance the omni::sync::mutex
ensures that the underlying mutex is a recursive mutex to not have a deadlock situation arise and have similar functionality across
platforms.Portions of Omni started before the C++11 standard was finalized, as such, one of the original design goals of Omni was to have as much "out of the box" compatibility as possible with as many platforms and compilers as could be deemed feasible. While the new standards do address some shortcomings of the previous standards libraries, "upgrade your compiler" comes with a completely different set of issues to consider, especially in cross-platform development.
Caveats like these are what can cause build issues and slow downs in production when trying to target your software for multiple platforms, and Omni can help alleviate these problems. Utilizing Omni and it's deterministic classes and functions, you don't have to waste the extra time playing detective to port your application between systems and can be sure the similar concepts (like that of a thread or mutex) are similar across platforms, ensuring you are aware of the consequences of the code across all supported platforms!
top
How did it start?
The framework spawned from an appreciation for events and delegates in .NET, a great appreciation for the C++ language and a deep understanding of the gap in functionally efficient cross platform programming constructs. Dissecting the .NET Framework Class Library and the Common Language Runtime (CLR) (specifically from a C# developers perspective) provided an ability to take the idioms and 'ease of use' of languages like C# and Java and wrap the same contexts in a cross platform framework, making use of standards compliant C++ and any specific system API's needed.
top
Where's it heading?
Omni is designed to afford a user of the framework more resources to develop while using less on design overhead and maintenance. From the delegate and event system to the timers and threads, Omni has begun to grow into a full cross platform framework with the intentions to provide simple to implement C++ code.
Currently the framework is still in Beta while the documentation and base classes are ironed out and finalized. Once the base classes have been vetted and thoroughly tested, goals for future development include sockets, database and extended file handling, XML and regex parsing, and UI (i.e. forms) development.
top
Why no pre-built libraries?
Choosing to develop with C++ can be a daunting undertaking considering the wide array of platforms and capabilities each support. Ensuring you have the right libraries and call the appropriate API for the system you want affects more than just design decisions, it affects its re-usability, maintainability and time to market to name just a few. While pre-compiled libraries are convenient, it can add an extra layer of confusion in the over all process.
Including the full source in your project allows you the control of how your projects will be built, including building your own 'Omni libraries' you can then customize and use as needed. You can visit the options page for more details on how you can customize the framework and you can visit the build section for more on compiling framework, as well for more information about which platforms are currently supported, you can visit the cross platform section.
top
Licensing
Omni has a permissive free license which allows any user of the code to easily integrate the framework as part of their works. This license was chosen to allow greater flexibility in how you see fit to use the code. Open source, closed source, government, finance, web, any area can easily be subject to any number of other licenses or other legal confusion, we'd rather avoid that and give you solid reusable code. We feel that Omni can help teach C++ by giving a familiar context to understand and providing the source in an easy to use format; a budding engineer can pick up the code and gain a deeper understanding for both C++ and system level programming. The license we've chosen helps us reach our goals of enabling and educating, both our users and ourselves.
top
If you have questions, comments or concerns about the framework or would like a further breakdown of a specific aspect please feel free to contact the Omni Q&A email
top
Example
The following is a simple demonstration of Omni to give an example of some of the feature sets the framework can provide. Like most examples this is not intended to demonstrate a "live" example of any real-world code, more of how Omni can be utilized and a demonstration of a few of the classes.
/* main.cpp */ #include <omni/framework> class MyClass { public: MyClass() : m_lock(), m_i(42) { } MyClass(int i) : m_lock(), m_i(i) { } void increment_loop() { std::cout << "entering thread " << omni::sync::thread_id() << std::endl; while (!omni::sync::thread::abort_requested()) { omni::sync::sleep(100); this->m_lock.lock(); ++this->m_i; this->m_lock.unlock(); } std::cout << "leaving thread " << omni::sync::thread_id() << std::endl; } int get_val() const { omni::sync::auto_lock<omni::sync::basic_lock> alock(&this->m_lock); return this->m_i; } OMNI_OSTREAM_OPERATOR(MyClass, get_val()) private: mutable omni::sync::basic_lock m_lock; int m_i; }; static omni::sync::thread* thread2; // timer_delegate is typedef'd as omni::delegate2<void, omni::chrono::tick_t, const omni::generic_ptr&> void timer_tick(omni::chrono::tick_t tick, const omni::generic_ptr& sobj) { static int tval; std::cout << "tick# " << tval << ": val = " << (*static_cast<MyClass*>(sobj)) << std::endl; if (++tval == 5) { std::cout << "requesting abort for thread " << thread2->id() << std::endl; omni::sync::thread::request_abort(thread2->id()); } } void user_thread_exception(const @exception.html">omni::exception& ex) { std::cout << "An exception occurred: " << ex << std::endl; } void thread_exception() { std::cout << "An unknown error occurred." << std::endl; } int main(int argc, char* argv[]) { // Hook up to any unhandled thread exception omni::sync::unhandled_thread_exception += &thread_exception; omni::sync::user_thread_exception += &user_thread_exception; // Our object MyClass val(20); // Create a managed thread on the stack using the thread_start::bind to attach to val omni::sync::thread thread1(omni::sync::thread_start::bind<MyClass, &MyClass::increment_loop>(val)); // Create a managed thread on the heap using allocate_thread template function thread2 = omni::sync::allocate_thread<MyClass, &MyClass::increment_loop>(val, omni::sync::thread_option::AUTO_JOIN, true); // Async timer, tick every second (1000ms == 1s) omni::chrono::async_timer timer(1000); // hook up the tick event and state object to use timer.tick += &timer_tick; timer.state_object = &val; std::cout << "starting val = " << val << std::endl; // output: 20 // start the threads timer.start(); thread1.start(); thread2->start(); std::cout << "thread1: " << thread1.id() << std::endl; std::cout << "thread2: " << thread2->id() << std::endl; std::cout << "val after start = " << val << std::endl; // auto_join = true, so thread2 will join on destruction delete thread2; // we won't get here until the timer has finished std::cout << "val after thread destroy = " << val << std::endl; // abort the thread and wait for it to finish thread1.abort_join(); std::cout << "ending val = " << val << std::endl; return 0; }
NOTES:
1.) C++98 ISO/IEC 14882:1998
2.) Some functionality is not in the standards library, other functionality is only in later versions and specifying certain compile options can allow the framework to be built with C++11/14/17 extensions enabled, as well as various other build options.
3.) Nothing extra to install except the necessary compiler and system libraries if not installed with the compiler or included with the platform.
top