I have noticed that BlueprintCallable are skipped when called for the Class Default Object. This would be a valueable for the Bluprint graph for data object.
I would like the ability to lay out my data object via the BlueprintGraph rather than having to rely on the Blueprint Data Only class default window. When I have a sufficiently deep hierarchy it becomes quite unwieldy.
// H
#pragma once
#include "Courage/CourageCommon.h"
#include "Courage/Core/CourageConstructionInterface.h"
#include "CoreMinimal.h"
#include "Delegates/Delegate.h"
#include "Delegates/DelegateCombinations.h"
#include "UObject/ObjectMacros.h"
#include "UObject/UnrealType.h"
#if WITH_EDITOR
#include "UObject/ObjectCompileContext.h"
#include "UObject/ObjectSaveContext.h"
#endif
#include "CourageObject.generated.h"
// https://heapcleaner.wordpress.com/2016/06/11/uobject-constructor-postinitproperties-and-postload/
USTRUCT(BlueprintType)
struct FCourageObjectPostCDOCompiledContext
{
GENERATED_BODY()
public:
/** True if the Blueprint is currently being regenerated for the first time after being loaded (aka, compile-on-load) */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
bool bIsRegeneratingOnLoad = false;
/** True if this notification was from a 'skeleton-only' compile */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
bool bIsSkeletonOnly = false;
FCourageObjectPostCDOCompiledContext()
{}
#if WITH_EDITOR
FCourageObjectPostCDOCompiledContext(const FObjectPostCDOCompiledContext& Ctx)
: bIsRegeneratingOnLoad(Ctx.bIsRegeneratingOnLoad)
, bIsSkeletonOnly(Ctx.bIsSkeletonOnly)
{
}
#endif
};
UCLASS(BlueprintType
, Blueprintable
, ClassGroup = "Courage"
, meta = (
PrioritizeCategories = "Courage Courage|Internal"
, AutoCollapseCategories = "Courage|Internal"
))
class COURAGE_API UCourageObject : public UObject
{
GENERATED_BODY()
public:
UCourageObject();
UFUNCTION(BlueprintPure, CallInEditor)
UObject* GetClassDefaultObject() const { return GetClass()->GetDefaultObject(); }
UFUNCTION(BlueprintCallable, CallInEditor)
void TESTFUNCTION() const;
/**
* Called after the C++ constructor and after the properties have been initialized, including those loaded from config.
* This is called before any serialization or other setup has happened.
*/
virtual void PostInitProperties() override;
UFUNCTION(BlueprintImplementableEvent, CallInEditor)
void BlueprintPostInitProperties();
/**
* Called after properties are overwritten, including after subobjects initialization from a CDO.
* This could be called multiple times during an object lifetime, which is not the case for PostInitProperties which is expected to be called only once.
*/
virtual void PostReinitProperties() override;
UFUNCTION(BlueprintImplementableEvent, CallInEditor)
void BlueprintPostReinitProperties();
/**
* Called after the C++ constructor has run on the Class Default Object (CDO) for a class. This is an obscure routine used to deal with the recursion
* in the construction of the default materials
*/
virtual void PostCDOContruct() override;
UFUNCTION(BlueprintImplementableEvent, CallInEditor)
void BlueprintPostCDOContruct();
#if WITH_EDITOR
/**
* Called after the Blueprint compiler has finished generating the Class Default Object (CDO) for a class. This can only happen in the editor.
* This is called when the CDO and its associated class structure have been fully generated and populated, and allows the assignment of cached/derived data,
* eg) caching the name/count of properties of a certain type, or inspecting the properties on the class and using their meta-data and CDO default values to derive game data.
*/
virtual void PostCDOCompiled(const Super::FPostCDOCompiledContext& Context) override;
UFUNCTION(BlueprintImplementableEvent, CallInEditor)
void BlueprintPostCDOCompiled(const FCourageObjectPostCDOCompiledContext& InContext);
virtual void PreSaveRoot(FObjectPreSaveRootContext ObjectSaveContext) override;
UFUNCTION(BlueprintImplementableEvent, CallInEditor)
void BlueprintPreSaveRoot();
virtual void PostSaveRoot(FObjectPostSaveRootContext ObjectSaveContext) override;
UFUNCTION(BlueprintImplementableEvent, CallInEditor)
void BlueprintPostSaveRoot();
virtual void PreSave(FObjectPreSaveContext SaveContext) override;
UFUNCTION(BlueprintImplementableEvent, CallInEditor)
void BlueprintPreSave();
#endif
/**
* Do any object-specific cleanup required immediately after loading an object.
* This is not called for newly-created objects, and by default will always execute on the game thread.
*/
virtual void PostLoad() override;
UFUNCTION(BlueprintImplementableEvent, CallInEditor)
void BlueprintPostLoad();
};
// CPP
#include "Courage/Core/CourageObject.h"
UCourageObject::UCourageObject()
: Super()
{
}
void UCourageObject::TESTFUNCTION() const
{
UE_LOG(LogTemp, Warning, TEXT("TESTFUNCTION has been called"));
}
void UCourageObject::PostInitProperties()
{
Super::PostInitProperties();
BlueprintPostInitProperties();
UE_LOG(LogTemp, Warning, TEXT("PostInitProperties has been called"));
}
void UCourageObject::PostReinitProperties()
{
Super::PostReinitProperties();
BlueprintPostReinitProperties();
UE_LOG(LogTemp, Warning, TEXT("PostReinitProperties has been called"));
}
void UCourageObject::PostCDOContruct()
{
Super::PostCDOContruct();
BlueprintPostCDOContruct();
UE_LOG(LogTemp, Warning, TEXT("PostCDOContruct has been called"));
}
void UCourageObject::PostLoad()
{
Super::PostLoad();
//BlueprintPostLoad();
}
#if WITH_EDITOR
void UCourageObject::PostCDOCompiled(const Super::FPostCDOCompiledContext& Context)
{
Super::PostCDOCompiled(Context);
FCourageObjectPostCDOCompiledContext Ctx(Context);
BlueprintPostCDOCompiled(Ctx);
UE_LOG(LogTemp, Warning, TEXT("PostCDOCompiled has been called"))
}
void UCourageObject::PreSaveRoot(FObjectPreSaveRootContext ObjectSaveContext)
{
Super::PreSaveRoot(ObjectSaveContext);
BlueprintPreSaveRoot();
UE_LOG(LogTemp, Warning, TEXT("PreSaveRoot has been called"))
}
void UCourageObject::PostSaveRoot(FObjectPostSaveRootContext ObjectSaveContext)
{
Super::PostSaveRoot(ObjectSaveContext);
BlueprintPostSaveRoot();
UE_LOG(LogTemp, Warning, TEXT("PostSaveRoot has been called"))
}
void UCourageObject::PreSave(FObjectPreSaveContext SaveContext)
{
Super::PreSave(SaveContext);
BlueprintPreSave();
UE_LOG(LogTemp, Warning, TEXT("PreSave has been called"))
}
#endif