mirror of
https://github.com/wqking/eventpp.git
synced 2024-12-26 15:52:40 +08:00
Fixed typos in documents
This commit is contained in:
parent
a135c761b4
commit
4bb20b5557
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@ tests/build/temp*
|
|||||||
tests/build/project*
|
tests/build/project*
|
||||||
tests/coverage
|
tests/coverage
|
||||||
build
|
build
|
||||||
|
.vscode
|
||||||
|
26
doc/anyid.md
26
doc/anyid.md
@ -1,5 +1,19 @@
|
|||||||
# Class AnyId reference
|
# Class AnyId reference
|
||||||
|
<!--begintoc-->
|
||||||
|
## Table Of Contents
|
||||||
|
|
||||||
|
* [Description](#a2_1)
|
||||||
|
* [API reference](#a2_2)
|
||||||
|
* [Header](#a3_1)
|
||||||
|
* [Class AnyId template parameters](#a3_2)
|
||||||
|
* [Public types](#a3_3)
|
||||||
|
* [Member functions](#a3_4)
|
||||||
|
* [Global type AnyHashableId](#a2_3)
|
||||||
|
* [Comparison AnyId](#a2_4)
|
||||||
|
* [When to use AnyId?](#a2_5)
|
||||||
|
<!--endtoc-->
|
||||||
|
|
||||||
|
<a id="a2_1"></a>
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
The template class `AnyId` can be used as the event ID type in `EventDispatcher` and `EventQueue`, then any types can be used as the event type.
|
The template class `AnyId` can be used as the event ID type in `EventDispatcher` and `EventQueue`, then any types can be used as the event type.
|
||||||
@ -31,23 +45,26 @@ For an `int` event type, we can't use `std::string` as the event ID.
|
|||||||
|
|
||||||
With `AnyId` in previous example code, we can pass any types as the event ID.
|
With `AnyId` in previous example code, we can pass any types as the event ID.
|
||||||
|
|
||||||
|
<a id="a2_2"></a>
|
||||||
## API reference
|
## API reference
|
||||||
|
|
||||||
|
<a id="a3_1"></a>
|
||||||
### Header
|
### Header
|
||||||
|
|
||||||
eventpp/utilities/anyid.h
|
eventpp/utilities/anyid.h
|
||||||
|
|
||||||
|
<a id="a3_2"></a>
|
||||||
### Class AnyId template parameters
|
### Class AnyId template parameters
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
template <template <typename> class Digester = std::hash, typename Storage = EmptyStorage>
|
template <template <typename> class Digester = std::hash, typename Storage = EmptyStorage>
|
||||||
class AnyId;
|
class AnyId;
|
||||||
```
|
```
|
||||||
`Digester`: a template class that has one template parameter. It has a function call operator that receives one value and returns the digest of the value. The returned digest must be hashable, i.e, it must be able to be passed to `std::hash`. One of such `Digester` is `std::hash`. The parameter default value is `std::hash`. An event ID that's converted to `AnyId` must be able to pass to `Digester` function call operator. For exmaple, if `Digester` is `std::hash`, the event ID must be hashable, aka, it must be able to be passed to `std::hash`, so `int` and `std::string` works, but `const char *` not.
|
`Digester`: a template class that has one template parameter. It has a function call operator that receives one value and returns the digest of the value. The returned digest must be hashable, i.e, it must be able to be passed to `std::hash`. One of such `Digester` is `std::hash`. The parameter default value is `std::hash`. An event ID that's converted to `AnyId` must be able to pass to `Digester` function call operator. For example, if `Digester` is `std::hash`, the event ID must be hashable, aka, it must be able to be passed to `std::hash`, so `int` and `std::string` works, but `const char *` not.
|
||||||
`Storage`: a class that can be constructed with any types of values which are going to be used in `AnyId`. One of such `Storage` is `std::any` (in C++17). The parameter default value is an empty storage class that can be constructed with any types and it doesn't hold the value.
|
`Storage`: a class that can be constructed with any types of values which are going to be used in `AnyId`. One of such `Storage` is `std::any` (in C++17). The parameter default value is an empty storage class that can be constructed with any types and it doesn't hold the value.
|
||||||
|
|
||||||
`Digester` is used to convert any types to a specified type and `AnyId` stores the digest instead of the value itself.
|
`Digester` is used to convert any types to a specified type and `AnyId` stores the digest instead of the value itself.
|
||||||
`Storage` is used to store the actural value.
|
`Storage` is used to store the actual value.
|
||||||
|
|
||||||
A typical implementation of `Digester`:
|
A typical implementation of `Digester`:
|
||||||
```c++
|
```c++
|
||||||
@ -85,9 +102,11 @@ struct MyStorage
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a id="a3_3"></a>
|
||||||
### Public types
|
### Public types
|
||||||
`DigestType`: the digest type that returned by `Digester`. If `Digester` is `std::hash`, `DigestType` is `std::size_t`.
|
`DigestType`: the digest type that returned by `Digester`. If `Digester` is `std::hash`, `DigestType` is `std::size_t`.
|
||||||
|
|
||||||
|
<a id="a3_4"></a>
|
||||||
### Member functions
|
### Member functions
|
||||||
|
|
||||||
#### constructors
|
#### constructors
|
||||||
@ -112,6 +131,7 @@ const Storage & getValue() const;
|
|||||||
Return the value that's stored in `Storage`. The default `Storage` is an empty structure, so you can't get the real value from it.
|
Return the value that's stored in `Storage`. The default `Storage` is an empty structure, so you can't get the real value from it.
|
||||||
If `std::any` is used as the `Storage` parameter when instantiating the `AnyId` template, `getValue` returns the `std::any` thus the value can be obtained from the `std::any`.
|
If `std::any` is used as the `Storage` parameter when instantiating the `AnyId` template, `getValue` returns the `std::any` thus the value can be obtained from the `std::any`.
|
||||||
|
|
||||||
|
<a id="a2_3"></a>
|
||||||
## Global type AnyHashableId
|
## Global type AnyHashableId
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
@ -121,6 +141,7 @@ using AnyHashableId = AnyId<>;
|
|||||||
`AnyHashableId` is an instantiation of `AnyId` with the default parameters. It can be used in place of the event ID in `EventDispatcher` or `EventQueue`.
|
`AnyHashableId` is an instantiation of `AnyId` with the default parameters. It can be used in place of the event ID in `EventDispatcher` or `EventQueue`.
|
||||||
In the example code in the beginning of this document, the `eventpp::AnyId<>` can be replaced with `eventpp::AnyHashableId`.
|
In the example code in the beginning of this document, the `eventpp::AnyId<>` can be replaced with `eventpp::AnyHashableId`.
|
||||||
|
|
||||||
|
<a id="a2_4"></a>
|
||||||
## Comparison AnyId
|
## Comparison AnyId
|
||||||
|
|
||||||
`AnyId` supports `operator ==` for being used in `std::unordered_map`, and `operator <` for being used in `std::map` (which map is used depending on the policies), in `EventDispatcher` and `EventQueue`.
|
`AnyId` supports `operator ==` for being used in `std::unordered_map`, and `operator <` for being used in `std::map` (which map is used depending on the policies), in `EventDispatcher` and `EventQueue`.
|
||||||
@ -128,6 +149,7 @@ In the example code in the beginning of this document, the `eventpp::AnyId<>` ca
|
|||||||
If the `Storage` supports the operators, the values in the storage are compared. In this case, it doesn't matter if digest collides.
|
If the `Storage` supports the operators, the values in the storage are compared. In this case, it doesn't matter if digest collides.
|
||||||
If the `Storage` doesn't support the operators, only the digests are compared. In this case, if digest collides, the result is in collision.
|
If the `Storage` doesn't support the operators, only the digests are compared. In this case, if digest collides, the result is in collision.
|
||||||
|
|
||||||
|
<a id="a2_5"></a>
|
||||||
## When to use AnyId?
|
## When to use AnyId?
|
||||||
|
|
||||||
Even though `AnyId` looks smart and very flexible, I highly don't encourage you to use it at all because that means the architecture has flaws. You should always prefer to single event type, such as `int`, or `std::string`, than mixing them.
|
Even though `AnyId` looks smart and very flexible, I highly don't encourage you to use it at all because that means the architecture has flaws. You should always prefer to single event type, such as `int`, or `std::string`, than mixing them.
|
||||||
|
@ -41,7 +41,7 @@ Function `argumentAdapter` receives a function `func`, and return a functor obje
|
|||||||
If `func` is a `std::function`, or a pointer to free function, `argumentAdapter` can deduce the parameter types of func, then `argumentAdapter` can be called without any template parameter.
|
If `func` is a `std::function`, or a pointer to free function, `argumentAdapter` can deduce the parameter types of func, then `argumentAdapter` can be called without any template parameter.
|
||||||
If `func` is a functor object that `argumentAdapter` can't deduce the parameter types, `argumentAdapter` needs a template parameter which is the prototype of `func`.
|
If `func` is a functor object that `argumentAdapter` can't deduce the parameter types, `argumentAdapter` needs a template parameter which is the prototype of `func`.
|
||||||
`ArgumentAdapter` converts argument types using `static_cast`. For `std::shared_ptr`, `std::static_pointer_cast` is used. If `static_cast` or `std::static_pointer_cast` can't convert the types, compile errors are issued.
|
`ArgumentAdapter` converts argument types using `static_cast`. For `std::shared_ptr`, `std::static_pointer_cast` is used. If `static_cast` or `std::static_pointer_cast` can't convert the types, compile errors are issued.
|
||||||
Caveat: Sucessful type casting doesn't mean correct. For example (pseudo code),
|
Caveat: Successful type casting doesn't mean correct. For example (pseudo code),
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
class A;
|
class A;
|
||||||
|
@ -167,7 +167,7 @@ void wait() const;
|
|||||||
```
|
```
|
||||||
`wait` causes the current thread to block until the queue is not empty.
|
`wait` causes the current thread to block until the queue is not empty.
|
||||||
Note: though `wait` has work around with spurious wakeup internally, the queue is not guaranteed not empty after `wait` returns.
|
Note: though `wait` has work around with spurious wakeup internally, the queue is not guaranteed not empty after `wait` returns.
|
||||||
`wait` is useful when a thread processes the event queue. A sampel usage is,
|
`wait` is useful when a thread processes the event queue. A sample usage is,
|
||||||
```c++
|
```c++
|
||||||
for(;;) {
|
for(;;) {
|
||||||
eventQueue.wait();
|
eventQueue.wait();
|
||||||
|
@ -134,7 +134,7 @@ void wait() const;
|
|||||||
```
|
```
|
||||||
`wait` causes the current thread to block until there is new event arrives in the queue.
|
`wait` causes the current thread to block until there is new event arrives in the queue.
|
||||||
Note: though `wait` has work around with spurious wakeup internally, the queue is not guaranteed not empty after `wait` returns.
|
Note: though `wait` has work around with spurious wakeup internally, the queue is not guaranteed not empty after `wait` returns.
|
||||||
`wait` is useful when a thread processes the event queue. A sampel usage is,
|
`wait` is useful when a thread processes the event queue. A sample usage is,
|
||||||
```c++
|
```c++
|
||||||
for(;;) {
|
for(;;) {
|
||||||
eventQueue.wait();
|
eventQueue.wait();
|
||||||
|
@ -127,8 +127,8 @@ eventpp::EventDispatcher<int, void (int e, int i, std::string), MyPolicies> disp
|
|||||||
|
|
||||||
dispatcher.appendListener(3, [](const int e, const int i, const std::string & s) {
|
dispatcher.appendListener(3, [](const int e, const int i, const std::string & s) {
|
||||||
std::cout
|
std::cout
|
||||||
<< "Got event 3, i was 1 but actural is " << i
|
<< "Got event 3, i was 1 but actual is " << i
|
||||||
<< " s was Hello but actural is " << s
|
<< " s was Hello but actual is " << s
|
||||||
<< std::endl
|
<< std::endl
|
||||||
;
|
;
|
||||||
});
|
});
|
||||||
@ -174,7 +174,7 @@ dispatcher.dispatch(5, 2, "World");
|
|||||||
> Filter 1, changed i is 38 s is Hi
|
> Filter 1, changed i is 38 s is Hi
|
||||||
> Filter 2, e is 3 passed in i is 38 s is Hi
|
> Filter 2, e is 3 passed in i is 38 s is Hi
|
||||||
> Filter 3, e is 3 passed in i is 38 s is Hi
|
> Filter 3, e is 3 passed in i is 38 s is Hi
|
||||||
> Got event 3, i was 1 but actural is 38 s was Hello but actural is Hi
|
> Got event 3, i was 1 but actual is 38 s was Hello but actual is Hi
|
||||||
> Filter 1, e is 5 passed in i is 2 s is World
|
> Filter 1, e is 5 passed in i is 2 s is World
|
||||||
> Filter 1, changed i is 38 s is Hi
|
> Filter 1, changed i is 38 s is Hi
|
||||||
> Filter 2, e is 5 passed in i is 38 s is Hi
|
> Filter 2, e is 5 passed in i is 38 s is Hi
|
||||||
|
@ -103,7 +103,7 @@ The function `reset()` removes all listeners which added by ScopedRemover from t
|
|||||||
|
|
||||||
The functions `setDispatcher()` and `setCallbackList` sets the dispatcher or callback list, and reset the ScopedRemover object.
|
The functions `setDispatcher()` and `setCallbackList` sets the dispatcher or callback list, and reset the ScopedRemover object.
|
||||||
|
|
||||||
The functions `removeListener` and `remove` remove the listener, similar to the same name functions in the underlying class (CallbackList, EventDispatcher, or EventQueue). They are useful to remove the listeners without destorying the ScopedRemover object. The functions return `true` if the listener is removed successfully, `false` if the listener is not found.
|
The functions `removeListener` and `remove` remove the listener, similar to the same name functions in the underlying class (CallbackList, EventDispatcher, or EventQueue). They are useful to remove the listeners without destroying the ScopedRemover object. The functions return `true` if the listener is removed successfully, `false` if the listener is not found.
|
||||||
|
|
||||||
The other member functions that have the same names with the corresponding underlying class (CallbackList, EventDispatcher, or EventQueue). Those functions add listener to the dispatcher.
|
The other member functions that have the same names with the corresponding underlying class (CallbackList, EventDispatcher, or EventQueue). Those functions add listener to the dispatcher.
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ find_path(EVENTPP_INCLUDE_DIR eventpp/eventqueue.h)
|
|||||||
include_directories(${EVENTPP_INCLUDE_DIR})
|
include_directories(${EVENTPP_INCLUDE_DIR})
|
||||||
```
|
```
|
||||||
|
|
||||||
Then run cmake, note you need -DCMAKE_TOOLCHAIN_FILE to specifiy vcpkg, and replace -G with your generator
|
Then run cmake, note you need -DCMAKE_TOOLCHAIN_FILE to specify vcpkg, and replace -G with your generator
|
||||||
```
|
```
|
||||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=VCPKGDIR/vcpkg/scripts/buildsystems/vcpkg.cmake -G"MinGW Makefiles"
|
cmake .. -DCMAKE_TOOLCHAIN_FILE=VCPKGDIR/vcpkg/scripts/buildsystems/vcpkg.cmake -G"MinGW Makefiles"
|
||||||
```
|
```
|
||||||
|
@ -175,8 +175,8 @@ TEST_CASE("EventDispatcher tutorial 5, event filter")
|
|||||||
|
|
||||||
dispatcher.appendListener(3, [](const int /*e*/, const int i, const std::string & s) {
|
dispatcher.appendListener(3, [](const int /*e*/, const int i, const std::string & s) {
|
||||||
std::cout
|
std::cout
|
||||||
<< "Got event 3, i was 1 but actural is " << i
|
<< "Got event 3, i was 1 but actual is " << i
|
||||||
<< " s was Hello but actural is " << s
|
<< " s was Hello but actual is " << s
|
||||||
<< std::endl
|
<< std::endl
|
||||||
;
|
;
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user