MCRO
C++23 utilities for Unreal Engine.
Loading...
Searching...
No Matches
Finally.h
Go to the documentation of this file.
1/** @noop License Comment
2 * @file
3 * @copyright
4 * This Source Code is subject to the terms of the Mozilla Public License, v2.0.
5 * If a copy of the MPL was not distributed with this file You can obtain one at
6 * https://mozilla.org/MPL/2.0/
7 *
8 * @author David Mórász
9 * @date 2025
10 */
11
12#pragma once
13#include "CoreMinimal.h"
14
16{
17 /**
18 * Run arbitrary finalizers on destruction. It has similar purpose to ON_SCOPE_EXIT, however FFinally can be moved
19 * around into different scopes, Payload will be only executed if the finalizer hasn't been moved from, otherwise
20 * the payload will be ignored in the source of move assignments:
21 *
22 * {
23 * FFinally fin([] {...})
24 * Async(EAsyncExecution::ThreadPool, [fin = MoveTemp(fin)]
25 * {
26 * // Payload is executed at the end of this scope
27 * }
28 * // Payload is not executed here
29 * }
30 *
31 * Finalizers can be moved into nested scopes
32 *
33 * {
34 * FFinally fin([] {...})
35 * Async(EAsyncExecution::ThreadPool, [fin = MoveTemp(fin)] mutable
36 * {
37 * AsyncTask(ENamedThreads::GameThread, [fin = MoveTemp(fin)]
38 * {
39 * // Payload is executed at the end of this scope
40 * }
41 * // Payload is not executed here
42 * }
43 * // Payload is not executed here
44 * }
45 */
46 struct FFinally : FNoncopyable
47 {
48 private:
49 TUniqueFunction<void()> Payload;
50 bool bIsValid = true;
51
52 public:
53 FFinally(TUniqueFunction<void()>&& payload) : Payload(MoveTemp(payload)) {}
54 FFinally(FFinally&& from) noexcept : Payload(MoveTemp(from.Payload))
55 {
56 from.bIsValid = false;
57 }
58
60 {
61 if(bIsValid) Payload();
62 }
63 };
64
65 /** Do not use this directly, use FINALLY macro. Similar intentions to ON_SCOPE_EXIT but gives more freedom */
67 {
68 FFinally operator+(TUniqueFunction<void()>&& payload)
69 {
70 return FFinally(MoveTemp(payload));
71 }
72 };
73}
74
75/**
76 * A more convenient way to use `FFinally`.
77 *
78 * @code
79 * auto fin = FINALLY(=, this) mutable
80 * {
81 * ...
82 * };
83 * AsyncTask(ENamedThreads::GameThread, [fin = MoveTemp(fin)]
84 * {
85 * // Payload is executed at the end of this scope
86 * }
87 * @endcode
88 */
89#define FINALLY(...) Mcro::Finally::FFinallySyntaxSupport() + [__VA_ARGS__]()
FFinally operator+(TUniqueFunction< void()> &&payload)
Definition Finally.h:68
FFinally(TUniqueFunction< void()> &&payload)
Definition Finally.h:53
FFinally(FFinally &&from) noexcept
Definition Finally.h:54