ProudNet Utility
Using collections
STL, ATL, etc. already provide collection classes (std.map, std.vector, CFastArray, CAtlArray, CAtlMap, etc.). However, ProudNet provides a set of classes that work well in situations where both STL and ATL are not available, or where high performance is required.
Array Class
Proud.CFastArray
Linked List Class
Proud.CFastList
It uses Fast Heap internally. Unlike CFastArray, the class can be used with constructors, destructors, and copy allocation operators.
Map Class
Proud.CFastMap
It uses a hash algorithm for (Key,Value) pairs. It is very similar in usage to CAtlMap, and can use the same iterators and some of the same methods as STL.map.
Set Class
Proud.CFastSet
Unlike CFastMap, it is a class that only owns the key, the rest is the same as CFastMap.
Quick Memory Manager
ProudNet has a built-in high-performance memory manager, which developers can use to accelerate the processing power of their applications.
The following memory managers are supported by ProudNet.
- Lookaside allocator
The lookaside allocator applies the usual memory pool technique. If you need to allocate and deallocate the same amount of memory frequently, you may want to use the lookaside allocator.
The main mechanisms are described below.
When allocating a new memory block, new system memory is allocated.
When freeing a block of memory, the freed block is returned to the lookaside allocator.
When reallocating memory blocks, the memory blocks returned by the lookaside allocator are recycled.
This process runs at a very high speed. It is much faster than memory allocation in the OS environment.
But there are also disadvantages.
A lookaside allocator can only allocate memory that is always the same size.
All memory blocks allocated by the lookaside allocator must be freed before the lookaside allocator is destroyed.
Here is how to use the lookaside allocator.
First, create an object with the Proud.CLookasideAllocator.New method. You can also create it as a global object.
Allocate a block of memory with the Proud.CLookasideAllocator.Alloc method.
Freeing is done with Proud.CLookasideAllocator.Free. Realloc does not exist.
Destroy the Proud.CLookasideAllocator object after freeing all memory blocks.
- Fast Heap
ProudNet's Fast heap is slightly slower than the Lookaside allocator, but much faster than memory allocation/release in the OS environment, and can allocate/release memory blocks of different sizes.
The implementation class for ProudNet's Fast heap is Proud.CFastHeap. Proud.CFastHeap also allows you to remove Proud.CFastHeap objects after all memory blocks have been destroyed.
Here is how to use Fast heap.
First, create a Fast heap object with the Proud.CFastHeap.New method. You can also create it as a global object.
Allocate a block of memory with the Proud.CFastHeap.Alloc method.
Freeing is done with Proud.CFastHeap.Free. Memory blocks can be reallocated with CFastHeap.Realloc.
Destroy the Proud.CFastHeap object after freeing all memory blocks.
Specify as default allocator for C++ class
An easy way to accelerate a fast heap or lookaside allocator in a C++ class is to override C++'s operator new, delete methods.
This ensures that when C++ classes are created and destroyed with the new, delete operators, the fast heap or lookaside allocator is used instead of the system's memory heap.
In the example below, when the class instantiates with the operator new or delete, we let the high-performance memory manager allocate/free memory on our behalf. There are different advantages and disadvantages to each, so choose and use accordingly.
Smart Pointer
ProudNet has a smart pointer Proud.RefCount class.
A smart pointer guarantees the existence of a created object as long as there are variables referring to it, and only destroys it when the variables referring to it no longer exist.
It also serves to eliminate the problem of referencing objects that have already been destroyed due to developer-created bugs (dangling) or not destroying objects in time (leak).
Each time a smart pointer variable is copied, the object reference count increases by 1. In the picture below, the Object Instance exists until the reference count becomes 0.
There are times when you have multiple smart pointers referencing an object and you want to force the object to be destroyed.
For example, if a smart pointer is referencing an object that holds an open file handle, there will be times when you need to destroy the object that holds that file handle immediately.
However, if a smart pointer is referencing that object here and there, you may run into trouble because you do not know when the object is destroyed. For these cases, you can use the Dispose Pattern to explicitly destroy an object that is referenced in multiple places.
- Dispose Pattern
Dispose Pattern is a program pattern for achieving the effect of explicitly destroying an object referenced by one or more smart pointers without knowing exactly when the object will be destroyed.
To use the Dispose Pattern on an object that will be treated as a smart class, the object must have a "self-state" as a member variable, which means that the object has already been destroyed and is unusable. If the self-state is 'already destroyed', then we should raise an error when referencing the object, and otherwise make it perform normally.
Below is an example of using the Dispose Pattern.
Dispose Pattern is also covered in programming languages with smart pointer and Garbage Collector, such as Java and C#.
Thread Utility
ProudNet offers several thread utility classes.
Proud.Thread
Easily create and destroy threads.
Proud.CriticalSection
You can create a critical section.
Proud.CriticalSectionLock
You can lock and unlock.
String Class
ProudNet provides string classes Proud.String, Proud.StringA that make handling strings as easy as the string classes in ATL or STL.
Programs that use the .Net Framework have a symbol called System.string. So if you are mixing .Net Frameworks, you may need to specify the namespace of either System or Proud.
For example, see below.
- String creation function(format)
Proud.StringT provides a string creation function like sprintf().
- String processing performance
Copy-on-write
Measuring String Length
Proud.StringT.GetLength returns the pre-measured length of the string immediately upon call, which is different from strlen().
Proud.StringT does not have a thread safe like int or float. Therefore, it is not safe to access the same string object from multiple threads at the same time (unless all threads are read only).
This is the same as for string classes in ATL or STL.
Timer Queue
Timer Queue is a module that performs tick event on a thread pool and provides an API called Windows Timer Queue on Windows XP, 2000 and later operating systems.
Run a function you specify at a certain time, but the function runs on one of the threads in the thread pool. If all the threads are running something (in a running state), the execution of the function is put on hold until one of the threads finishes its past work.
The user function calling from the Timer Queue will be selected from one of the threads in the thread pool, and if there is a thread with nothing to do (idle state), it will be selected to execute the user function, even if the user function that was running earlier has not finished executing.
Suppose you have the following task list.
The black arrow is 0.1 seconds and A,B,C,D,E are the action items that need to be done every 0.1 seconds. A,D will be done in less than 0.1 seconds, B will be done in exactly 0.1 seconds, and C,E will not be done in 0.1 seconds.
In the server main loop approach, these work items are performed as shown in the following figure. Because it executes all work items in one thread, D,E does not start in time.
However, in the Timer Queue approach, another thread is mobilized to execute D, and E is running in time on the thread that completed C earlier.
Execute the necessary tasks on time, but mobilize more threads if necessary.
Timer Queue is primarily used in server programs due to the fact that user functions can be running on more than one thread at the same time.
While it enables parallelism, it comes with its own set of risks, so determine if you really need this feature before using it.
If Timer Queue is used incorrectly, the number of threads in the server process may increase explosively, which may have an adverse effect on performance. If there is no compelling reason to use Timer Queue, use Proud.CTimerThread or handle timer loop, RMI, and events on the server.
- How to use a timer queue
You need to access the Proud.CTimerQueue class, which is a singleton.
You can set the function to be called at a certain time and how often it will be called in a Proud::NewTimerParam structure and pass it as an argument to Proud.CTimerQueue.NewTimer and you will receive a Proud.CTimerQueueTimer object. And until you destroy the Proud.CTimerQueueTimer object, the user function you specify will be executed at regular intervals.
Leaving a log
When developing an online game, you may need the ability to leave various execution records (logs). ProudNet provides the ability to leave logs for this purpose.
ProudNet's logging function runs asynchronously, so the method returns as soon as you call the method to leave a log. Additionally, a separate thread writes the actual log to a file or database.
- Logging to a file
The Proud::CLogWriter class allows you to write logs to a file.
- Logging to a database
The Proud::CDbLogWriter class allows you to write logs to the DB.
To use this, you must create a LogTable in advance by running LogTable.sql in the Sample/DbmsSchema folder. To build a DBMS, refer to the procedure in Building a Sample Database.
Latency Measurement Features
ProudNet provides latency measurement in the form of StopWatch.
If it is available, you should use it instead of the server's GetLastPing or GetRecentPing, as it is more accurate than traditional latency measurement functions.
(1) Start measuring latency
Calling StartRoundTripLatencyTest starts the object and relay for measuring latency.
(2) End of latency measurement
If you want to stop the test before the previously specified testDuration, call the StopRoundTripLatencyTest function. If you do not call StopRoundTripLatencyTest until the testDuration has passed, the measurement will automatically stop.
(3) Getting latency measurements
PIDL Compiler Add-on
This is an add-on for Visual Studio that allows you to easily set up Custom Build from ProudNet IDL (PIDL) files.
- Setting
1. Run <installation path>\ProudNet\util\PIDL-addon.vsix.
2. Select the Visual Studio you want to install the add-on to and proceed to Install.
3. When installation is completed successfully, it will be displayed as shown below.
- Delete
You can uninstall it through the Tools → Extensions and Updates menu.
For Visual Studio 2010, click Tools → Extension Manager
- Add PIDL File Window
Call the Add PIDL window. Select Project → right click → select Add new PIDL file
Enter a PIDL file name.
Displays the path where the PIDL file will be added.
Add an external PIDL file.
Create a new PIDL file.
Exit the Add PIDL window.
- Add a PIDL file
Enter the name of the PIDL file to add
Click New PIDL
A PIDL file is added, as shown above, and the Custom Build settings for that file are by default. If they differ from the default settings, you can change them via the Change File Properties feature.
- PIDL File Properties Window
Call the PIDL Properties window.
Select PIDL file → right click → select Properties
View/change the Custom Build Tool settings in the PIDL file. PIDL Compiler Location: Set the PIDL compiler location. PIDL Compiler Location is Relative: The absolute/relative value of the entered path. Output Directory (All Languages): Set the output path. Output Directory is Relative (All Languages): The absolute/relative value of the entered path.
Language-specific settings windows: These can be created for each of the C++, C#, Java, and Unreal Script languages.
Language-specific settings window: Generate Code: C++ default Yes, other languages False (can be set as needed) C++ Implementation File Extension: C++ only.
Last updated