Skip to content

Commit 26a9202

Browse files
committed
Replaced the Callback placeholder alias with two implementations. (WORK IN PROGRESS...)
1 parent cfc83b6 commit 26a9202

29 files changed

+380
-144
lines changed

Source/DFPSR/History.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,15 @@ Changes from version 0.3.0
8484
* More int types were replaced with int32_t to be consistent in making the size explicit.
8585
While many compilers see int and int32_t as the same type and will not complain, the names are not guaranteed to always refer to the same type.
8686
Replace 'int' with 'int32_t' in your entire project if you have any problems with int types not being accepted.
87-
87+
* std::function was finally replaced with the framework's own wrappers over function pointers and lambdas.
88+
If you just want things to work, replace 'std::function' with 'StorableCallback' to allocate heap memory for lambda closures.
89+
StorableCallback allow saving the closure outside of the original lambda's scope, and should therefore avoid capturing by reference.
90+
If you don't need to capture anything, you can initialize it using a function pointer instead.
91+
If you want a guarantee that there will be no heap allocation, replace 'std::function<...>' with 'const TemporaryCallback<...> &', where ... is your function interface.
92+
TemporaryCallback must be passed by reference, because it can not live outside of the original lambda's scope.
93+
If the compiler complains about TemporaryCallback itself being captured by value, you just pass it by reference instead like in function calls.
94+
Unlike std::function, the callback types are not nullable, so instead of checking for null before calling, you simply initialize with a default action that is either doing nothing to throwing an error.
95+
By not having a default constructor, there will be no extra runtime overhead to check if the function exists and you will never have to worry about null function exceptions.
96+
If you see that the compiler can't find a constructor for StorableCallback and it points to a variable declaration, you need to initialize it with a function.
97+
string_assignMessageHandler now uses function pointers to avoid cyclic dependencies between stringAPI.h and StorableCallback.h.
98+
A message handler needs to be stored but will usually only work with global and thread-local variables.

Source/DFPSR/api/configAPI.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
using namespace dsr;
2727

28-
void dsr::config_parse_ini(const ReadableString& content, ConfigIniCallback receiverLambda) {
28+
void dsr::config_parse_ini(const ReadableString& content, const ConfigIniCallback &receiver) {
2929
List<String> lines = string_split(content, U'\n');
3030
String block = U"";
3131
for (int32_t l = 0; l < lines.length(); l++) {
@@ -41,7 +41,7 @@ void dsr::config_parse_ini(const ReadableString& content, ConfigIniCallback rece
4141
if (assignmentIndex > -1) {
4242
String key = string_removeOuterWhiteSpace(string_before(command, assignmentIndex));
4343
String value = string_removeOuterWhiteSpace(string_after(command, assignmentIndex));
44-
receiverLambda(block, key, value);
44+
receiver(block, key, value);
4545
} else {
4646
int32_t blockStartIndex = string_findFirst(command, U'[');
4747
int32_t blockEndIndex = string_findFirst(command, U']');

Source/DFPSR/api/configAPI.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
#define DFPSR_API_CONFIG
2626

2727
#include "stringAPI.h"
28-
#include "../base/Callback.h"
28+
#include "../base/TemporaryCallback.h"
2929

3030
namespace dsr {
3131
// A type of function sending (block, key, value) to the caller.
3232
// One can have hard-coded options, lookup-tables, dictionaries, et cetera for looking up the given key names.
33-
using ConfigIniCallback = Callback<void(const ReadableString& block, const ReadableString& key, const ReadableString& value)>;
33+
using ConfigIniCallback = TemporaryCallback<void(const ReadableString& block, const ReadableString& key, const ReadableString& value)>;
3434
/*
3535
Parsing the given content of a *.ini configuration file.
3636
Sending callbacks to receiverLambda for each key being assigned a value.
@@ -52,7 +52,7 @@ namespace dsr {
5252
}
5353
});
5454
*/
55-
void config_parse_ini(const ReadableString& content, ConfigIniCallback receiverLambda);
55+
void config_parse_ini(const ReadableString& content, const ConfigIniCallback &receiver);
5656

5757
// Adding an ini generator might be convenient for complying with the *.ini file standard
5858
// but it would also take away some artistic freedom with how lines are indented

Source/DFPSR/api/fileAPI.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ EntryType file_getEntryType(const ReadableString &path) {
586586
return result;
587587
}
588588

589-
bool file_getFolderContent(const ReadableString& folderPath, Callback<void(const ReadableString& entryPath, const ReadableString& entryName, EntryType entryType)> action) {
589+
bool file_getFolderContent(const ReadableString& folderPath, const TemporaryCallback<void(const ReadableString& entryPath, const ReadableString& entryName, EntryType entryType)> &action) {
590590
String optimizedPath = file_optimizePath(folderPath, LOCAL_PATH_SYNTAX);
591591
#ifdef USE_MICROSOFT_WINDOWS
592592
String pattern = file_combinePaths(optimizedPath, U"*.*", LOCAL_PATH_SYNTAX);
@@ -639,7 +639,7 @@ bool file_getFolderContent(const ReadableString& folderPath, Callback<void(const
639639
return true;
640640
}
641641

642-
void file_getPathEntries(const ReadableString& path, Callback<void(ReadableString, int64_t, int64_t)> action) {
642+
void file_getPathEntries(const ReadableString& path, const TemporaryCallback<void(ReadableString, int64_t, int64_t)> &action) {
643643
int64_t sectionStart = 0;
644644
int64_t length = string_length(path);
645645
for (int64_t i = 0; i < string_length(path); i++) {

Source/DFPSR/api/fileAPI.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "stringAPI.h"
2828
#include "bufferAPI.h"
2929
#include "../base/Handle.h"
30+
#include "../base/TemporaryCallback.h"
3031
#include "../settings.h"
3132

3233
// The file API exists to save and load buffers of data for any type of file.
@@ -98,7 +99,7 @@ namespace dsr {
9899
// The first entry must be something selectable to be included. Otherwise it is ignored.
99100
// C: would be returned as an entry, because other drives can be selected.
100101
// The implicit Windows drive \ and Posix system root / will not be returned, because they are implicit and can't be replaced in the path.
101-
void file_getPathEntries(const ReadableString& path, Callback<void(ReadableString, int64_t, int64_t)> action);
102+
void file_getPathEntries(const ReadableString& path, const TemporaryCallback<void(ReadableString, int64_t, int64_t)> &action);
102103

103104
// Path-syntax: Depends on pathSyntax argument.
104105
// Turns / and \ into the path convention specified by pathSyntax, which is the local system's by default.
@@ -258,7 +259,7 @@ namespace dsr {
258259
// entryName equals file_getPathlessName(entryPath).
259260
// entryType equals file_getEntryType(entryPath).
260261
// Post-condition: Returns true iff the folder could be found.
261-
bool file_getFolderContent(const ReadableString& folderPath, Callback<void(const ReadableString& entryPath, const ReadableString& entryName, EntryType entryType)> action);
262+
bool file_getFolderContent(const ReadableString& folderPath, const TemporaryCallback<void(const ReadableString& entryPath, const ReadableString& entryName, EntryType entryType)> &action);
262263

263264
// Path-syntax: According to the local computer.
264265
// Access permissions: Default settings according to the local operating system, either inherited from the parent folder or no specific restrictions.

Source/DFPSR/api/filterAPI.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#define DFPSR_API_FILTER
2727

2828
#include "../implementation/image/Image.h"
29-
#include "../base/Callback.h"
29+
#include "../base/TemporaryCallback.h"
3030

3131
namespace dsr {
3232

@@ -51,9 +51,9 @@ namespace dsr {
5151
// Create images from Lambda expressions when speed is not critical.
5252
// Capture images within [] and sample pixels from them using image_readPixel_border, image_readPixel_clamp and image_readPixel_tile.
5353
// Lambda expressions for generating integer images.
54-
using ImageGenRgbaU8 = Callback<ColorRgbaI32(int32_t x, int32_t y)>;
55-
using ImageGenI32 = Callback<int32_t(int32_t x, int32_t y)>; // Used for U8 and U16 images using different saturations.
56-
using ImageGenF32 = Callback<float(int32_t x, int32_t y)>;
54+
using ImageGenRgbaU8 = TemporaryCallback<ColorRgbaI32(int32_t x, int32_t y)>;
55+
using ImageGenI32 = TemporaryCallback<int32_t(int32_t x, int32_t y)>; // Used for U8 and U16 images using different saturations.
56+
using ImageGenF32 = TemporaryCallback<float(int32_t x, int32_t y)>;
5757
// In-place image generation to an existing image.
5858
// The pixel at the upper left corner gets (startX, startY) as x and y arguments to the function.
5959
void filter_mapRgbaU8(const ImageRgbaU8 &target, const ImageGenRgbaU8& lambda, int32_t startX = 0, int32_t startY = 0);

Source/DFPSR/api/guiAPI.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ Component dsr::component_getChild(const Component& parent, int32_t childIndex) {
146146
}
147147
}
148148

149-
static void findAllComponentsByName(const Component& component, const ReadableString& name, Callback<void(Component, int32_t)> callback) {
149+
static void findAllComponentsByName(const Component& component, const ReadableString& name, const TemporaryCallback<void(Component, int32_t)> &callback) {
150150
if (component_exists(component)) {
151151
// Check if the current component matches
152152
if (string_match(component->getName(), name)) {
@@ -159,7 +159,7 @@ static void findAllComponentsByName(const Component& component, const ReadableSt
159159
}
160160
}
161161
}
162-
void dsr::window_findAllComponentsByName(const Window& window, const ReadableString& name, Callback<void(Component, int32_t)> callback) {
162+
void dsr::window_findAllComponentsByName(const Window& window, const ReadableString& name, const TemporaryCallback<void(Component, int32_t)> &callback) {
163163
MUST_EXIST(window, window_findAllComponentsByName);
164164
findAllComponentsByName(window->getRootComponent(), name, callback);
165165
}

Source/DFPSR/api/guiAPI.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ namespace dsr {
127127
// To allow detaching components while iterating over the list of children, order is reversed for child components.
128128
// Raises an exception if window doesn't exist.
129129
// Component names are case sensitive to reduce the risk of accidental naming conflicts among many components.
130-
void window_findAllComponentsByName(const Window& window, const ReadableString& name, Callback<void(Component component, int32_t index)> callback);
130+
void window_findAllComponentsByName(const Window& window, const ReadableString& name, const TemporaryCallback<void(Component component, int32_t index)> &callback);
131131

132132
// The three main events to run in a loop at the end of the main function
133133
// If the window's event queue contained any resize of the window, the canvas and the depth buffer will be replaced during this call.

Source/DFPSR/api/mediaMachineAPI.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ String machine_getOutputName(const MediaMachine& machine, int32_t methodIndex, i
11971197
return method->locals[method->inputCount + outputIndex].name;
11981198
}
11991199

1200-
MediaResult MediaMethod::callUsingKeywords(Callback<void(MediaMachine &machine, int32_t methodIndex, int32_t inputIndex, const ReadableString &argumentName)> setInputAction) {
1200+
MediaResult MediaMethod::callUsingKeywords(const TemporaryCallback<void(MediaMachine &machine, int32_t methodIndex, int32_t inputIndex, const ReadableString &argumentName)> &setInputAction) {
12011201
if (this->methodIndex < 0 || this->methodIndex >= this->machine->methods.length()) {
12021202
throwError(U"Method index ", this->methodIndex, U" is out of bound 0..", this->machine->methods.length() - 1, U"\n");
12031203
}

Source/DFPSR/api/mediaMachineAPI.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include "../implementation/image/Image.h"
2828
#include "../base/Handle.h"
29+
#include "../base/TemporaryCallback.h"
2930
#include "../math/FixedPoint.h"
3031

3132
namespace dsr {
@@ -239,7 +240,7 @@ class MediaMethod {
239240
// The function setInputAction should simply make a call to machine_setInputByIndex with the provided machine, methodIndex, inputIndex and the value corresponding to argumentName in setInputAction.
240241
// If you don't recognize argumentName, then throw an exception because default input arguments are currently not implemented.
241242
// Useful when the called function can be extended or reduced with only the arguments needed.
242-
MediaResult callUsingKeywords(Callback<void(MediaMachine &machine, int32_t methodIndex, int32_t inputIndex, const ReadableString &argumentName)> setInputAction);
243+
MediaResult callUsingKeywords(const TemporaryCallback<void(MediaMachine &machine, int32_t methodIndex, int32_t inputIndex, const ReadableString &argumentName)> &setInputAction);
243244
};
244245

245246
// Post-condition: Returns a MediaMethod structure, which can be stored as a reference counting function pointer that keeps the virtual machine alive.

0 commit comments

Comments
 (0)