// Copyright 2020 Phyronnaz #pragma once #include "CoreMinimal.h" #include "VoxelMinimal.h" #include "Templates/SubclassOf.h" #include "VoxelGenerators/VoxelGenerator.h" #include "VoxelGeneratorPicker.generated.h" UENUM(BlueprintType) enum class EVoxelGeneratorPickerType : uint8 { Class, Object }; template struct TVoxelGeneratorPicker { public: using UGenerator = TGenerator; using FGeneratorInstance = typename TChooseClass::Value, FVoxelGeneratorInstance, FVoxelTransformableGeneratorInstance>::Result; TVoxelGeneratorPicker() = default; TVoxelGeneratorPicker(TYPE_OF_NULLPTR) {} TVoxelGeneratorPicker(UClass* InClass) { Type = EVoxelGeneratorPickerType::Class; Class = InClass; } TVoxelGeneratorPicker(TSubclassOf InClass) : TVoxelGeneratorPicker(InClass.Get()) { } TVoxelGeneratorPicker(UGenerator* InObject) { Type = EVoxelGeneratorPickerType::Object; Object = InObject; } TVoxelGeneratorPicker(TSoftClassPtr InClass) : TVoxelGeneratorPicker(InClass.LoadSynchronous()) { } TVoxelGeneratorPicker(TSoftObjectPtr InObject) : TVoxelGeneratorPicker(InObject.LoadSynchronous()) { } template TVoxelGeneratorPicker(TVoxelGeneratorPicker Picker) { Type = Picker.Type; Class = Picker.Class.Get(); Object = Cast(Picker.Object); } public: EVoxelGeneratorPickerType Type = EVoxelGeneratorPickerType::Class; TSubclassOf Class; TObjectPtr Object = nullptr; TMap Parameters; #if WITH_EDITORONLY_DATA TObjectPtr EditorData = nullptr; #endif // Might return nullptr! UGenerator* GetGenerator() const { if (Type == EVoxelGeneratorPickerType::Class) { return Class ? Class->template GetDefaultObject() : nullptr; } else { return Object; } } UObject* GetObject() const { if (Type == EVoxelGeneratorPickerType::Class) { return Class; } else { return Object; } } bool IsValid() const { return GetObject() != nullptr; } bool IsClass() const { return Type == EVoxelGeneratorPickerType::Class; } bool IsObject() const { return Type == EVoxelGeneratorPickerType::Object; } bool operator==(const TVoxelGeneratorPicker& Other) const { // We ignore editor data here return Type == Other.Type && (Type == EVoxelGeneratorPickerType::Class ? (Class == Other.Class) : (Object == Other.Object)) && Parameters.OrderIndependentCompareEqual(Other.Parameters); } }; template uint32 GetTypeHash(const TVoxelGeneratorPicker& Key) { return HashCombine(GetTypeHash(Key.GetObject()), GetTypeHash(Key.Parameters.Num())); } USTRUCT(BlueprintType, meta=(HasNativeMake="Voxel.VoxelGeneratorTools.MakeGeneratorPickerFromObject")) struct VOXEL_API FVoxelGeneratorPicker #if CPP : TVoxelGeneratorPicker #endif { GENERATED_BODY() using TVoxelGeneratorPicker::TVoxelGeneratorPicker; // Will default to EmptyGenerator if null TVoxelSharedRef GetInstance(bool bSilent) const; #if !CPP UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel") EVoxelGeneratorPickerType Type = EVoxelGeneratorPickerType::Class; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel") TSubclassOf Class; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel", meta = (DisallowedClasses = "VoxelGraphMacro")) TObjectPtr Object = nullptr; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel") TMap Parameters; #if WITH_EDITORONLY_DATA UPROPERTY(Transient) TObjectPtr EditorData = nullptr; #endif #endif }; USTRUCT(BlueprintType, meta=(HasNativeMake="Voxel.VoxelGeneratorTools.MakeTransformableGeneratorPickerFromObject")) struct FVoxelTransformableGeneratorPicker #if CPP : TVoxelGeneratorPicker #endif { GENERATED_BODY() using TVoxelGeneratorPicker::TVoxelGeneratorPicker; // Will default to EmptyGenerator if null TVoxelSharedRef GetInstance(bool bSilent) const; #if !CPP UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel") EVoxelGeneratorPickerType Type = EVoxelGeneratorPickerType::Class; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel") TSubclassOf Class; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel", meta = (DisallowedClasses = "VoxelGraphMacro")) TObjectPtr Object = nullptr; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel") TMap Parameters; #if WITH_EDITORONLY_DATA UPROPERTY(Transient) TObjectPtr EditorData = nullptr; #endif #endif }; VOXEL_DEPRECATED(1.2, "Use FVoxelGeneratorPicker instead of FVoxelWorldGeneratorPicker") typedef FVoxelGeneratorPicker FVoxelWorldGeneratorPicker; VOXEL_DEPRECATED(1.2, "Use FVoxelTransformableGeneratorPicker instead of FVoxelTransformableWorldGeneratorPicker") typedef FVoxelTransformableGeneratorPicker FVoxelTransformableWorldGeneratorPicker;