|
|
@@ -5,7 +5,7 @@ Utilities {#utilities}
|
|
|
This manual will quickly go over all the important utility systems commonly used by Banshee. We won't go into major detail about these features, but will rather point you towards the relevant API documentation.
|
|
|
|
|
|
# Module {#utilities_a}
|
|
|
-A @ref BansheeEngine::Module<T> "Module<T>" is a specialized form of singleton used for many of Banshee's systems. Unlike normal singletons it requires manual startup and shutdown, which solves many of the problems associated with traditional singletons.
|
|
|
+A @ref bs::Module<T> "Module<T>" is a specialized form of singleton used for many of Banshee's systems. Unlike normal singletons it requires manual startup and shutdown, which solves many of the problems associated with traditional singletons.
|
|
|
|
|
|
To use it for your own objects, simply inherit from it:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
@@ -13,7 +13,7 @@ class MyModule : public Module<MyModule>
|
|
|
{ };
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
-Use @ref BansheeEngine::Module<T>::startUp "Module<T>::startUp" to start it up. Once started use @ref BansheeEngine::Module<T>::instance "Module<T>::instance" to access its instance. Once done with it call @ref BansheeEngine::Module<T>::shutDown "Module<T>::shutDown" to release it. For example:
|
|
|
+Use @ref bs::Module<T>::startUp "Module<T>::startUp" to start it up. Once started use @ref bs::Module<T>::instance "Module<T>::instance" to access its instance. Once done with it call @ref bs::Module<T>::shutDown "Module<T>::shutDown" to release it. For example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
MyModule::startUp();
|
|
|
MyModule::instance().doSomething();
|
|
|
@@ -21,12 +21,12 @@ MyModule::shutDown();
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
# Path {#utilities_b}
|
|
|
-Use @ref BansheeEngine::Path "Path" to manipulate file/folder paths. Initialize it with a path string and then call various methods to manipulate it. It is recommended to always store paths using @ref BansheeEngine::Path "Path" instead of raw strings.
|
|
|
+Use @ref bs::Path "Path" to manipulate file/folder paths. Initialize it with a path string and then call various methods to manipulate it. It is recommended to always store paths using @ref bs::Path "Path" instead of raw strings.
|
|
|
|
|
|
-Some of the things you can do once a @ref BansheeEngine::Path "Path" is constructed:
|
|
|
- - Retrieve the filename using @ref BansheeEngine::Path::getFilename "Path::getFilename"
|
|
|
- - Retrieve the filename extension using @ref BansheeEngine::Path::getExtension "Path::getExtension"
|
|
|
- - Get last element of path, either file or directory using @ref BansheeEngine::Path::getTail "Path::getTail"
|
|
|
+Some of the things you can do once a @ref bs::Path "Path" is constructed:
|
|
|
+ - Retrieve the filename using @ref bs::Path::getFilename "Path::getFilename"
|
|
|
+ - Retrieve the filename extension using @ref bs::Path::getExtension "Path::getExtension"
|
|
|
+ - Get last element of path, either file or directory using @ref bs::Path::getTail "Path::getTail"
|
|
|
- Iterate over directories, get drive, combine paths, convert relative to absolute paths and vice versa, and more...
|
|
|
|
|
|
For example:
|
|
|
@@ -42,14 +42,14 @@ Path b("File.txt");
|
|
|
Path combined = a + b; // // Path is now "C:\Path\To\File.txt"
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
-All @ref BansheeEngine::Path "Path" methods that return strings come in two variants, one that returns a narrow (8-bit) character string like @ref BansheeEngine::Path::getFilename "Path::getFilename", and one that contains wide character string like @ref BansheeEngine::Path::getWFilename "Path::getWFilename".
|
|
|
+All @ref bs::Path "Path" methods that return strings come in two variants, one that returns a narrow (8-bit) character string like @ref bs::Path::getFilename "Path::getFilename", and one that contains wide character string like @ref bs::Path::getWFilename "Path::getWFilename".
|
|
|
|
|
|
When setting paths be careful with setting backslashes or slashes at the end of the path. Path with a no backslash/slash on the end will be interpreted as a file path, and path with a backslash/slash will be interpreted as a folder path. For example:
|
|
|
- - "C:\MyFolder" - "MyFolder" interpreted as a file, @ref BansheeEngine::Path::getFilename "Path::getFilename" returns "MyFolder"
|
|
|
- - "C:\MyFolder\" - "MyFolder" interpreted as a folder, @ref BansheeEngine::Path::getFilename "Path::getFilename" returns an empty string
|
|
|
+ - "C:\MyFolder" - "MyFolder" interpreted as a file, @ref bs::Path::getFilename "Path::getFilename" returns "MyFolder"
|
|
|
+ - "C:\MyFolder\" - "MyFolder" interpreted as a folder, @ref bs::Path::getFilename "Path::getFilename" returns an empty string
|
|
|
|
|
|
# File system {#utilities_c}
|
|
|
-The @ref BansheeEngine::FileSystem "FileSystem" module allows you to open and create files, create folders, move/copy/remove files and folders, iterate all folder/files in a folder, get file size, check if folder/folder exists, get working path and others.
|
|
|
+The @ref bs::FileSystem "FileSystem" module allows you to open and create files, create folders, move/copy/remove files and folders, iterate all folder/files in a folder, get file size, check if folder/folder exists, get working path and others.
|
|
|
|
|
|
An example creating a folder and a file:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
@@ -58,9 +58,9 @@ SPtr<DataStream> fileStream = FileSystem::createAndOpenFile("C:\\Path\\To\\File.
|
|
|
... write to data stream...
|
|
|
~~~~~~~~~~~~~
|
|
|
# Data streams {#utilities_d}
|
|
|
-@ref BansheeEngine::DataStream "Data streams" allow you to easily write/read binary/text data from/to disk/memory/etc. The two primary types of streams are @ref BansheeEngine::MemoryDataStream "MemoryDataStream" for reading/writing directly to memory, and @ref BansheeEngine::FileDataStream "FileDataStream" for reading/writing to a file.
|
|
|
+@ref bs::DataStream "Data streams" allow you to easily write/read binary/text data from/to disk/memory/etc. The two primary types of streams are @ref bs::MemoryDataStream "MemoryDataStream" for reading/writing directly to memory, and @ref bs::FileDataStream "FileDataStream" for reading/writing to a file.
|
|
|
|
|
|
-You create memory streams by providing them with a pointer and size of a memory buffer, while you create file streams by calling @ref BansheeEngine::FileSystem::openFile "FileSystem::openFile" or @ref BansheeEngine::FileSystem::createAndOpenFile "FileSystem::createAndOpenFile". Once you are done with a stream make sure to close it by calling @ref BansheeEngine::DataStream::close "DataStream::close". Stream will also be automatically closed when it goes out of scope.
|
|
|
+You create memory streams by providing them with a pointer and size of a memory buffer, while you create file streams by calling @ref bs::FileSystem::openFile "FileSystem::openFile" or @ref bs::FileSystem::createAndOpenFile "FileSystem::createAndOpenFile". Once you are done with a stream make sure to close it by calling @ref bs::DataStream::close "DataStream::close". Stream will also be automatically closed when it goes out of scope.
|
|
|
|
|
|
Once you have a stream you can seek to a position within a stream and read/write to it. For example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
@@ -76,7 +76,7 @@ fileStream.close();
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
# Events {#utilities_e}
|
|
|
-@ref BansheeEngine::TEvent<RetType, Args> "Events" allow your objects to expose events that may trigger during execution. External objects interested in those events can then register callbacks with those events and be notified when they happen. They are useful because they allow two objects to communicate without necessarily knowing about each other's types, which can reduce class coupling and improve design.
|
|
|
+@ref bs::TEvent<RetType, Args> "Events" allow your objects to expose events that may trigger during execution. External objects interested in those events can then register callbacks with those events and be notified when they happen. They are useful because they allow two objects to communicate without necessarily knowing about each other's types, which can reduce class coupling and improve design.
|
|
|
|
|
|
When creating an event, all you need to do it specify a format of the callback it sends out, for example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
@@ -87,7 +87,7 @@ class MySystem
|
|
|
};
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
-Then an external object can register itself with an event by calling @ref BansheeEngine::TEvent<RetType, Args> "Event::connect". This method will return an @ref BansheeEngine::HEvent "HEvent" handle. You can use this handle to manually disconnect from the event by calling @ref BansheeEngine::HEvent::disconnect "HEvent::disconnect". For example:
|
|
|
+Then an external object can register itself with an event by calling @ref bs::TEvent<RetType, Args> "Event::connect". This method will return an @ref bs::HEvent "HEvent" handle. You can use this handle to manually disconnect from the event by calling @ref bs::HEvent::disconnect "HEvent::disconnect". For example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
// Subscribe to an event we defined previously
|
|
|
// Simply pass a function pointer matching the callback
|
|
|
@@ -124,7 +124,7 @@ MySystem::myEvent2(5); // Trigger an event with a single argument
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
# Any {#utilities_f}
|
|
|
-Use the @ref BansheeEngine::Any "Any" type to easily store any kind of object in it. For example:
|
|
|
+Use the @ref bs::Any "Any" type to easily store any kind of object in it. For example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
Any var1 = Vector<String>();
|
|
|
|
|
|
@@ -132,13 +132,13 @@ struct MyStruct { int a; };
|
|
|
Any var2 = MyStruct();
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
-Use @ref BansheeEngine::any_cast "any_cast" and @ref BansheeEngine::any_cast_ref "any_cast_ref" to retrieve valid types from an @ref BansheeEngine::Any "Any" variable. For example:
|
|
|
+Use @ref bs::any_cast "any_cast" and @ref bs::any_cast_ref "any_cast_ref" to retrieve valid types from an @ref bs::Any "Any" variable. For example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
Vector<String> val1 = any_cast<Vector<String>>(var1);
|
|
|
MyStruct& val2 = any_cast_ref<MyStruct>(var2);
|
|
|
~~~~~~~~~~~~~
|
|
|
# Flags {#utilities_g}
|
|
|
-@ref BansheeEngine::Flags<Enum, Storage> "Flags" provide a wrapper around an `enum` and allow you to easily perform bitwise operations on them without having to cast to integers. For example when using raw C++ you must do something like this:
|
|
|
+@ref bs::Flags<Enum, Storage> "Flags" provide a wrapper around an `enum` and allow you to easily perform bitwise operations on them without having to cast to integers. For example when using raw C++ you must do something like this:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
enum class MyFlag
|
|
|
{
|
|
|
@@ -152,7 +152,7 @@ MyFlag combined = (MyFlag)((UINT32)MyFlag::Flag1 | (UINT32)MyFlag::Flag2);
|
|
|
|
|
|
Which is cumbersome. Flags require an additional step to define the enum, but after that allow you to manipulate values much more nicely.
|
|
|
|
|
|
-To create @ref BansheeEngine::Flags<Enum, Storage> "Flags" for an enum simply define a `typedef` with your enum type provided as the template parameter. You must also follow that definition with a @ref BS_FLAGS_OPERATORS macro in order to ensure all operators are properly defined. For example:
|
|
|
+To create @ref bs::Flags<Enum, Storage> "Flags" for an enum simply define a `typedef` with your enum type provided as the template parameter. You must also follow that definition with a @ref BS_FLAGS_OPERATORS macro in order to ensure all operators are properly defined. For example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
typedef Flags<MyFlag> MyFlags;
|
|
|
BS_FLAGS_OPERATORS(MyFlag)
|
|
|
@@ -163,18 +163,18 @@ Now you can do something like this:
|
|
|
MyFlags combined = MyFlag::Flag1 | MyFlag::Flag2;
|
|
|
~~~~~~~~~~~~~
|
|
|
# String {#utilities_h}
|
|
|
-Banshee uses @ref BansheeEngine::String "String" for narrow character strings (8-bit) and @ref BansheeEngine::WString "WString" for wide character strings. Wide character strings are different size depending on platform.
|
|
|
+Banshee uses @ref bs::String "String" for narrow character strings (8-bit) and @ref bs::WString "WString" for wide character strings. Wide character strings are different size depending on platform.
|
|
|
|
|
|
-A variety of string manipulation functionality is provided in @ref BansheeEngine::StringUtil "StringUtil", like matching, replacing, comparing, formating and similar.
|
|
|
+A variety of string manipulation functionality is provided in @ref bs::StringUtil "StringUtil", like matching, replacing, comparing, formating and similar.
|
|
|
|
|
|
-Conversion between various types (like int, float, bool, etc.) and string is provided via overloads of @ref BansheeEngine::toString "toString" and @ref BansheeEngine::toWString "toWString". You can also convert strings into different types by calling methods like @ref BansheeEngine::parseINT32 "parseINT32", @ref BansheeEngine::parseBool "parseBool", and similar for other types.
|
|
|
+Conversion between various types (like int, float, bool, etc.) and string is provided via overloads of @ref bs::toString "toString" and @ref bs::toWString "toWString". You can also convert strings into different types by calling methods like @ref bs::parseINT32 "parseINT32", @ref bs::parseBool "parseBool", and similar for other types.
|
|
|
|
|
|
# Threading {#utilities_i}
|
|
|
## Primitives {#utilities_i_a}
|
|
|
This section describes the most basic primitives you can use to manipulate threads. All threading primitives use the standard C++ library constructs, so for more information you should read their documentation.
|
|
|
|
|
|
### Thread {#utilities_i_a_a}
|
|
|
-To create a new thread use @ref BansheeEngine::Thread "Thread", like so:
|
|
|
+To create a new thread use @ref bs::Thread "Thread", like so:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
void workerFunc()
|
|
|
{
|
|
|
@@ -185,7 +185,7 @@ Thread myThread(&workerFunc);
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
### Mutex {#utilities_i_a_b}
|
|
|
-Use @ref BansheeEngine::Mutex "Mutex" and @ref BansheeEngine::Lock "Lock" to synchronize access between multiple threads, like so:
|
|
|
+Use @ref bs::Mutex "Mutex" and @ref bs::Lock "Lock" to synchronize access between multiple threads, like so:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
Vector<int> output;
|
|
|
int startIdx = 0;
|
|
|
@@ -204,10 +204,10 @@ Thread threadA(&workerFunc);
|
|
|
Thread threadB(&workerFunc);
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
-If a mutex can be locked recursively, use @ref BansheeEngine::RecursiveMutex "RecursiveMutex" and @ref BansheeEngine::RecursiveLock "RecursiveLock" instead.
|
|
|
+If a mutex can be locked recursively, use @ref bs::RecursiveMutex "RecursiveMutex" and @ref bs::RecursiveLock "RecursiveLock" instead.
|
|
|
|
|
|
### Signal {#utilities_i_a_c}
|
|
|
-Use @ref BansheeEngine::Signal "Signal" to pause thread execution until another thread reaches a certain point. For example:
|
|
|
+Use @ref bs::Signal "Signal" to pause thread execution until another thread reaches a certain point. For example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
bool isReady = false;
|
|
|
int result = 0;
|
|
|
@@ -242,11 +242,11 @@ if(!isReady)
|
|
|
### Other {#utilities_i_a_d}
|
|
|
The previous sections covered all the primitives, but there is some more useful functionality to be aware of:
|
|
|
- @ref BS_THREAD_HARDWARE_CONCURRENCY - Returns number of logical CPU cores.
|
|
|
- - @ref BS_THREAD_CURRENT_ID - Returns @ref BansheeEngine::ThreadId "ThreadId" of the current thread.
|
|
|
+ - @ref BS_THREAD_CURRENT_ID - Returns @ref bs::ThreadId "ThreadId" of the current thread.
|
|
|
- @ref BS_THREAD_SLEEP - Pauses the current thread for a set number of milliseconds.
|
|
|
|
|
|
## Thread pool {#utilities_i_b}
|
|
|
-Instead of using @ref BansheeEngine::Thread "Thread" as described in the previous section, you should instead use @ref BansheeEngine::ThreadPool "ThreadPool" for running threads. @ref BansheeEngine::ThreadPool "ThreadPool" allows you to re-use threads and avoid paying the cost of thread creation and destruction. It keeps any thread that was retired in idle state, and will re-use it when user requests a new thread.
|
|
|
+Instead of using @ref bs::Thread "Thread" as described in the previous section, you should instead use @ref bs::ThreadPool "ThreadPool" for running threads. @ref bs::ThreadPool "ThreadPool" allows you to re-use threads and avoid paying the cost of thread creation and destruction. It keeps any thread that was retired in idle state, and will re-use it when user requests a new thread.
|
|
|
|
|
|
An example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
@@ -259,9 +259,9 @@ ThreadPool::instance().run("MyThread", &workerFunc);
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
## Task scheduler {#utilities_i_c}
|
|
|
-@ref BansheeEngine::TaskScheduler "TaskScheduler" allows even more fine grained control over threads. It ensures there are only as many threads as the number of logical CPU cores. This ensures good thread distribution accross the cores, so that multiple threads don't fight for resources on the same core.
|
|
|
+@ref bs::TaskScheduler "TaskScheduler" allows even more fine grained control over threads. It ensures there are only as many threads as the number of logical CPU cores. This ensures good thread distribution accross the cores, so that multiple threads don't fight for resources on the same core.
|
|
|
|
|
|
-It accomplishes that by storing each worker function as a @ref BansheeEngine::Task "Task". It then dispatches tasks to threads that are free. In case tasks are dependant on one another you may also provide task dependencies, as well as task priorities.
|
|
|
+It accomplishes that by storing each worker function as a @ref bs::Task "Task". It then dispatches tasks to threads that are free. In case tasks are dependant on one another you may also provide task dependencies, as well as task priorities.
|
|
|
|
|
|
An example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
@@ -276,50 +276,50 @@ TaskScheduler::instance().addTask(task);
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
# Math {#utilities_j}
|
|
|
-Majority of the math related functionality is located in the @ref BansheeEngine::Math "Math" class.
|
|
|
+Majority of the math related functionality is located in the @ref bs::Math "Math" class.
|
|
|
|
|
|
Some other useful math classes are:
|
|
|
- - @ref BansheeEngine::Vector2 "Vector2"
|
|
|
- - @ref BansheeEngine::Vector3 "Vector3"
|
|
|
- - @ref BansheeEngine::Vector4 "Vector4"
|
|
|
- - @ref BansheeEngine::Matrix3 "Matrix3"
|
|
|
- - @ref BansheeEngine::Matrix4 "Matrix4"
|
|
|
- - @ref BansheeEngine::Quaternion "Quaternion"
|
|
|
- - @ref BansheeEngine::Radian "Radian"
|
|
|
- - @ref BansheeEngine::Degree "Degree"
|
|
|
- - @ref BansheeEngine::Ray "Ray"
|
|
|
- - @ref BansheeEngine::Plane "Plane"
|
|
|
- - @ref BansheeEngine::Rect2 "Rect2"
|
|
|
- - @ref BansheeEngine::Rect2I "Rect2I"
|
|
|
- - @ref BansheeEngine::Vector2I "Vector2I"
|
|
|
+ - @ref bs::Vector2 "Vector2"
|
|
|
+ - @ref bs::Vector3 "Vector3"
|
|
|
+ - @ref bs::Vector4 "Vector4"
|
|
|
+ - @ref bs::Matrix3 "Matrix3"
|
|
|
+ - @ref bs::Matrix4 "Matrix4"
|
|
|
+ - @ref bs::Quaternion "Quaternion"
|
|
|
+ - @ref bs::Radian "Radian"
|
|
|
+ - @ref bs::Degree "Degree"
|
|
|
+ - @ref bs::Ray "Ray"
|
|
|
+ - @ref bs::Plane "Plane"
|
|
|
+ - @ref bs::Rect2 "Rect2"
|
|
|
+ - @ref bs::Rect2I "Rect2I"
|
|
|
+ - @ref bs::Vector2I "Vector2I"
|
|
|
|
|
|
# Time {#utilities_k}
|
|
|
-To access timing information use the @ref BansheeEngine::Time "Time" module, more easily accessible via @ref BansheeEngine::gTime "gTime" method:
|
|
|
- - @ref BansheeEngine::Time::getTime "Time::getTime" - Returns time since start-up in seconds, updated once per frame.
|
|
|
- - @ref BansheeEngine::Time::getFrameDelta "Time::getFrameDelta" - Returns the time between execution of this and last frame.
|
|
|
- - @ref BansheeEngine::Time::getFrameIdx "Time::getFrameIdx" - Returns a sequential index of the current frame.
|
|
|
- - @ref BansheeEngine::Time::getTimePrecise "Time::getTimePrecise" - Returns time suitable for precision measurements. Returns time at the exact time it was called, instead of being updated once per frame.
|
|
|
+To access timing information use the @ref bs::Time "Time" module, more easily accessible via @ref bs::gTime "gTime" method:
|
|
|
+ - @ref bs::Time::getTime "Time::getTime" - Returns time since start-up in seconds, updated once per frame.
|
|
|
+ - @ref bs::Time::getFrameDelta "Time::getFrameDelta" - Returns the time between execution of this and last frame.
|
|
|
+ - @ref bs::Time::getFrameIdx "Time::getFrameIdx" - Returns a sequential index of the current frame.
|
|
|
+ - @ref bs::Time::getTimePrecise "Time::getTimePrecise" - Returns time suitable for precision measurements. Returns time at the exact time it was called, instead of being updated once per frame.
|
|
|
|
|
|
# Logging {#utilities_l}
|
|
|
-To report warnings and errors use the @ref BansheeEngine::Debug "Debug" module. Call @ref BansheeEngine::Debug::logDebug "Debug::logDebug", @ref BansheeEngine::Debug::logWarning "Debug::logWarning" and @ref BansheeEngine::Debug::logError "Debug::logError" to log messages.
|
|
|
+To report warnings and errors use the @ref bs::Debug "Debug" module. Call @ref bs::Debug::logDebug "Debug::logDebug", @ref bs::Debug::logWarning "Debug::logWarning" and @ref bs::Debug::logError "Debug::logError" to log messages.
|
|
|
|
|
|
-Use @ref BansheeEngine::Debug::saveLog "Debug::saveLog" to save a log to the disk in HTML format. Use use @ref BansheeEngine::Debug::getLog "Debug::getLog" to get a @ref BansheeEngine::Log "Log" object you can manually parse.
|
|
|
+Use @ref bs::Debug::saveLog "Debug::saveLog" to save a log to the disk in HTML format. Use use @ref bs::Debug::getLog "Debug::getLog" to get a @ref bs::Log "Log" object you can manually parse.
|
|
|
|
|
|
Macros for common log operations are also provided: @ref LOGDBG, @ref LOGWRN and @ref LOGERR. They're equivalent to the methods above.
|
|
|
|
|
|
# Crash handling {#utilities_m}
|
|
|
-Use the @ref BansheeEngine::CrashHandler "CrashHandler" to report fatal errors. Call @ref BansheeEngine::CrashHandler::reportCrash "CrashHandler::reportCrash" to manually trigger such an error. An error will be logged, a message box with relevant information displayed and the application terminated.
|
|
|
+Use the @ref bs::CrashHandler "CrashHandler" to report fatal errors. Call @ref bs::CrashHandler::reportCrash "CrashHandler::reportCrash" to manually trigger such an error. An error will be logged, a message box with relevant information displayed and the application terminated.
|
|
|
|
|
|
-You can also use @ref BS_EXCEPT macro, which internally calls @ref BansheeEngine::CrashHandler::reportCrash "CrashHandler::reportCrash" but automatically adds file/line information.
|
|
|
+You can also use @ref BS_EXCEPT macro, which internally calls @ref bs::CrashHandler::reportCrash "CrashHandler::reportCrash" but automatically adds file/line information.
|
|
|
|
|
|
-@ref BansheeEngine::CrashHandler "CrashHandler" also provides @ref BansheeEngine::CrashHandler::getStackTrace "CrashHandler::getStackTrace" that allows you to retrieve a stack trace to the current method.
|
|
|
+@ref bs::CrashHandler "CrashHandler" also provides @ref bs::CrashHandler::getStackTrace "CrashHandler::getStackTrace" that allows you to retrieve a stack trace to the current method.
|
|
|
|
|
|
# Dynamic libraries {#utilities_n}
|
|
|
-Use @ref BansheeEngine::DynLibManager "DynLibManager" to load dynamic libraries (.dll, .so). It has two main methods:
|
|
|
- - @ref BansheeEngine::DynLibManager::load "DynLibManager::load" - Accepts a file name to the library, and returns the @ref BansheeEngine::DynLib "DynLib" object if the load is successful or null otherwise.
|
|
|
- - @ref BansheeEngine::DynLibManager::unload "DynLibManager::unload" - Unloads a previously loaded library.
|
|
|
+Use @ref bs::DynLibManager "DynLibManager" to load dynamic libraries (.dll, .so). It has two main methods:
|
|
|
+ - @ref bs::DynLibManager::load "DynLibManager::load" - Accepts a file name to the library, and returns the @ref bs::DynLib "DynLib" object if the load is successful or null otherwise.
|
|
|
+ - @ref bs::DynLibManager::unload "DynLibManager::unload" - Unloads a previously loaded library.
|
|
|
|
|
|
-Once the library is loaded you can use the @ref BansheeEngine::DynLib "DynLib" object, and its @ref BansheeEngine::DynLib::getSymbol "DynLib::getSymbol" method to retrieve a function pointer within the dynamic library, and call into it. For example if we wanted to retrieve a function pointer for the `loadPlugin` method:
|
|
|
+Once the library is loaded you can use the @ref bs::DynLib "DynLib" object, and its @ref bs::DynLib::getSymbol "DynLib::getSymbol" method to retrieve a function pointer within the dynamic library, and call into it. For example if we wanted to retrieve a function pointer for the `loadPlugin` method:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
// Load library
|
|
|
DynLib* myLibrary = DynLibManager::instance().load("myPlugin");
|
|
|
@@ -336,7 +336,7 @@ DynLibManager::instance().unload(myLibrary);
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
# Testing {#utilities_o}
|
|
|
-Implement @ref BansheeEngine::TestSuite "TestSuite" to set up unit tests for your application. To register new tests call @ref BS_ADD_TEST. Test is assumed to succeed unless either @ref BS_TEST_ASSERT or @ref BS_TEST_ASSERT_MSG are triggered.
|
|
|
+Implement @ref bs::TestSuite "TestSuite" to set up unit tests for your application. To register new tests call @ref BS_ADD_TEST. Test is assumed to succeed unless either @ref BS_TEST_ASSERT or @ref BS_TEST_ASSERT_MSG are triggered.
|
|
|
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
class MyTestSuite : TestSuite
|
|
|
@@ -355,20 +355,20 @@ private:
|
|
|
};
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
-To run all tests create a instance of the @ref BansheeEngine::TestSuite "TestSuite" and run it, like so:
|
|
|
+To run all tests create a instance of the @ref bs::TestSuite "TestSuite" and run it, like so:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
SPtr<TestSuite> tests = MyTestSuite::create<MyTestSuite>();
|
|
|
tests->run(ExceptionTestOutput());
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
-When running the test we provide @ref BansheeEngine::ExceptionTestOutput "ExceptionTestOutput" which tells the test runner to terminate the application when a test fails. You can implement your own @ref BansheeEngine::TestOutput "TestOutput" to handle test failure more gracefully.
|
|
|
+When running the test we provide @ref bs::ExceptionTestOutput "ExceptionTestOutput" which tells the test runner to terminate the application when a test fails. You can implement your own @ref bs::TestOutput "TestOutput" to handle test failure more gracefully.
|
|
|
|
|
|
# Allocators {#utilities_p}
|
|
|
Banshee allows you to allocate memory in various ways, so you can have fast memory allocations for many situations.
|
|
|
## General {#utilities_p_a}
|
|
|
-The most common memory allocation operations are `new`/`delete` or `malloc`/`free`. Banshee provides its own wrappers for these methods as @ref BansheeEngine::bs_new "bs_new"/@ref BansheeEngine::bs_delete "bs_delete" and @ref BansheeEngine::bs_alloc "bs_alloc"/@ref BansheeEngine::bs_free "bs_free". They provide the same functionality but make it possible for Banshee to track memory allocations which can be useful for profiling and debugging. You should always use them instead of the standard ones.
|
|
|
+The most common memory allocation operations are `new`/`delete` or `malloc`/`free`. Banshee provides its own wrappers for these methods as @ref bs::bs_new "bs_new"/@ref bs::bs_delete "bs_delete" and @ref bs::bs_alloc "bs_alloc"/@ref bs::bs_free "bs_free". They provide the same functionality but make it possible for Banshee to track memory allocations which can be useful for profiling and debugging. You should always use them instead of the standard ones.
|
|
|
|
|
|
-Use @ref BansheeEngine::bs_newN "bs_newN"/@ref BansheeEngine::bs_deleteN "bs_deleteN" to create and delete arrays of objects.
|
|
|
+Use @ref bs::bs_newN "bs_newN"/@ref bs::bs_deleteN "bs_deleteN" to create and delete arrays of objects.
|
|
|
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
UINT8* buffer = (UINT8*)bs_alloc(1024); // Allocate a raw buffer of 1024 bytes.
|
|
|
@@ -386,7 +386,7 @@ Stack allocator allows you to allocate memory quickly, usually without a call to
|
|
|
|
|
|
However it comes with a downside that it can only deallocate memory in the opposite order it was allocated. This usually only makes it suitable for temporary allocations within a single method, where you can guarantee the proper order.
|
|
|
|
|
|
-Use @ref BansheeEngine::bs_stack_alloc "bs_stack_alloc" / @ref BansheeEngine::bs_stack_free "bs_stack_free" and @ref BansheeEngine::bs_stack_new "bs_stack_new" / @ref BansheeEngine::bs_stack_delete "bs_stack_delete" to allocate/free memory using the stack allocator.
|
|
|
+Use @ref bs::bs_stack_alloc "bs_stack_alloc" / @ref bs::bs_stack_free "bs_stack_free" and @ref bs::bs_stack_new "bs_stack_new" / @ref bs::bs_stack_delete "bs_stack_delete" to allocate/free memory using the stack allocator.
|
|
|
|
|
|
For example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
@@ -405,9 +405,9 @@ Frame allocator segments all allocated memory into "frames". These frames are st
|
|
|
|
|
|
This releases the restriction that memory must be freed in the order it was allocated, which makes the allocator usable in more situations, but it also means that a lot of memory might be wasted as unused memory will be kept until the entire frame is freed.
|
|
|
|
|
|
-Use @ref BansheeEngine::bs_frame_alloc "bs_frame_alloc" / @ref BansheeEngine::bs_frame_free "bs_frame_free" or @ref BansheeEngine::bs_frame_new "bs_frame_new" / @ref BansheeEngine::bs_frame_delete "bs_frame_delete" to allocate/free memory using the frame allocator. Calls to @ref BansheeEngine::bs_frame_free "bs_frame_free" / @ref BansheeEngine::bs_frame_delete "bs_frame_delete" are required even through the frame allocator doesn't process individual deallocations, and this is used primarily for debug purposes.
|
|
|
+Use @ref bs::bs_frame_alloc "bs_frame_alloc" / @ref bs::bs_frame_free "bs_frame_free" or @ref bs::bs_frame_new "bs_frame_new" / @ref bs::bs_frame_delete "bs_frame_delete" to allocate/free memory using the frame allocator. Calls to @ref bs::bs_frame_free "bs_frame_free" / @ref bs::bs_frame_delete "bs_frame_delete" are required even through the frame allocator doesn't process individual deallocations, and this is used primarily for debug purposes.
|
|
|
|
|
|
-Use @ref BansheeEngine::bs_frame_mark "bs_frame_mark" to start a new frame. All frame allocations should happen after this call. If you don't call @ref BansheeEngine::bs_frame_mark "bs_frame_mark" a global frame will be used. Once done with your calculations use @ref BansheeEngine::bs_frame_clear "bs_frame_clear" to free all memory in the current frame. The frames have to be released in opposite order they were created.
|
|
|
+Use @ref bs::bs_frame_mark "bs_frame_mark" to start a new frame. All frame allocations should happen after this call. If you don't call @ref bs::bs_frame_mark "bs_frame_mark" a global frame will be used. Once done with your calculations use @ref bs::bs_frame_clear "bs_frame_clear" to free all memory in the current frame. The frames have to be released in opposite order they were created.
|
|
|
|
|
|
For example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
@@ -422,9 +422,9 @@ bs_frame_free(buffer2); // Only does some checks in debug mode, doesn't actually
|
|
|
bs_frame_clear(); // Frees memory for both buffers
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
-You can also create your own frame allocators by constructing a @ref BansheeEngine::FrameAlloc "FrameAlloc" and calling memory management methods on it directly. This can allow you to use a frame allocator on a more global scope. For example if you are running some complex algorithm involving multiple classes you might create a frame allocator to be used throughout the algorithm, and then just free all the memory at once when the algorithm finishes.
|
|
|
+You can also create your own frame allocators by constructing a @ref bs::FrameAlloc "FrameAlloc" and calling memory management methods on it directly. This can allow you to use a frame allocator on a more global scope. For example if you are running some complex algorithm involving multiple classes you might create a frame allocator to be used throughout the algorithm, and then just free all the memory at once when the algorithm finishes.
|
|
|
|
|
|
-You may also use frame allocator to allocate containers like @ref BansheeEngine::String "String", @ref BansheeEngine::Vector "Vector" or @ref BansheeEngine::Map "Map". Simply mark the frame as in the above example, and then use the following container alternatives: @ref BansheeEngine::String "FrameString", @ref BansheeEngine::FrameVector "FrameVector" or @ref BansheeEngine::FrameMap "FrameMap" (other container types also available). For example:
|
|
|
+You may also use frame allocator to allocate containers like @ref bs::String "String", @ref bs::Vector "Vector" or @ref bs::Map "Map". Simply mark the frame as in the above example, and then use the following container alternatives: @ref bs::String "FrameString", @ref bs::FrameVector "FrameVector" or @ref bs::FrameMap "FrameMap" (other container types also available). For example:
|
|
|
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
// Mark a new frame
|
|
|
@@ -437,7 +437,7 @@ bs_frame_clear(); // Frees memory for the vector
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
## Static {#utilities_p_d}
|
|
|
-@ref BansheeEngine::StaticAlloc<BlockSize, MaxDynamicMemory> "Static allocator" is the only specialized type of allocator that is used for permanent allocations. It allows you to pre-allocate a static buffer on the internal stack. It will then use internal stack memory until it runs out, after which it will use normal dynamic allocations. If you can predict a good static buffer size you can guarantee that most of your objects don't allocate any heap memory, while wasting minimum memory on the stack. This kind of allocator is mostly useful when you have many relatively small objects, each of which requires dynamic allocation of a different size.
|
|
|
+@ref bs::StaticAlloc<BlockSize, MaxDynamicMemory> "Static allocator" is the only specialized type of allocator that is used for permanent allocations. It allows you to pre-allocate a static buffer on the internal stack. It will then use internal stack memory until it runs out, after which it will use normal dynamic allocations. If you can predict a good static buffer size you can guarantee that most of your objects don't allocate any heap memory, while wasting minimum memory on the stack. This kind of allocator is mostly useful when you have many relatively small objects, each of which requires dynamic allocation of a different size.
|
|
|
|
|
|
An example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|
|
|
@@ -461,7 +461,7 @@ class MyObj
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
## Shared pointers {#utilities_p_e}
|
|
|
-Shared pointers are smart pointers that will automatically free memory when the last reference to the pointed memory goes out of scope. They're implemented as @ref BansheeEngine::SPtr "SPtr", which is just a wrapper for the standard C++ library `std::shared_ptr`. Use @ref BansheeEngine::bs_shared_ptr_new "bs_shared_ptr_new" to create a new shared pointer, or @ref BansheeEngine::bs_shared_ptr "bs_shared_ptr" to create one from an existing instance. The pointer memory is allocated and freed using the general allocator.
|
|
|
+Shared pointers are smart pointers that will automatically free memory when the last reference to the pointed memory goes out of scope. They're implemented as @ref bs::SPtr "SPtr", which is just a wrapper for the standard C++ library `std::shared_ptr`. Use @ref bs::bs_shared_ptr_new "bs_shared_ptr_new" to create a new shared pointer, or @ref bs::bs_shared_ptr "bs_shared_ptr" to create one from an existing instance. The pointer memory is allocated and freed using the general allocator.
|
|
|
|
|
|
For example:
|
|
|
~~~~~~~~~~~~~{.cpp}
|