BearishSun 9 лет назад
Родитель
Сommit
9a41fe02f1

+ 33 - 0
Documentation/Manuals/Native/User/containers.md

@@ -0,0 +1,33 @@
+Containers 						{#containers}
+===============
+
+Containers are data types that contain a set of elements. Banshee uses wrappers for C++ standard library containers like vector, set or map. Aside from different names Banshee containers act exactly like standard library containers.
+
+All available containers:
+ - @ref bs::Vector "Vector" - A sequential list of elements. Fast iteration, slow lookup, slow insertion/deletion (except for the last element).
+ - @ref bs::List "List" - A sequential list of elements. Slow iteration, slow lookup, fast insertion/deletion for all elements.
+ - @ref bs::Stack "Stack" - A collection of elements where elements can only be retrieved and inserted in a specific order. Last element inserted is always the first element retrieved.
+ - @ref bs::Queue "Queue" - A collection of elements where elements can only be retrieved and inserted in a specific order. First element inserted is always the first element retrieved.
+ - @ref bs::Set "Set" - An ordered list of elements. Fast iteration, fast lookup, mediocre insertion/deletion.
+ - @ref bs::Map "Map" - Same as **Set**, only each element is represented as a key-value pair, while **Set** only contains keys.
+ - @ref bs::UnorderedSet "UnorderedSet" - Similar to **Set** it allows fast lookup, but elements aren't sorted. In general offers better performance than **Set**.
+ - @ref bs::UnorderedMap "UnorderedMap" - Same as **UnorderedSet**, only each element is represented as a key-value pair, while **Set** only contains keys.
+ 
+An example with a vector and an unordered map:
+~~~~~~~~~~~~~{.cpp}
+int nextUserId = 0;
+Vector<String> userNames = { "Sleepy", "Grumpy", "Dopey" };
+
+// Generate IDs for each user and store them in a map for quick lookup.
+UnorderedMap<String, int> users;
+for(auto& entry : userNames)
+	users[entry] = nextUserId++;
+
+// Perform lookup to check if user exists
+auto iterFind = users.find("Sneezy");
+if(iterFind != users.end())
+{
+	// User exists
+	int userId = iterFind->second;
+}
+~~~~~~~~~~~~~

+ 41 - 0
Documentation/Manuals/Native/User/memory.md

@@ -0,0 +1,41 @@
+Memory allocation 						{#memory}
+===============
+When allocating memory in Banshee it is prefered (but not required) to use Banshee's allocator functions instead of the standard *new* / *delete* operators or *malloc* / *free*.
+
+Use @ref bs::bs_new "bs_new" instead of *new* and @ref bs::bs_delete "bs_delete" instead of *delete*.
+Use @ref bs::bs_newN "bs_newN" instead of *new[]* and @ref bs::bs_deleteN "bs_deleteN" instead of *delete[]*.
+Use @ref bs::bs_alloc "bs_alloc" instead of *malloc* and @ref bs::bs_free "bs_free" instead of *free*.
+
+This ensures the Banshee can keep track of all allocated memory, which ensures better debugging and profiling tools and ensures the internal memory allocation method can be changed in the future.
+
+~~~~~~~~~~~~~{.cpp}
+// Helper structure
+struct MyStruct 
+{ 
+	MyStruct() {}
+	MyStruct(int a, bool b)
+		:a(a), b(b)
+	{ }
+	
+	int a; 
+	bool b; 
+};
+
+// Allocating memory the normal way
+MyStruct* ptr = new MyStruct(123, false);
+MyStruct** ptrArray = new MyStruct[5];
+void* rawMem = malloc(12);
+
+delete ptr;
+delete[] ptrArray;
+free(rawMem);
+
+// Allocating memory the Banshee way
+MyStruct* bsPtr = bs_new<MyStruct>(123, false);
+MyStruct** bsPtrArray = bs_newN<MyStruct>(5);
+void* bsRawMem = bs_alloc(12);
+
+bs_delete(bsPtr);
+bs_deleteN(bsPtrArray, 5);
+bs_free(bsRawMem);
+~~~~~~~~~~~~~

+ 54 - 0
Documentation/Manuals/Native/User/smartPointers.md

@@ -0,0 +1,54 @@
+Smart pointers						{#smartPointers}
+===============
+
+Smart pointers allow the user to allocate objects dynamically (i.e. like using *new* or *malloc*), but without having to worry about freeing the object. They are prefered to normal memory allocation as they prevent memory leaks when the user might forget to free memory. They are also very useful in situations when object ownership is not clearly defined and it might not be clear who is responsible for freeing the object, or when.
+
+# Unique pointers
+Unique pointers hold ownership of a dynamically allocated object, and automatically free it when they go out of scope. As their name implies they cannot be copied - in other words, only one pointer to that object can exist. They are mostly useful for temporary allocations, or for places where object ownership is clearly defined to a single owner.
+
+In Banshee type're represented with @ref bs::UPtr "UPtr", which is just a wrapper for the standard library's *std::unique_ptr*. Use @ref bs::bs_unique_ptr_new "bs_unique_ptr_new<T>" to create a unique pointer pointing to a new instance of T, or @ref bs::bs_unique_ptr "bs_unique_ptr" to create one from an existing instance. 
+
+~~~~~~~~~~~~~{.cpp}
+// Helper structure
+struct MyStruct 
+{ 
+	MyStruct() {}
+	MyStruct(int a, bool b)
+		:a(a), b(b)
+	{ }
+	
+	int a; 
+	bool b; 
+};
+
+UPtr<MyStruct> ptr = bs_unique_ptr_new<MyStruct>(123, false);
+
+// No need to free "ptr", it will automatically be freed when it goes out of scope
+~~~~~~~~~~~~~
+
+## Transfering ownership
+Since only a single instance of a unique pointer to a specific object may exist, they cannot be copied. However sometimes it is useful to move them to another object (transfer of ownership). In such case you can use *std::move* as shown below:
+
+~~~~~~~~~~~~~{.cpp}
+UPtr<MyStruct> ptr = bs_unique_ptr_new<MyStruct>(123, false);
+
+// Transfer ownership
+UPtr<MyStruct> ptrOther = std::move(ptr);
+
+// ptrOther now owns the object, while ptr is undefined
+~~~~~~~~~~~~~
+
+# Shared pointers
+Shared pointers are similar to unique pointers, as they also don't require the object to be explicitly freed after creation. However, unlike unique pointers they can be copied (therefore their name "shared"). This means multiple entities can hold a shared pointer to a single object. Only once ALL such entities lose their shared pointers will the pointed-to object be destroyed.
+
+In Banshee type're represented with @ref bs::SPtr "SPtr", which is just a wrapper for the standard library's *std::shared_ptr*. Use @ref bs::bs_shared_ptr_new "bs_shared_ptr_new<T>" to create a shared pointer pointing to a new instance of T, or @ref bs::bs_shared_ptr "bs_shared_ptr" to create one from an existing instance. 
+
+You will find Banshee uses shared pointers commonly all around its codebase.
+
+~~~~~~~~~~~~~{.cpp}
+SPtr<MyStruct> ptr = bs_shared_ptr_new<MyStruct>(123, false);
+SPtr<MyStruct> anotherPtr = ptr;
+
+// Object will be freed after both "ptr" and "anotherPtr" go out of scope. 
+// Normally you'd want to pass a copy of the pointer to some other system, otherwise we could have used a unique ptr
+~~~~~~~~~~~~~

+ 56 - 0
Documentation/Manuals/Native/User/strings.md

@@ -0,0 +1,56 @@
+Strings 						{#strings}
+===============
+Strings are represented with @ref bs::String "String" and @ref bs::WString "WString" types. These are wrappers for the standard C++ strings and have the same interface and behaviour.
+
+Use the **String** type for strings containing only ASCII characters (limited character set). Use the **WString** (wide string) for strings containing more complex characters, as it supports all Unicode characters.
+
+~~~~~~~~~~~~~{.cpp}
+String simple = "SimpleString";
+WString complex = "ж¤ÞÐ";
+~~~~~~~~~~~~~
+
+# Converting data types
+You can convert most primitive data types to strings by using the @ref bs::toString "toString" or @ref bs::toWString "toWString" functions.
+
+~~~~~~~~~~~~~{.cpp}
+bool v1 = false;
+int v2 = 244;
+
+String str1 = toString(v1);
+String str2 = toString(v2);
+~~~~~~~~~~~~~
+
+You can also do an opposite conversion, converting from a string to a primitive data type by calling one of the *parse* functions.
+
+~~~~~~~~~~~~~{.cpp}
+String str1 = "false";
+String str2 = "244";
+
+bool v1 = parseBool(str1, false);
+int v2 = parseINT32(str2, 0);
+~~~~~~~~~~~~~
+
+If the system cannot properly parse the string, it will instead assign the default value provided.
+
+# Manipulating strings
+Various forms of string manipulations can be performed via @ref bs::StringUtil "StringUtil", including but not limited to: making a string upper or lower case, replacing string elements, matching string elements, splitting strings based on delimiters and more.
+
+~~~~~~~~~~~~~{.cpp}
+String string = "124,355,banana,954";
+
+// Split string into entries separated by ,
+Vector<String> entries = StringUtil::split(string, ",");
+
+// Replace all occurrences of "banana" within the string, with "643"
+string = StringUtil::replaceAll(string, "banana", "643");
+~~~~~~~~~~~~~
+
+# Formatting strings
+Often you need to construct larger strings from other strings. Use @ref bs::StringUtil::format "StringUtil::format" to construct such strings by providing a template string, which contains special identifiers for inserting other strings. The identifiers are represented like "{0}, {1}" in the source string, where the number represents the position of the parameter that will be used for replacing the identifier.
+
+~~~~~~~~~~~~~{.cpp}
+String templateStr = "Hello, my name is {0}.";
+String str = StringUtil::format(templateStr, "Banshee");
+
+// str now contains the string "Hello, my name is Banshee."
+~~~~~~~~~~~~~

+ 10 - 0
Documentation/Manuals/Native/manuals.md

@@ -15,6 +15,16 @@ Manuals									{#manuals}
  - [Importing textures](@ref importingTextures)
  - [Importing textures](@ref importingTextures)
  - [Importing meshes](@ref importingMeshes)
  - [Importing meshes](@ref importingMeshes)
  - [Materials](@ref simpleMaterials)
  - [Materials](@ref simpleMaterials)
+- **Utilities**
+ - [Containers](@ref containers)
+ - [Strings](@ref strings)
+ - [Memory allocation](@ref memory)
+ - [Smart pointers](@ref smartPointers) 
+ - [Events](@ref events)
+ - [File system](@ref fileSystem) 
+ - [Math utilities](@ref mathUtilities)
+ - [Logging messages](@ref logging)
+ - [Measuring time](@ref time)
  
  
 # Developer guides
 # Developer guides