用法:参考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);

UE4/UE4.27-Source/Engine\Source\Runtime\Core\Public\HAL\IConsoleManager.h (last edited 2021-11-02 04:16:31 by zbjxb)