BLI: add high level documentation for core data structures #25
@ -1 +1,47 @@
|
|||||||
# Functions
|
# Functions
|
||||||
|
|
||||||
|
There are many ways to store a reference to a function. This document gives an overview over those and gives recommendations for when to use which approach.
|
||||||
|
|
||||||
|
1. Pass function pointer and user data (as void *) separately:
|
||||||
|
- The only method that is compatible with C interfaces.
|
||||||
|
- Is cumbersome to work with in many cases, because one has to keep track of two parameters.
|
||||||
|
- Not type safe at all, because of the void pointer.
|
||||||
|
- It requires workarounds when one wants to pass a lambda into a function.
|
||||||
|
2. Using `std::function`:
|
||||||
|
- It works well with most callables and is easy to use.
|
||||||
|
- Owns the callable, so it can be returned from a function more safely than other methods.
|
||||||
|
- Requires that the callable is copyable.
|
||||||
|
- Requires an allocation when the callable is too large (typically > 16 bytes).
|
||||||
|
3. Using a template for the callable type:
|
||||||
|
- Most efficient solution at runtime, because compiler knows the exact callable at the place
|
||||||
|
where it is called.
|
||||||
|
- Works well with all callables.
|
||||||
|
- Requires the function to be in a header file.
|
||||||
|
- It's difficult to constrain the signature of the function.
|
||||||
|
4. Using `blender::FunctionRef` ([source](https://projects.blender.org/blender/blender/src/branch/main/source/blender/blenlib/BLI_function_ref.hh)):
|
||||||
|
- Second most efficient solution at runtime.
|
||||||
|
- It's easy to constrain the signature of the callable.
|
||||||
|
- Does not require the function to be in a header file.
|
||||||
|
- Works well with all callables.
|
||||||
|
- It's a non-owning reference, so it *cannot* be stored safely in general.
|
||||||
|
|
||||||
|
The following diagram helps to decide which approach to use when building an API where the user has to pass in a function.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart TD
|
||||||
|
is_called_from_c["Is called from C code?"]
|
||||||
|
is_stored_when_function_ends["Is stored when function ends?"]
|
||||||
|
is_call_performance_bottleneck["Call is performance bottleneck?"]
|
||||||
|
use_function_pointer["Use function pointer and user data (approach 1)."]
|
||||||
|
use_std_function["Use `std::function` (approach 2)."]
|
||||||
|
use_template["Use `template<typename Fn>` (approach 3)."]
|
||||||
|
use_function_ref["Use `blender::FunctionRef` (approach 4)."]
|
||||||
|
|
||||||
|
|
||||||
|
is_called_from_c --"yes"--> use_function_pointer
|
||||||
|
is_called_from_c --"no"--> is_stored_when_function_ends
|
||||||
|
is_stored_when_function_ends --"yes"--> use_std_function
|
||||||
|
is_stored_when_function_ends --"no"--> is_call_performance_bottleneck
|
||||||
|
is_call_performance_bottleneck --"no"--> use_function_ref
|
||||||
|
is_call_performance_bottleneck --"yes"--> use_template
|
||||||
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user