用法:参考RemoteControlPreset.cpp
1 static TAutoConsoleVariable<int32> CVarRemoteControlFramesBetweenPropertyWatch(TEXT("RemoteControl.FramesBetweenPropertyWatch"), 5, TEXT("The number of frames between every property value comparison when manually watching for property changes."));
1 // Copyright Epic Games, Inc. All Rights Reserved.
2
3 #pragma once
4
5 #include "CoreTypes.h"
6 #include "Misc/AssertionMacros.h"
7 #include "Templates/UnrealTemplate.h"
8 #include "Containers/UnrealString.h"
9 #include "Logging/LogMacros.h"
10 #include "Delegates/IDelegateInstance.h"
11 #include "Delegates/Delegate.h"
12 #include "Features/IModularFeature.h"
13 #include "Templates/EnableIf.h"
14
15 #define TRACK_CONSOLE_FIND_COUNT !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
16
17 #if DO_CHECK && (!UE_BUILD_SHIPPING) // Disable even if checks in shipping are enabled.
18 #define cvarCheckCode( Code ) checkCode( Code )
19 #else
20 #define cvarCheckCode(...)
21 #endif
22
23 template <class T> class TConsoleVariableData;
24
25 /**
26 * Console variable usage guide:
27 *
28 * The variable should be creates early in the initialization but not before (not in global variable construction).
29 * Choose the right variable type, consider using a console command if more functionality is needed (see Exec()).
30 * Available types: bool, int, float, bool&, int&, float&, string
31 * Always provide a good help text, other should be able to understand the function of the console variable by reading this help.
32 * The help length should be limited to a reasonable width in order to work well for low res screen resolutions.
33 *
34 * Usage in the game console:
35 * <COMMAND> ? print the HELP
36 * <COMMAND> print the current state of the console variable
37 * <COMMAND> x set and print the new state of the console variable
38 *
39 * All variables support auto completion. The single line help that can show up there is currently not connected to the help as the help text
40 * is expected to be multi line.
41 * The former Exec() system can be used to access the console variables.
42 * Use console variables only in main thread.
43 * The state of console variables is not network synchronized or serialized (load/save). The plan is to allow to set the state in external files (game/platform/engine/local).
44 */
45
46 /**
47 * Bitmask 0x1, 0x2, 0x4, ..
48 */
49 enum EConsoleVariableFlags
50 {
51 /* Mask for flags. Use this instead of ~ECVF_SetByMask */
52 ECVF_FlagMask = 0x0000ffff,
53
54 /**
55 * Default, no flags are set, the value is set by the constructor
56 */
57 ECVF_Default = 0x0,
58 /**
59 * Console variables marked with this flag behave differently in a final release build.
60 * Then they are are hidden in the console and cannot be changed by the user.
61 */
62 ECVF_Cheat = 0x1,
63 /**
64 * Console variables cannot be changed by the user (from console).
65 * Changing from C++ or ini is still possible.
66 */
67 ECVF_ReadOnly = 0x4,
68 /**
69 * UnregisterConsoleObject() was called on this one.
70 * If the variable is registered again with the same type this object is reactivated. This is good for DLL unloading.
71 */
72 ECVF_Unregistered = 0x8,
73 /**
74 * This flag is set by the ini loading code when the variable wasn't registered yet.
75 * Once the variable is registered later the value is copied over and the variable is destructed.
76 */
77 ECVF_CreatedFromIni = 0x10,
78 /**
79 * Maintains another shadow copy and updates the copy with render thread commands to maintain proper ordering.
80 * Could be extended for more/other thread.
81 * Note: On console variable references it assumes the reference is accessed on the render thread only
82 * (Don't use in any other thread or better don't use references to avoid the potential pitfall).
83 */
84 ECVF_RenderThreadSafe = 0x20,
85
86 /* ApplyCVarSettingsGroupFromIni will complain if this wasn't set, should not be combined with ECVF_Cheat */
87 ECVF_Scalability = 0x40,
88
89 /* those cvars control other cvars with the flag ECVF_Scalability, names should start with "sg." */
90 ECVF_ScalabilityGroup = 0x80,
91
92 // ------------------------------------------------
93
94 /* Set flags */
95 ECVF_SetFlagMask = 0x00ff0000,
96
97 // Use to set a cvar without calling all cvar sinks. Much faster, but potentially unsafe. Use only if you know the particular cvar/setting does not require a sink call
98 ECVF_Set_NoSinkCall_Unsafe = 0x00010000,
99
100 // ------------------------------------------------
101
102 /* to get some history of where the last value was set by ( useful for track down why a cvar is in a specific state */
103 ECVF_SetByMask = 0xff000000,
104
105 // the ECVF_SetBy are sorted in override order (weak to strong), the value is not serialized, it only affects it's override behavior when calling Set()
106
107 // lowest priority (default after console variable creation)
108 ECVF_SetByConstructor = 0x00000000,
109 // from Scalability.ini (lower priority than game settings so it's easier to override partially)
110 ECVF_SetByScalability = 0x01000000,
111 // (in game UI or from file)
112 ECVF_SetByGameSetting = 0x02000000,
113 // project settings (editor UI or from file, higher priority than game setting to allow to enforce some setting fro this project)
114 ECVF_SetByProjectSetting = 0x03000000,
115 // per project setting (ini file e.g. Engine.ini or Game.ini)
116 ECVF_SetBySystemSettingsIni = 0x04000000,
117 // per device setting (e.g. specific iOS device, higher priority than per project to do device specific settings)
118 ECVF_SetByDeviceProfile = 0x05000000,
119 // consolevariables.ini (for multiple projects)
120 ECVF_SetByConsoleVariablesIni = 0x06000000,
121 // a minus command e.g. -VSync (very high priority to enforce the setting for the application)
122 ECVF_SetByCommandline = 0x07000000,
123 // least useful, likely a hack, maybe better to find the correct SetBy...
124 ECVF_SetByCode = 0x08000000,
125 // editor UI or console in game or editor
126 ECVF_SetByConsole = 0x09000000,
127
128 // ------------------------------------------------
129 };
130
131 class IConsoleVariable;
132
133 #if !NO_CVARS
134
135 /** Console variable delegate type This is a void callback function. */
136 DECLARE_DELEGATE_OneParam(FConsoleVariableDelegate, IConsoleVariable*);
137
138 /** Console variable multicast delegate type. */
139 DECLARE_MULTICAST_DELEGATE_OneParam(FConsoleVariableMulticastDelegate, IConsoleVariable*);
140
141 /** Console command delegate type (takes no arguments.) This is a void callback function. */
142 DECLARE_DELEGATE( FConsoleCommandDelegate );
143
144 /** Console command delegate type (with arguments.) This is a void callback function that always takes a list of arguments. */
145 DECLARE_DELEGATE_OneParam( FConsoleCommandWithArgsDelegate, const TArray< FString >& );
146
147 /** Console command delegate type with a world argument. This is a void callback function that always takes a world. */
148 DECLARE_DELEGATE_OneParam( FConsoleCommandWithWorldDelegate, UWorld* );
149
150 /** Console command delegate type (with a world and arguments.) This is a void callback function that always takes a list of arguments and a world. */
151 DECLARE_DELEGATE_TwoParams(FConsoleCommandWithWorldAndArgsDelegate, const TArray< FString >&, UWorld*);
152
153 /** Console command delegate type (with a world arguments and output device.) This is a void callback function that always takes a list of arguments, a world and output device. */
154 DECLARE_DELEGATE_ThreeParams(FConsoleCommandWithWorldArgsAndOutputDeviceDelegate, const TArray< FString >&, UWorld*, FOutputDevice&);
155
156 /** Console command delegate type with the output device passed through. */
157 DECLARE_DELEGATE_OneParam( FConsoleCommandWithOutputDeviceDelegate, FOutputDevice& );
158
159 #else
160
161 template <typename DerivedType, typename... ParamTypes>
162 struct FNullConsoleVariableDelegate
163 {
164 /**
165 * Static: Creates a raw C++ pointer global function delegate
166 */
167 template <typename... VarTypes>
168 inline static DerivedType CreateStatic(typename TIdentity<void (*)(ParamTypes..., VarTypes...)>::Type, VarTypes...)
169 {
170 return {};
171 }
172
173 template<typename FunctorType, typename... VarTypes>
174 inline static DerivedType CreateLambda(FunctorType&&, VarTypes...)
175 {
176 return {};
177 }
178
179 template<typename UserClass, typename FunctorType, typename... VarTypes>
180 inline static DerivedType CreateWeakLambda(UserClass*, FunctorType&&, VarTypes...)
181 {
182 return {};
183 }
184
185 template <typename UserClass, typename... VarTypes>
186 inline static DerivedType CreateRaw(UserClass*, typename TMemFunPtrType<false, UserClass, void (ParamTypes..., VarTypes...)>::Type, VarTypes...)
187 {
188 return {};
189 }
190 template <typename UserClass, typename... VarTypes>
191 inline static DerivedType CreateRaw(UserClass*, typename TMemFunPtrType<true, UserClass, void (ParamTypes..., VarTypes...)>::Type, VarTypes...)
192 {
193 return {};
194 }
195
196 template <typename UserClass, typename... VarTypes>
197 inline static DerivedType CreateSP(const TSharedRef<UserClass, ESPMode::Fast>&, typename TMemFunPtrType<false, UserClass, void (ParamTypes..., VarTypes...)>::Type, VarTypes...)
198 {
199 return {};
200 }
201 template <typename UserClass, typename... VarTypes>
202 inline static DerivedType CreateSP(const TSharedRef<UserClass, ESPMode::Fast>&, typename TMemFunPtrType<true, UserClass, void (ParamTypes..., VarTypes...)>::Type, VarTypes...)
203 {
204 return {};
205 }
206
207 template <typename UserClass, typename... VarTypes>
208 inline static DerivedType CreateSP(UserClass*, typename TMemFunPtrType<false, UserClass, void (ParamTypes..., VarTypes...)>::Type, VarTypes...)
209 {
210 return {};
211 }
212 template <typename UserClass, typename... VarTypes>
213 inline static DerivedType CreateSP(UserClass*, typename TMemFunPtrType<true, UserClass, void (ParamTypes..., VarTypes...)>::Type, VarTypes...)
214 {
215 return {};
216 }
217
218 template <typename UserClass, typename... VarTypes>
219 inline static DerivedType CreateThreadSafeSP(const TSharedRef<UserClass, ESPMode::ThreadSafe>&, typename TMemFunPtrType<false, UserClass, void (ParamTypes..., VarTypes...)>::Type, VarTypes...)
220 {
221 return {};
222 }
223 template <typename UserClass, typename... VarTypes>
224 inline static DerivedType CreateThreadSafeSP(const TSharedRef<UserClass, ESPMode::ThreadSafe>&, typename TMemFunPtrType<true, UserClass, void (ParamTypes..., VarTypes...)>::Type, VarTypes...)
225 {
226 return {};
227 }
228
229 template <typename UserClass, typename... VarTypes>
230 inline static DerivedType CreateThreadSafeSP(UserClass*, typename TMemFunPtrType<false, UserClass, void (ParamTypes..., VarTypes...)>::Type, VarTypes...)
231 {
232 return {};
233 }
234 template <typename UserClass, typename... VarTypes>
235 inline static DerivedType CreateThreadSafeSP(UserClass*, typename TMemFunPtrType<true, UserClass, void (ParamTypes..., VarTypes...)>::Type, VarTypes...)
236 {
237 return {};
238 }
239
240 template <typename UObjectTemplate, typename... VarTypes>
241 inline static DerivedType CreateUFunction(UObjectTemplate*, const FName&, VarTypes...)
242 {
243 return {};
244 }
245
246 template <typename UserClass, typename... VarTypes>
247 inline static DerivedType CreateUObject(UserClass*, typename TMemFunPtrType<false, UserClass, void (ParamTypes..., VarTypes...)>::Type, VarTypes...)
248 {
249 return {};
250 }
251 template <typename UserClass, typename... VarTypes>
252 inline static DerivedType CreateUObject(UserClass*, typename TMemFunPtrType<true, UserClass, void (ParamTypes..., VarTypes...)>::Type, VarTypes...)
253 {
254 return {};
255 }
256
257 FDelegateHandle GetHandle() const
258 {
259 return {};
260 }
261
262 bool ExecuteIfBound(ParamTypes...)
263 {
264 return false;
265 }
266 };
267
268 struct FConsoleVariableDelegate : FNullConsoleVariableDelegate<FConsoleVariableDelegate, IConsoleVariable*> {};
269 struct FConsoleCommandDelegate : FNullConsoleVariableDelegate<FConsoleCommandDelegate> {};
270 struct FConsoleCommandWithArgsDelegate : FNullConsoleVariableDelegate<FConsoleCommandWithArgsDelegate, const TArray<FString>&> {};
271 struct FConsoleCommandWithWorldDelegate : FNullConsoleVariableDelegate<FConsoleCommandWithWorldDelegate, UWorld*> {};
272 struct FConsoleCommandWithWorldAndArgsDelegate : FNullConsoleVariableDelegate<FConsoleCommandWithWorldAndArgsDelegate, const TArray<FString>&, UWorld*> {};
273 struct FConsoleCommandWithWorldArgsAndOutputDeviceDelegate : FNullConsoleVariableDelegate<FConsoleCommandWithWorldArgsAndOutputDeviceDelegate, const TArray<FString>&, UWorld*, FOutputDevice&> {};
274 struct FConsoleCommandWithOutputDeviceDelegate : FNullConsoleVariableDelegate<FConsoleCommandWithOutputDeviceDelegate, FOutputDevice&> {};
275
276 #endif
277
278 template <class T> class TConsoleVariableData;
279
280 /**
281 * Interface for console objects (variables and commands)
282 */
283 class IConsoleObject
284 {
285
286 public:
287
288 IConsoleObject()
289 #if TRACK_CONSOLE_FIND_COUNT
290 : FindCallCount(0)
291 #endif
292 {}
293
294 virtual ~IConsoleObject() {}
295
296 /**
297 * @return never 0, can be multi line ('\n')
298 */
299 virtual const TCHAR* GetHelp() const = 0;
300 /**
301 * @return never 0, can be multi line ('\n')
302 */
303 virtual void SetHelp(const TCHAR* Value) = 0;
304 /**
305 * Get the internal state of the flags.
306 */
307 virtual EConsoleVariableFlags GetFlags() const = 0;
308 /**
309 * Sets the internal flag state to the specified value.
310 */
311 virtual void SetFlags(const EConsoleVariableFlags Value) = 0;
312
313 // Convenience methods -------------------------------------
314
315 /**
316 * Removes the specified flags in the internal state.
317 */
318 void ClearFlags(const EConsoleVariableFlags Value)
319 {
320 uint32 New = (uint32)GetFlags() & ~(uint32)Value;
321
322 SetFlags((EConsoleVariableFlags)New);
323 }
324 /**
325 * Test is any of the specified flags is set in the internal state.
326 */
327 bool TestFlags(const EConsoleVariableFlags Value) const
328 {
329 return ((uint32)GetFlags() & (uint32)Value) != 0;
330 }
331
332 /**
333 * Casts this object to an IConsoleVariable, returns 0 if it's not
334 */
335 virtual class IConsoleVariable* AsVariable()
336 {
337 return 0;
338 }
339
340 virtual bool IsVariableBool() const { return false; }
341 virtual bool IsVariableInt() const { return false; }
342 virtual bool IsVariableFloat() const { return false; }
343 virtual bool IsVariableString() const { return false; }
344
345 virtual class TConsoleVariableData<bool>* AsVariableBool()
346 {
347 ensureMsgf(false, TEXT("Attempted to access variable data of a console variable type that doesn't support it. For example FindTConsoleVariableData* on a FAutoConsoleVariableRef."));
348 return 0;
349 }
350
351 virtual class TConsoleVariableData<int32>* AsVariableInt()
352 {
353 ensureMsgf(false, TEXT("Attempted to access variable data of a console variable type that doesn't support it. For example FindTConsoleVariableData* on a FAutoConsoleVariableRef."));
354 return 0;
355 }
356
357 virtual class TConsoleVariableData<float>* AsVariableFloat()
358 {
359 ensureMsgf(false, TEXT("Attempted to access variable data of a console variable type that doesn't support it. For example FindTConsoleVariableData* on a FAutoConsoleVariableRef."));
360 return 0;
361 }
362
363 virtual class TConsoleVariableData<FString>* AsVariableString()
364 {
365 ensureMsgf(false, TEXT("Attempted to access variable data of a console variable type that doesn't support it. For example FindTConsoleVariableData* on a FAutoConsoleVariableRef."));
366 return 0;
367 }
368
369 /**
370 * Casts this object to an IConsoleCommand, verifying first that it is safe to do so
371 */
372 virtual struct IConsoleCommand* AsCommand()
373 {
374 return 0;
375 }
376
377 private: // -----------------------------------------
378
379 #if TRACK_CONSOLE_FIND_COUNT
380 // no longer pure visual, if that causes problems we can change the interface
381 // to track down FindConsoleObject/FindConsoleVariable calls without static
382 uint32 FindCallCount;
383 #endif
384
385 /**
386 * should only be called by the manager, needs to be implemented for each instance
387 */
388 virtual void Release() = 0;
389
390 friend class FConsoleManager;
391 };
392
393 /**
394 * Interface for console variables
395 */
396 class IConsoleVariable : public IConsoleObject
397 {
398 public:
399
400 /**
401 * Set the internal value from the specified string.
402 * @param SetBy anything in ECVF_LastSetMask e.g. ECVF_SetByScalability
403 **/
404 virtual void Set(const TCHAR* InValue, EConsoleVariableFlags SetBy = ECVF_SetByCode) = 0;
405
406 /**
407 * Get the internal value as a bool, works on bools, ints and floats.
408 */
409 virtual bool GetBool() const = 0;
410 /**
411 * Get the internal value as int (should not be used on strings).
412 * @return value is not rounded (simple cast)
413 */
414 virtual int32 GetInt() const = 0;
415 /** Get the internal value as float (works on all types). */
416 virtual float GetFloat() const = 0;
417 /** Get the internal value as string (works on all types). */
418 virtual FString GetString() const = 0;
419
420 /** Generic versions for templated code */
421 void GetValue(int32& OutIntValue)
422 {
423 OutIntValue = GetInt();
424 }
425 void GetValue(bool& OutBoolValue)
426 {
427 OutBoolValue = GetBool();
428 }
429 void GetValue(float& OutFloatValue)
430 {
431 OutFloatValue = GetFloat();
432 }
433 void GetValue(FString& OutStringValue)
434 {
435 OutStringValue = GetString();
436 }
437
438 /**
439 * Allows to specify a callback function that is called when the console variable value changes.
440 * Is even called if the value is the same as the value before. Will always be on the game thread.
441 * This can be dangerous (instead try to use RegisterConsoleVariableSink())
442 * - Setting other console variables in the delegate can cause infinite loops
443 * - Setting many console variables could result in wasteful cycles (e.g. if multiple console variables require to reattach all objects it would happen for each one)
444 * - The call can be at any time during initialization.
445 * As this cannot be specified during constructions you are not called on creation.
446 * We also don't call for the SetOnChangedCallback() call as this is up to the caller.
447 **/
448 virtual void SetOnChangedCallback(const FConsoleVariableDelegate& Callback) = 0;
449
450 virtual FConsoleVariableMulticastDelegate& OnChangedDelegate() = 0;
451
452 // convenience methods
453
454 /** Set the internal value from the specified bool. */
455 void Set(bool InValue, EConsoleVariableFlags SetBy = ECVF_SetByCode)
456 {
457 // NOTE: Bool needs to use 1 and 0 here rather than true/false, as this may be a int32 or something
458 // and eventually this code calls, TTypeFromString<T>::FromString which won't handle the true/false,
459 // but 1 and 0 will work for whatever.
460 // inefficient but no common code path
461 Set(InValue ? TEXT("1") : TEXT("0"), SetBy);
462 }
463 /** Set the internal value from the specified int. */
464 void Set(int32 InValue, EConsoleVariableFlags SetBy = ECVF_SetByCode)
465 {
466 // inefficient but no common code path
467 Set(*FString::Printf(TEXT("%d"), InValue), SetBy);
468 }
469 /** Set the internal value from the specified float. */
470 void Set(float InValue, EConsoleVariableFlags SetBy = ECVF_SetByCode)
471 {
472 // inefficient but no common code path
473 Set(*FString::Printf(TEXT("%g"), InValue), SetBy);
474 }
475
476 void SetWithCurrentPriority(bool InValue)
477 {
478 EConsoleVariableFlags CurFlags = (EConsoleVariableFlags)(GetFlags() & ECVF_SetByMask);
479 Set(InValue, CurFlags);
480 }
481 void SetWithCurrentPriority(int32 InValue)
482 {
483 EConsoleVariableFlags CurFlags = (EConsoleVariableFlags)(GetFlags() & ECVF_SetByMask);
484 Set(InValue, CurFlags);
485 }
486 void SetWithCurrentPriority(float InValue)
487 {
488 EConsoleVariableFlags CurFlags = (EConsoleVariableFlags)(GetFlags() & ECVF_SetByMask);
489 Set(InValue, CurFlags);
490 }
491 void SetWithCurrentPriority(const TCHAR* InValue)
492 {
493 EConsoleVariableFlags CurFlags = (EConsoleVariableFlags)(GetFlags() & ECVF_SetByMask);
494 Set(InValue, CurFlags);
495 }
496 };
497
498 /**
499 * Interface for console commands
500 */
501 struct IConsoleCommand : public IConsoleObject
502 {
503 /**
504 * Executes this command (optionally, with arguments)
505 *
506 * @param Args Argument list for this command
507 * @param InWorld World context for this command
508 * @return True if the delegate for this command was executed successfully
509 */
510 virtual bool Execute( const TArray< FString >& Args, UWorld* InWorld, class FOutputDevice& OutputDevice ) = 0;
511 };
512
513 /**
514 * Interface to propagate changes of console variables to another thread
515 */
516 struct IConsoleThreadPropagation
517 {
518 virtual void OnCVarChange(int32& Dest, int32 NewValue) = 0;
519 virtual void OnCVarChange(float& Dest, float NewValue) = 0;
520 virtual void OnCVarChange(bool& Dest, bool NewValue) = 0;
521 virtual void OnCVarChange(FString& Dest, const FString& NewValue) = 0;
522 };
523
524 /**
525 * Declares a delegate type that's used by the console manager to call back into a user function for each
526 * known console object.
527 *
528 * First parameter is the Name string for the current console object
529 * Second parameter is the current console object
530 */
531 DECLARE_DELEGATE_TwoParams( FConsoleObjectVisitor, const TCHAR*, IConsoleObject* );
532
533
534 /**
535 * Class representing an handle to an online delegate.
536 */
537 class FConsoleVariableSinkHandle
538 {
539 public:
540 FConsoleVariableSinkHandle()
541 {
542 }
543
544 explicit FConsoleVariableSinkHandle(FDelegateHandle InHandle)
545 : Handle(InHandle)
546 {
547 }
548
549 template <typename MulticastDelegateType>
550 void RemoveFromDelegate(MulticastDelegateType& MulticastDelegate)
551 {
552 MulticastDelegate.Remove(Handle);
553 }
554
555 template <typename DelegateType>
556 bool HasSameHandle(const DelegateType& Delegate) const
557 {
558 return Delegate.GetHandle() == Handle;
559 }
560
561 private:
562 FDelegateHandle Handle;
563 };
564
565
566 /**
567 * Handles executing console commands
568 */
569 class IConsoleCommandExecutor : public IModularFeature
570 {
571 public:
572 virtual ~IConsoleCommandExecutor() = default;
573
574 /**
575 * Get the name identifying this modular feature set.
576 */
577 static FName ModularFeatureName()
578 {
579 static const FName Name = TEXT("ConsoleCommandExecutor");
580 return Name;
581 }
582
583 /**
584 * Get the name of this executor.
585 */
586 virtual FName GetName() const = 0;
587
588 /**
589 * Get the display name of this executor.
590 */
591 virtual FText GetDisplayName() const = 0;
592
593 /**
594 * Get the description of this executor.
595 */
596 virtual FText GetDescription() const = 0;
597
598 /**
599 * Get the hint text of this executor.
600 */
601 virtual FText GetHintText() const = 0;
602
603 /**
604 * Get the list of auto-complete suggestions for the given command.
605 */
606 virtual void GetAutoCompleteSuggestions(const TCHAR* Input, TArray<FString>& Out) = 0;
607
608 /**
609 * Get the list of commands that this executor has recently processed.
610 */
611 virtual void GetExecHistory(TArray<FString>& Out) = 0;
612
613 /**
614 * Execute the given command using this executor.
615 * @return true if the command was recognized.
616 */
617 virtual bool Exec(const TCHAR* Input) = 0;
618
619 /**
620 * True if we allow the console to be closed using the "open console" hot-key.
621 * @note Some scripting languages use the default "open console" hot-key (~) in their code, so these should return false.
622 */
623 virtual bool AllowHotKeyClose() const = 0;
624
625 /**
626 * True if we allow the console to create multi-line commands.
627 */
628 virtual bool AllowMultiLine() const = 0;
629
630 /**
631 * Returns the hotkey for this executor
632 */
633 virtual struct FInputChord GetHotKey() const = 0;
634 };
635
636
637 /**
638 * handles console commands and variables, registered console variables are released on destruction
639 */
640 struct CORE_API IConsoleManager
641 {
642 /**
643 * Create a bool console variable
644 * @param Name must not be 0
645 * @param Help must not be 0
646 * @param Flags bitmask combined from EConsoleVariableFlags
647 */
648 virtual IConsoleVariable* RegisterConsoleVariable(const TCHAR* Name, bool DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default) = 0;
649 /**
650 * Create a int console variable
651 * @param Name must not be 0
652 * @param Help must not be 0
653 * @param Flags bitmask combined from EConsoleVariableFlags
654 */
655 virtual IConsoleVariable* RegisterConsoleVariable(const TCHAR* Name, int32 DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default) = 0;
656 /**
657 * Create a float console variable
658 * @param Name must not be 0
659 * @param Help must not be 0
660 * @param Flags bitmask combined from EConsoleVariableFlags
661 */
662 virtual IConsoleVariable* RegisterConsoleVariable(const TCHAR* Name, float DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default) = 0;
663 /**
664 * Create a string console variable
665 * @param Name must not be 0
666 * @param Help must not be 0
667 * @param Flags bitmask combined from EConsoleVariableFlags
668 */
669 virtual IConsoleVariable* RegisterConsoleVariable(const TCHAR* Name, const TCHAR* DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default) = 0;
670 /**
671 * Create a string console variable
672 * @param Name must not be 0
673 * @param Help must not be 0
674 * @param Flags bitmask combined from EConsoleVariableFlags
675 */
676 virtual IConsoleVariable* RegisterConsoleVariable(const TCHAR* Name, const FString& DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default) = 0;
677 /**
678 * Create a reference to a bool console variable
679 * @param Name must not be 0
680 * @param Help must not be 0
681 * @param Flags bitmask combined from EConsoleVariableFlags
682 */
683 virtual IConsoleVariable* RegisterConsoleVariableRef(const TCHAR* Name, bool& RefValue, const TCHAR* Help, uint32 Flags = ECVF_Default) = 0;
684 /**
685 * Create a reference to a int console variable
686 * @param Name must not be 0
687 * @param Help must not be 0
688 * @param Flags bitmask combined from EConsoleVariableFlags
689 */
690 virtual IConsoleVariable* RegisterConsoleVariableRef(const TCHAR* Name, int32& RefValue, const TCHAR* Help, uint32 Flags = ECVF_Default) = 0;
691 /**
692 * Create a reference to a float console variable
693 * @param Name must not be 0
694 * @param Help must not be 0
695 * @param Flags bitmask combined from EConsoleVariableFlags
696 */
697 virtual IConsoleVariable* RegisterConsoleVariableRef(const TCHAR* Name, float& RefValue, const TCHAR* Help, uint32 Flags = ECVF_Default) = 0;
698 /**
699 * Create a reference to a string console variable
700 * @param Name must not be 0
701 * @param Help must not be 0
702 * @param Flags bitmask combined from EConsoleVariableFlags
703 */
704 virtual IConsoleVariable* RegisterConsoleVariableRef(const TCHAR* Name, FString& RefValue, const TCHAR* Help, uint32 Flags = ECVF_Default) = 0;
705 /**
706 * Create a reference to a show flag variable
707 * @param CVarName must not be 0, e.g. "Show.PostProcessing"
708 * @param FlagName must not be 0, e.g. "PostProcessing"
709 * @param BitNumber in the memory defined by Force0MaskPtr and Force1MaskPtr
710 * @param Force0MaskPtr memory that contains the bits that should be forced to 0
711 * @param Force1MaskPtr memory that contains the bits that should be forced to 1
712 * @param Help must not be 0
713 * @param Flags bitmask combined from EConsoleVariableFlags
714 */
715 virtual IConsoleVariable* RegisterConsoleVariableBitRef(const TCHAR* CVarName, const TCHAR* FlagName, uint32 BitNumber, uint8* Force0MaskPtr, uint8* Force1MaskPtr, const TCHAR* Help, uint32 Flags = ECVF_Default) = 0;
716
717 // ----------
718
719 /**
720 * The sinks are only called if a change has been done since the last time
721 * Should be called in very few points:
722 * - after ini file loading
723 * - after user console input
724 * - user initiated a console variable change (it needs to be clear to user that a cvar can change e.g. game options menu)
725 * - beginning of Tick (to catch stray Set() calls, which are usually bad)
726 */
727 virtual void CallAllConsoleVariableSinks() = 0;
728
729 /**
730 * The registered command is executed at few defined points (see CallAllConsoleVariableSinks)
731 * @param Command
732 */
733 virtual FConsoleVariableSinkHandle RegisterConsoleVariableSink_Handle(const FConsoleCommandDelegate& Command) = 0;
734
735 /**
736 * The registered command is executed at few defined points (see CallAllConsoleVariableSinks)
737 * @param Command
738 */
739 virtual void UnregisterConsoleVariableSink_Handle(FConsoleVariableSinkHandle Handle) = 0;
740
741 // ----------
742
743 /**
744 * Register a console command that takes no arguments
745 *
746 * @param Name The name of this command (must not be nullptr)
747 * @param Help Help text for this command
748 * @param Command The user function to call when this command is executed
749 * @param Flags Optional flags bitmask
750 */
751 virtual IConsoleCommand* RegisterConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandDelegate& Command, uint32 Flags = ECVF_Default) = 0;
752
753 /**
754 * Register a console command that takes arguments
755 *
756 * @param Name The name of this command (must not be nullptr)
757 * @param Help Help text for this command
758 * @param Command The user function to call when this command is executed
759 * @param Flags Optional flags bitmask
760 */
761 virtual IConsoleCommand* RegisterConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithArgsDelegate& Command, uint32 Flags = ECVF_Default) = 0;
762
763 /**
764 * Register a console command that takes arguments
765 *
766 * @param Name The name of this command (must not be nullptr)
767 * @param Help Help text for this command
768 * @param Command The user function to call when this command is executed
769 * @param Flags Optional flags bitmask
770 */
771 virtual IConsoleCommand* RegisterConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithWorldDelegate& Command, uint32 Flags = ECVF_Default) = 0;
772
773 /**
774 * Register a console command that takes arguments
775 *
776 * @param Name The name of this command (must not be nullptr)
777 * @param Help Help text for this command
778 * @param Command The user function to call when this command is executed
779 * @param Flags Optional flags bitmask
780 */
781 virtual IConsoleCommand* RegisterConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithWorldAndArgsDelegate& Command, uint32 Flags = ECVF_Default) = 0;
782
783 /**
784 * Register a console command that takes arguments
785 *
786 * @param Name The name of this command (must not be nullptr)
787 * @param Help Help text for this command
788 * @param Command The user function to call when this command is executed
789 * @param Flags Optional flags bitmask
790 */
791 virtual IConsoleCommand* RegisterConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithWorldArgsAndOutputDeviceDelegate& Command, uint32 Flags = ECVF_Default) = 0;
792
793 /**
794 * Register a console command that takes arguments
795 *
796 * @param Name The name of this command (must not be nullptr)
797 * @param Help Help text for this command
798 * @param Command The user function to call when this command is executed
799 * @param Flags Optional flags bitmask
800 */
801 virtual IConsoleCommand* RegisterConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithOutputDeviceDelegate& Command, uint32 Flags = ECVF_Default) = 0;
802
803 /**
804 * Register a console command that is handles by an Exec functions (for auto completion)
805 *
806 * @param Name The name of this command (must not be nullptr)
807 * @param Help Help text for this command
808 * @param Flags Optional flags bitmask
809 */
810 virtual IConsoleCommand* RegisterConsoleCommand(const TCHAR* Name, const TCHAR* Help, uint32 Flags = (uint32)ECVF_Default) = 0;
811
812 /**
813 * Unregisters a console object, if that object was registered. O(n), n is the console object count
814 *
815 * @param ConsoleObject - object to remove
816 * @param bKeepState if the current state is kept in memory until a cvar with the same name is registered
817 */
818 virtual void UnregisterConsoleObject( IConsoleObject* ConsoleObject, bool bKeepState = true) = 0;
819
820 /**
821 * Unregisters a console variable or command by name, if an object of that name was registered.
822 *
823 * @param Name - name of object to remove
824 * @param bKeepState if the current state is kept in memory until a cvar with the same name is registered
825 */
826 virtual void UnregisterConsoleObject(const TCHAR* Name, bool bKeepState = true) = 0;
827
828 /**
829 * Find a console variable
830 * @param Name must not be 0
831 * @return 0 if the object wasn't found
832 */
833 virtual IConsoleVariable* FindConsoleVariable(const TCHAR* Name, bool bTrackFrequentCalls = true) const = 0;
834
835 /**
836 * Find a console variable or command
837 * @param Name must not be 0
838 * @return 0 if the object wasn't found
839 */
840 virtual IConsoleObject* FindConsoleObject(const TCHAR* Name, bool bTrackFrequentCalls = true) const = 0;
841
842 /**
843 * Find a typed console variable (faster access to the value, no virtual function call)
844 * @param Name must not be 0
845 * @return 0 if the object wasn't found
846 */
847 TConsoleVariableData<int32>* FindTConsoleVariableDataInt(const TCHAR* Name) const
848 {
849 IConsoleVariable* P = FindConsoleVariable(Name);
850
851 return P ? P->AsVariableInt() : 0;
852 }
853
854 /**
855 * Find a typed console variable (faster access to the value, no virtual function call)
856 * @param Name must not be 0
857 * @return 0 if the object wasn't found
858 */
859 TConsoleVariableData<float>* FindTConsoleVariableDataFloat(const TCHAR* Name) const
860 {
861 IConsoleVariable* P = FindConsoleVariable(Name);
862
863 return P ? P->AsVariableFloat() : 0;
864 }
865
866
867 /**
868 * Iterate in O(n), not case sensitive, does not guarantee that UnregisterConsoleObject() will work in the loop
869 * @param Visitor must not be 0
870 * @param ThatStartsWith must not be 0
871 */
872 virtual void ForEachConsoleObjectThatStartsWith( const FConsoleObjectVisitor& Visitor, const TCHAR* ThatStartsWith = TEXT("")) const = 0;
873
874 /**
875 * Not case sensitive, does not guarantee that UnregisterConsoleObject() will work in the loop
876 * @param Visitor must not be 0
877 * @param ThatContains must not be 0
878 */
879 virtual void ForEachConsoleObjectThatContains(const FConsoleObjectVisitor& Visitor, const TCHAR* ThatContains) const = 0;
880
881 /**
882 * Process user input
883 * e.g.
884 * "MyCVar" to get the current value of the console variable
885 * "MyCVar -5.2" to set the value to -5.2
886 * "MyCVar ?" to get the help text
887 * @param Input must not be 0
888 * @param Ar archive
889 * @param InWorld world context
890 * @return true if the command was recognized
891 */
892 virtual bool ProcessUserConsoleInput(const TCHAR* Input, FOutputDevice& Ar, UWorld* InWorld) = 0;
893
894 /**
895 * @param Input - must not be 0
896 */
897 virtual void AddConsoleHistoryEntry(const TCHAR* Key, const TCHAR* Input) = 0;
898
899 /**
900 */
901 virtual void GetConsoleHistory(const TCHAR* Key, TArray<FString>& Out) = 0;
902
903 /**
904 * Check if a name (command or variable) has been registered with the console manager
905 * @param Name - Name to check. Must not be 0
906 */
907 virtual bool IsNameRegistered(const TCHAR* Name) const = 0;
908
909 // currently only for render thread
910 // @param InCallback 0 to disable the callbacks
911 virtual void RegisterThreadPropagation(uint32 ThreadId = 0, IConsoleThreadPropagation* InCallback = 0) = 0;
912
913 /** Returns the singleton for the console manager **/
914 FORCEINLINE static IConsoleManager& Get()
915 {
916 if (!Singleton)
917 {
918 SetupSingleton();
919 check(Singleton != nullptr);
920 }
921 return *Singleton;
922 }
923
924 protected:
925 virtual ~IConsoleManager() { }
926
927 private:
928 /** Singleton for the console manager **/
929 static IConsoleManager* Singleton;
930
931 /** Function to create the singleton **/
932 static void SetupSingleton();
933 };
934
935
936 /**
937 * auto registering console variable sinks (register a callback function that is called when ever a cvar is changes by the user, changes are grouped and happen in specific engine spots during the frame/main loop)
938 */
939 class CORE_API FAutoConsoleVariableSink
940 {
941 public:
942 /** Constructor, saves the argument for future removal from the console variable system **/
943 FAutoConsoleVariableSink(const FConsoleCommandDelegate& InCommand)
944 : Command(InCommand)
945 {
946 Handle = IConsoleManager::Get().RegisterConsoleVariableSink_Handle(Command);
947 }
948 /** Destructor, removes the console variable sink **/
949 virtual ~FAutoConsoleVariableSink()
950 {
951 //disabled for now, destruction order makes this not always working IConsoleManager::Get().UnregisterConsoleVariableSink_Handle(Handle);
952 }
953
954 const FConsoleCommandDelegate& Command;
955 FConsoleVariableSinkHandle Handle;
956 };
957
958
959 /**
960 * Base class for autoregistering console commands.
961 */
962 class CORE_API FAutoConsoleObject
963 {
964 protected:
965 /** Constructor, saves the argument for future removal from the console variable system **/
966 FAutoConsoleObject(IConsoleObject* InTarget)
967 : Target(InTarget)
968 {
969 check(Target);
970 }
971 /** Destructor, removes the console object **/
972 virtual ~FAutoConsoleObject()
973 {
974 IConsoleManager::Get().UnregisterConsoleObject(Target);
975 }
976
977 public:
978 /** returns the contained console object as an IConsoleVariable **/
979 FORCEINLINE IConsoleVariable* AsVariable()
980 {
981 checkSlow(Target->AsVariable());
982 return static_cast<IConsoleVariable*>(Target);
983 }
984 /** returns the contained console object as an IConsoleVariable **/
985 FORCEINLINE const IConsoleVariable* AsVariable() const
986 {
987 checkSlow(Target->AsVariable());
988 return static_cast<const IConsoleVariable*>(Target);
989 }
990
991 private:
992 /** Contained console object, cannot be 0 **/
993 IConsoleObject* Target;
994 };
995
996 #if !NO_CVARS
997 /**
998 * Autoregistering float, int or string console variable
999 */
1000 class CORE_API FAutoConsoleVariable : private FAutoConsoleObject
1001 {
1002 public:
1003 /**
1004 * Create a bool console variable
1005 * @param Name must not be 0
1006 * @param Help must not be 0
1007 * @param Flags bitmask combined from EConsoleVariableFlags
1008 */
1009 FAutoConsoleVariable(const TCHAR* Name, bool DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1010 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariable(Name, DefaultValue, Help, Flags))
1011 {
1012 }
1013 /**
1014 * Create a int console variable
1015 * @param Name must not be 0
1016 * @param Help must not be 0
1017 * @param Flags bitmask combined from EConsoleVariableFlags
1018 */
1019 FAutoConsoleVariable(const TCHAR* Name, int32 DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1020 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariable(Name, DefaultValue, Help, Flags))
1021 {
1022 }
1023 /**
1024 * Create a float console variable
1025 * @param Name must not be 0
1026 * @param Help must not be 0
1027 * @param Flags bitmask combined from EConsoleVariableFlags
1028 */
1029 FAutoConsoleVariable(const TCHAR* Name, float DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1030 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariable(Name, DefaultValue, Help, Flags))
1031 {
1032 }
1033 /**
1034 * Create a string console variable
1035 * @param Name must not be 0
1036 * @param Help must not be 0
1037 * @param Flags bitmask combined from EConsoleVariableFlags
1038 */
1039 FAutoConsoleVariable(const TCHAR* Name, const TCHAR* DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1040 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariable(Name, DefaultValue, Help, Flags))
1041 {
1042 }
1043
1044 /**
1045 * Create a bool console variable
1046 * @param Name must not be 0
1047 * @param Help must not be 0
1048 * @param Callback Delegate called when the variable changes. @see IConsoleVariable::SetOnChangedCallback
1049 * @param Flags bitmask combined from EConsoleVariableFlags
1050 */
1051 FAutoConsoleVariable(const TCHAR* Name, bool DefaultValue, const TCHAR* Help, const FConsoleVariableDelegate& Callback, uint32 Flags = ECVF_Default)
1052 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariable(Name, DefaultValue, Help, Flags))
1053 {
1054 AsVariable()->SetOnChangedCallback(Callback);
1055 }
1056
1057 /**
1058 * Create a int console variable
1059 * @param Name must not be 0
1060 * @param Help must not be 0
1061 * @param Callback Delegate called when the variable changes. @see IConsoleVariable::SetOnChangedCallback
1062 * @param Flags bitmask combined from EConsoleVariableFlags
1063 */
1064 FAutoConsoleVariable(const TCHAR* Name, int32 DefaultValue, const TCHAR* Help, const FConsoleVariableDelegate& Callback, uint32 Flags = ECVF_Default)
1065 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariable(Name, DefaultValue, Help, Flags))
1066 {
1067 AsVariable()->SetOnChangedCallback(Callback);
1068 }
1069
1070 /**
1071 * Create a float console variable
1072 * @param Name must not be 0
1073 * @param Help must not be 0
1074 * @param Callback Delegate called when the variable changes. @see IConsoleVariable::SetOnChangedCallback
1075 * @param Flags bitmask combined from EConsoleVariableFlags
1076 */
1077 FAutoConsoleVariable(const TCHAR* Name, float DefaultValue, const TCHAR* Help, const FConsoleVariableDelegate& Callback, uint32 Flags = ECVF_Default)
1078 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariable(Name, DefaultValue, Help, Flags))
1079 {
1080 AsVariable()->SetOnChangedCallback(Callback);
1081 }
1082
1083 /**
1084 * Create a string console variable
1085 * @param Name must not be 0
1086 * @param Help must not be 0
1087 * @param Callback Delegate called when the variable changes. @see IConsoleVariable::SetOnChangedCallback
1088 * @param Flags bitmask combined from EConsoleVariableFlags
1089 */
1090 FAutoConsoleVariable(const TCHAR* Name, const TCHAR* DefaultValue, const TCHAR* Help, const FConsoleVariableDelegate& Callback, uint32 Flags = ECVF_Default)
1091 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariable(Name, DefaultValue, Help, Flags))
1092 {
1093 AsVariable()->SetOnChangedCallback(Callback);
1094 }
1095
1096 /** Dereference back to a console variable**/
1097 FORCEINLINE IConsoleVariable& operator*()
1098 {
1099 return *AsVariable();
1100 }
1101 FORCEINLINE const IConsoleVariable& operator*() const
1102 {
1103 return *AsVariable();
1104 }
1105 /** Dereference back to a console variable**/
1106 FORCEINLINE IConsoleVariable* operator->()
1107 {
1108 return AsVariable();
1109 }
1110 FORCEINLINE const IConsoleVariable* operator->() const
1111 {
1112 return AsVariable();
1113 }
1114 };
1115 #else
1116 class CORE_API FAutoConsoleVariable
1117 {
1118 public:
1119 FAutoConsoleVariable(const TCHAR* Name, int32 DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1120 {
1121 }
1122
1123 FAutoConsoleVariable(const TCHAR* Name, float DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1124 {
1125 }
1126
1127 FAutoConsoleVariable(const TCHAR* Name, const TCHAR* DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1128 {
1129 }
1130 };
1131 #endif
1132
1133 #if !NO_CVARS
1134 /**
1135 * Autoregistering float, int, bool, FString REF variable class...this changes that value when the console variable is changed.
1136 */
1137 class CORE_API FAutoConsoleVariableRef : private FAutoConsoleObject
1138 {
1139 public:
1140 /**
1141 * Create a reference to a int console variable
1142 * @param Name must not be 0
1143 * @param Help must not be 0
1144 * @param Flags bitmask combined from EConsoleVariableFlags
1145 */
1146 FAutoConsoleVariableRef(const TCHAR* Name, int32& RefValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1147 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariableRef(Name, RefValue, Help, Flags))
1148 {
1149 }
1150 /**
1151 * Create a reference to a float console variable
1152 * @param Name must not be 0
1153 * @param Help must not be 0
1154 * @param Flags bitmask combined from EConsoleVariableFlags
1155 */
1156 FAutoConsoleVariableRef(const TCHAR* Name, float& RefValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1157 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariableRef(Name, RefValue, Help, Flags))
1158 {
1159 }
1160 /**
1161 * Create a reference to a bool console variable
1162 * @param Name must not be 0
1163 * @param Help must not be 0
1164 * @param Flags bitmask combined from EConsoleVariableFlags
1165 */
1166 FAutoConsoleVariableRef(const TCHAR* Name, bool& RefValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1167 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariableRef(Name, RefValue, Help, Flags))
1168 {
1169 }
1170 /**
1171 * Create a reference to a FString console variable
1172 * @param Name must not be 0
1173 * @param Help must not be 0
1174 * @param Flags bitmask combined from EConsoleVariableFlags
1175 */
1176 FAutoConsoleVariableRef(const TCHAR* Name, FString& RefValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1177 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariableRef(Name, RefValue, Help, Flags))
1178 {
1179 }
1180
1181 /**
1182 * Create a reference to a int console variable
1183 * @param Name must not be 0
1184 * @param Help must not be 0
1185 * @param Callback Delegate called when the variable changes. @see IConsoleVariable::SetOnChangedCallback
1186 * @param Flags bitmask combined from EConsoleVariableFlags
1187 */
1188 FAutoConsoleVariableRef(const TCHAR* Name, int32& RefValue, const TCHAR* Help, const FConsoleVariableDelegate& Callback, uint32 Flags = ECVF_Default)
1189 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariableRef(Name, RefValue, Help, Flags))
1190 {
1191 AsVariable()->SetOnChangedCallback(Callback);
1192 }
1193
1194 /**
1195 * Create a reference to a float console variable
1196 * @param Name must not be 0
1197 * @param Help must not be 0
1198 * @param Callback Delegate called when the variable changes. @see IConsoleVariable::SetOnChangedCallback
1199 * @param Flags bitmask combined from EConsoleVariableFlags
1200 */
1201 FAutoConsoleVariableRef(const TCHAR* Name, float& RefValue, const TCHAR* Help, const FConsoleVariableDelegate& Callback, uint32 Flags = ECVF_Default)
1202 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariableRef(Name, RefValue, Help, Flags))
1203 {
1204 AsVariable()->SetOnChangedCallback(Callback);
1205 }
1206
1207 /**
1208 * Create a reference to a bool console variable
1209 * @param Name must not be 0
1210 * @param Help must not be 0
1211 * @param Callback Delegate called when the variable changes. @see IConsoleVariable::SetOnChangedCallback
1212 * @param Flags bitmask combined from EConsoleVariableFlags
1213 */
1214 FAutoConsoleVariableRef(const TCHAR* Name, bool& RefValue, const TCHAR* Help, const FConsoleVariableDelegate& Callback, uint32 Flags = ECVF_Default)
1215 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariableRef(Name, RefValue, Help, Flags))
1216 {
1217 AsVariable()->SetOnChangedCallback(Callback);
1218 }
1219
1220 /**
1221 * Create a reference to a FString console variable
1222 * @param Name must not be 0
1223 * @param Help must not be 0
1224 * @param Callback Delegate called when the variable changes. @see IConsoleVariable::SetOnChangedCallback
1225 * @param Flags bitmask combined from EConsoleVariableFlags
1226 */
1227 FAutoConsoleVariableRef(const TCHAR* Name, FString& RefValue, const TCHAR* Help, const FConsoleVariableDelegate& Callback, uint32 Flags = ECVF_Default)
1228 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariableRef(Name, RefValue, Help, Flags))
1229 {
1230 AsVariable()->SetOnChangedCallback(Callback);
1231 }
1232
1233 virtual ~FAutoConsoleVariableRef()
1234 {
1235 }
1236 /** Dereference back to a variable**/
1237 FORCEINLINE IConsoleVariable& operator*()
1238 {
1239 return *AsVariable();
1240 }
1241 FORCEINLINE const IConsoleVariable& operator*() const
1242 {
1243 return *AsVariable();
1244 }
1245 /** Dereference back to a variable**/
1246 FORCEINLINE IConsoleVariable* operator->()
1247 {
1248 return AsVariable();
1249 }
1250 FORCEINLINE const IConsoleVariable* operator->() const
1251 {
1252 return AsVariable();
1253 }
1254 };
1255 #else
1256 class CORE_API FAutoConsoleVariableRef
1257 {
1258 public:
1259 FAutoConsoleVariableRef(const TCHAR* Name, int32& RefValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1260 {
1261 }
1262
1263 FAutoConsoleVariableRef(const TCHAR* Name, float& RefValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1264 {
1265 }
1266
1267 FAutoConsoleVariableRef(const TCHAR* Name, bool& RefValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1268 {
1269 }
1270
1271 FAutoConsoleVariableRef(const TCHAR* Name, FString& RefValue, const TCHAR* Help, uint32 Flags = ECVF_Default)
1272 {
1273 }
1274
1275 FAutoConsoleVariableRef(const TCHAR* Name, int32& RefValue, const TCHAR* Help, const FConsoleVariableDelegate& Callback, uint32 Flags = ECVF_Default)
1276 {
1277 }
1278
1279 FAutoConsoleVariableRef(const TCHAR* Name, float& RefValue, const TCHAR* Help, const FConsoleVariableDelegate& Callback, uint32 Flags = ECVF_Default)
1280 {
1281 }
1282
1283 FAutoConsoleVariableRef(const TCHAR* Name, bool& RefValue, const TCHAR* Help, const FConsoleVariableDelegate& Callback, uint32 Flags = ECVF_Default)
1284 {
1285 }
1286
1287 FAutoConsoleVariableRef(const TCHAR* Name, FString& RefValue, const TCHAR* Help, const FConsoleVariableDelegate& Callback, uint32 Flags = ECVF_Default)
1288 {
1289 }
1290 };
1291 #endif // NO_CVARS
1292
1293
1294 // currently only supports main and render thread
1295 // optimized for read access speed (no virtual function call and no thread handling if using the right functions)
1296 // T: int32, float
1297 template <class T>
1298 class TConsoleVariableData
1299 {
1300 public:
1301 // constructor
1302 TConsoleVariableData(const T DefaultValue)
1303 {
1304 for(uint32 i = 0; i < UE_ARRAY_COUNT(ShadowedValue); ++i)
1305 {
1306 ShadowedValue[i] = DefaultValue;
1307 }
1308 }
1309
1310 // faster than GetValueOnAnyThread()
1311 T GetValueOnGameThread() const
1312 {
1313 // compiled out in shipping for performance (we can change in development later), if this get triggered you need to call GetValueOnRenderThread() or GetValueOnAnyThread(), the last one is a bit slower
1314 cvarCheckCode(ensure(GetShadowIndex() == 0)); // ensure to not block content creators, #if to optimize in shipping
1315 return ShadowedValue[0];
1316 }
1317
1318 // faster than GetValueOnAnyThread()
1319 T GetValueOnRenderThread() const
1320 {
1321 #if !defined(__clang__) // @todo Mac: figure out how to make this compile
1322 // compiled out in shipping for performance (we can change in development later), if this get triggered you need to call GetValueOnGameThread() or GetValueOnAnyThread(), the last one is a bit slower
1323 cvarCheckCode(ensure(IsInParallelRenderingThread())); // ensure to not block content creators, #if to optimize in shipping
1324 #endif
1325 return ShadowedValue[1];
1326 }
1327
1328 // convenient, for better performance consider using GetValueOnGameThread() or GetValueOnRenderThread()
1329 T GetValueOnAnyThread(bool bForceGameThread = false) const
1330 {
1331 return ShadowedValue[GetShadowIndex(bForceGameThread)];
1332 }
1333
1334 private: // ----------------------------------------------------
1335
1336 // [0]:main thread, [1]: render thread, having them both in the same cache line should only hurt on write which happens rarely for cvars
1337 T ShadowedValue[2];
1338
1339 // @return 0:main thread, 1: render thread, later more
1340 static uint32 GetShadowIndex(bool bForceGameThread = false)
1341 {
1342 if (bForceGameThread)
1343 {
1344 cvarCheckCode(ensure(!IsInActualRenderingThread()));
1345 return 0;
1346 }
1347 return IsInGameThread() ? 0 : 1;
1348 }
1349
1350 // needed for FConsoleVariable and FConsoleVariableRef2, intentionally not public
1351 T& GetReferenceOnAnyThread(bool bForceGameThread = false)
1352 {
1353 return ShadowedValue[GetShadowIndex(bForceGameThread)];
1354 }
1355
1356 template<class T2> friend class FConsoleVariable;
1357 template<class T2> friend class TAutoConsoleVariable;
1358 };
1359
1360 #if !NO_CVARS
1361 /**
1362 * Autoregistering float, int variable class...this changes that value when the console variable is changed.
1363 */
1364 template <class T>
1365 class TAutoConsoleVariable : public FAutoConsoleObject
1366 {
1367 public:
1368 /**
1369 * Create a float, int or string console variable
1370 * @param Name must not be 0
1371 * @param Help must not be 0
1372 * @param Flags bitmask combined from EConsoleVariableFlags
1373 */
1374 TAutoConsoleVariable(const TCHAR* Name, const T& DefaultValue, const TCHAR* Help, uint32 Flags = ECVF_Default);
1375
1376 T GetValueOnGameThread() const
1377 {
1378 return Ref->GetValueOnGameThread();
1379 }
1380
1381 T GetValueOnRenderThread() const
1382 {
1383 return Ref->GetValueOnRenderThread();
1384 }
1385
1386 T GetValueOnAnyThread(bool bForceGameThread = false) const
1387 {
1388 return Ref->GetValueOnAnyThread(bForceGameThread);
1389 }
1390
1391 /** Dereference back to a variable**/
1392 FORCEINLINE IConsoleVariable& operator*()
1393 {
1394 return *AsVariable();
1395 }
1396 FORCEINLINE const IConsoleVariable& operator*() const
1397 {
1398 return *AsVariable();
1399 }
1400 /** Dereference back to a variable**/
1401 FORCEINLINE IConsoleVariable* operator->()
1402 {
1403 return AsVariable();
1404 }
1405 FORCEINLINE const IConsoleVariable* operator->() const
1406 {
1407 return AsVariable();
1408 }
1409 private:
1410 TConsoleVariableData<T>* Ref;
1411 };
1412
1413 template <>
1414 inline TAutoConsoleVariable<bool>::TAutoConsoleVariable(const TCHAR* Name, const bool& DefaultValue, const TCHAR* Help, uint32 Flags)
1415 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariable(Name, DefaultValue, Help, Flags))
1416 {
1417 Ref = AsVariable()->AsVariableBool();
1418 }
1419
1420 template <>
1421 inline TAutoConsoleVariable<int32>::TAutoConsoleVariable(const TCHAR* Name, const int32& DefaultValue, const TCHAR* Help, uint32 Flags)
1422 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariable(Name, DefaultValue, Help, Flags))
1423 {
1424 Ref = AsVariable()->AsVariableInt();
1425 }
1426
1427 template <>
1428 inline TAutoConsoleVariable<float>::TAutoConsoleVariable(const TCHAR* Name, const float& DefaultValue, const TCHAR* Help, uint32 Flags)
1429 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariable(Name, DefaultValue, Help, Flags))
1430 {
1431 Ref = AsVariable()->AsVariableFloat();
1432 }
1433
1434 template <>
1435 inline TAutoConsoleVariable<FString>::TAutoConsoleVariable(const TCHAR* Name, const FString& DefaultValue, const TCHAR* Help, uint32 Flags)
1436 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleVariable(Name, DefaultValue, Help, Flags))
1437 {
1438 Ref = AsVariable()->AsVariableString();
1439 }
1440 #else
1441 template <class T>
1442 class TAutoConsoleVariable : public IConsoleVariable
1443 {
1444 public:
1445 TAutoConsoleVariable(const TCHAR* Name, const T& DefaultValue, const TCHAR* InHelp, uint32 InFlags = ECVF_Default)
1446 : Value(DefaultValue), Flags((EConsoleVariableFlags)InFlags)
1447 {
1448 }
1449
1450 T GetValueOnGameThread() const
1451 {
1452 return Value.GetValueOnGameThread();
1453 }
1454
1455 T GetValueOnRenderThread() const
1456 {
1457 return Value.GetValueOnRenderThread();
1458 }
1459
1460 T GetValueOnAnyThread(bool bForceGameThread = false) const
1461 {
1462 return Value.GetValueOnAnyThread(bForceGameThread);
1463 }
1464
1465 IConsoleVariable& operator*()
1466 {
1467 return *AsVariable();
1468 }
1469
1470 const IConsoleVariable& operator*() const
1471 {
1472 return *AsVariable();
1473 }
1474
1475 IConsoleVariable* operator->()
1476 {
1477 return AsVariable();
1478 }
1479
1480 const IConsoleVariable* operator->() const
1481 {
1482 return AsVariable();
1483 }
1484
1485 IConsoleVariable* AsVariable() { return this; }
1486 const IConsoleVariable* AsVariable() const { return this; }
1487
1488 virtual class TConsoleVariableData<int32>* AsVariableInt() override { return AsImpl<int32>(); }
1489 virtual class TConsoleVariableData<float>* AsVariableFloat() override { return AsImpl<float>(); }
1490 virtual class TConsoleVariableData<FString>* AsVariableString() override { return AsImpl<FString>(); }
1491
1492 virtual bool IsVariableInt() const override { return TIsSame<int32, T>::Value; }
1493 virtual int32 GetInt() const override { return GetImpl<int32>(); }
1494 virtual float GetFloat() const override { return GetImpl<float>(); }
1495 virtual FString GetString() const override { return GetImpl<FString>(); }
1496 virtual bool GetBool() const override { return GetImpl<bool>(); }
1497
1498 virtual const TCHAR* GetHelp() const override
1499 {
1500 return TEXT("NO_CVARS, no help");
1501 }
1502
1503 virtual void SetHelp(const TCHAR* InHelp) override
1504 {
1505 check(false);
1506 }
1507
1508 virtual void Release() override
1509 {
1510 check(false);
1511 }
1512
1513 virtual void SetOnChangedCallback(const FConsoleVariableDelegate &) override
1514 {
1515 check(false);
1516 }
1517
1518 virtual FConsoleVariableMulticastDelegate& OnChangedDelegate()override
1519 {
1520 static FConsoleVariableMulticastDelegate Dummy;
1521 check(false);
1522 return Dummy;
1523 }
1524
1525 virtual EConsoleVariableFlags GetFlags() const override
1526 {
1527 return Flags;
1528 }
1529
1530 virtual void SetFlags(const EConsoleVariableFlags InFlags) override
1531 {
1532 Flags = InFlags;
1533 }
1534
1535 virtual void Set(const TCHAR* InValue, EConsoleVariableFlags SetBy) override
1536 {
1537 LexFromString(Value.ShadowedValue[0], InValue);
1538 }
1539
1540 private:
1541 TConsoleVariableData<T> Value;
1542 FString Help;
1543 EConsoleVariableFlags Flags = EConsoleVariableFlags::ECVF_Default;
1544
1545 template<class Y>
1546 typename TEnableIf<!TIsSame<T, Y>::Value, Y>::Type GetImpl() const
1547 {
1548 check(false);
1549 return Y();
1550 }
1551
1552 template<class Y>
1553 typename TEnableIf<TIsSame<T, Y>::Value, Y>::Type GetImpl() const
1554 {
1555 return GetValueOnAnyThread();
1556 }
1557
1558 template<class Y>
1559 typename TEnableIf<!TIsSame<T, Y>::Value, TConsoleVariableData<Y>*>::Type AsImpl()
1560 {
1561 check(false);
1562 return nullptr;
1563 }
1564
1565 template<class Y>
1566 typename TEnableIf<TIsSame<T, Y>::Value, TConsoleVariableData<T>*>::Type AsImpl()
1567 {
1568 return &Value;
1569 }
1570 };
1571 #endif // NO_CVARS
1572
1573 #if !NO_CVARS
1574 /**
1575 * Autoregistering console command
1576 */
1577 class CORE_API FAutoConsoleCommand : private FAutoConsoleObject
1578 {
1579 public:
1580 /**
1581 * Register a console command that takes no arguments
1582 *
1583 * @param Name The name of this command (must not be nullptr)
1584 * @param Help Help text for this command
1585 * @param Command The user function to call when this command is executed
1586 * @param Flags Optional flags bitmask
1587 */
1588 FAutoConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandDelegate& Command, uint32 Flags = ECVF_Default)
1589 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleCommand(Name, Help, Command, Flags))
1590 {
1591 }
1592
1593 /**
1594 * Register a console command that takes arguments
1595 *
1596 * @param Name The name of this command (must not be nullptr)
1597 * @param Help Help text for this command
1598 * @param Command The user function to call when this command is executed
1599 * @param Flags Optional flags bitmask
1600 */
1601 FAutoConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithArgsDelegate& Command, uint32 Flags = ECVF_Default)
1602 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleCommand(Name, Help, Command, Flags))
1603 {
1604 }
1605
1606 /**
1607 * Register a console command that takes arguments, a world argument and an output device
1608 *
1609 * @param Name The name of this command (must not be nullptr)
1610 * @param Help Help text for this command
1611 * @param Command The user function to call when this command is executed
1612 * @param Flags Optional flags bitmask
1613 */
1614 FAutoConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithWorldArgsAndOutputDeviceDelegate& Command, uint32 Flags = ECVF_Default)
1615 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleCommand(Name, Help, Command, Flags))
1616 {
1617 }
1618 };
1619 #else
1620 class CORE_API FAutoConsoleCommand
1621 {
1622 public:
1623 FAutoConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandDelegate& Command, uint32 Flags = ECVF_Default)
1624 {
1625 }
1626
1627 FAutoConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithArgsDelegate& Command, uint32 Flags = ECVF_Default)
1628 {
1629 }
1630
1631 FAutoConsoleCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithWorldArgsAndOutputDeviceDelegate& Command, uint32 Flags = ECVF_Default)
1632 {
1633 }
1634 };
1635 #endif
1636
1637
1638 #if !NO_CVARS
1639 /**
1640 * Autoregistering console command with a world
1641 */
1642 class CORE_API FAutoConsoleCommandWithWorld : private FAutoConsoleObject
1643 {
1644 public:
1645 /**
1646 * Register a console command that takes a world argument
1647 *
1648 * @param Name The name of this command (must not be nullptr)
1649 * @param Help Help text for this command
1650 * @param Command The user function to call when this command is executed
1651 * @param Flags Optional flags bitmask
1652 */
1653 FAutoConsoleCommandWithWorld(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithWorldDelegate& Command, uint32 Flags = ECVF_Default)
1654 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleCommand(Name, Help, Command, Flags))
1655 {
1656 }
1657
1658
1659 };
1660
1661 /**
1662 * Autoregistering console command with a world and arguments
1663 */
1664 class CORE_API FAutoConsoleCommandWithWorldAndArgs : private FAutoConsoleObject
1665 {
1666 public:
1667 /**
1668 * Register a console command that takes arguments and a world argument
1669 *
1670 * @param Name The name of this command (must not be nullptr)
1671 * @param Help Help text for this command
1672 * @param Command The user function to call when this command is executed
1673 * @param Flags Optional flags bitmask
1674 */
1675 FAutoConsoleCommandWithWorldAndArgs(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithWorldAndArgsDelegate& Command, uint32 Flags = ECVF_Default)
1676 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleCommand(Name, Help, Command, Flags))
1677 {
1678 }
1679 };
1680
1681 /**
1682 * Autoregistering console command with an output device
1683 */
1684 class CORE_API FAutoConsoleCommandWithOutputDevice : private FAutoConsoleObject
1685 {
1686 public:
1687 /**
1688 * Register a console command that takes an output device
1689 *
1690 * @param Name The name of this command (must not be nullptr)
1691 * @param Help Help text for this command
1692 * @param Command The user function to call when this command is executed
1693 * @param Flags Optional flags bitmask
1694 */
1695 FAutoConsoleCommandWithOutputDevice(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithOutputDeviceDelegate& Command, uint32 Flags = ECVF_Default)
1696 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleCommand(Name, Help, Command, Flags))
1697 {
1698 }
1699 };
1700
1701 /**
1702 * Autoregistering console command with world, args, an output device
1703 */
1704 class CORE_API FAutoConsoleCommandWithWorldArgsAndOutputDevice : private FAutoConsoleObject
1705 {
1706 public:
1707 /**
1708 * Register a console command that takes an output device
1709 *
1710 * @param Name The name of this command (must not be nullptr)
1711 * @param Help Help text for this command
1712 * @param Command The user function to call when this command is executed
1713 * @param Flags Optional flags bitmask
1714 */
1715 FAutoConsoleCommandWithWorldArgsAndOutputDevice(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithWorldArgsAndOutputDeviceDelegate& Command, uint32 Flags = ECVF_Default)
1716 : FAutoConsoleObject(IConsoleManager::Get().RegisterConsoleCommand(Name, Help, Command, Flags))
1717 {
1718 }
1719 };
1720
1721 #else
1722
1723 class FAutoConsoleCommandWithWorld
1724 {
1725 public:
1726 template<class... Args> FAutoConsoleCommandWithWorld(const Args&...) {}
1727 };
1728
1729 class FAutoConsoleCommandWithWorldAndArgs
1730 {
1731 public:
1732 template<class... Args> FAutoConsoleCommandWithWorldAndArgs(const Args&...) {}
1733 };
1734
1735 class FAutoConsoleCommandWithOutputDevice
1736 {
1737 public:
1738 template<class... Args> FAutoConsoleCommandWithOutputDevice(const Args&...) {}
1739 };
1740
1741 class FAutoConsoleCommandWithWorldArgsAndOutputDevice
1742 {
1743 public:
1744 template<class... Args> FAutoConsoleCommandWithWorldArgsAndOutputDevice(const Args&...) {}
1745 };
1746
1747 #endif
1748
1749 CORE_API DECLARE_LOG_CATEGORY_EXTERN(LogConsoleResponse, Log, All);