2021-09-28 13:33:00 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# pragma once
# include "Delegates/DelegateCombinations.h"
# include "SmartObjectTypes.h"
2021-11-26 15:48:13 -05:00
# include "SmartObjectDefinition.h"
2021-09-28 13:33:00 -04:00
# include "SmartObjectOctree.h"
# include "SmartObjectRuntime.generated.h"
/**
* Enumeration to represent the runtime state of a slot
*/
UENUM ( )
enum class ESmartObjectSlotState : uint8
{
Free ,
Claimed ,
Occupied ,
MAX
} ;
/**
* Struct describing a reservation between a user and a smart object slot .
*/
2021-11-26 15:48:13 -05:00
USTRUCT ( BlueprintType )
2021-09-28 13:33:00 -04:00
struct SMARTOBJECTSMODULE_API FSmartObjectClaimHandle
{
GENERATED_BODY ( )
FSmartObjectClaimHandle ( const FSmartObjectID InSmartObjectID , const FSmartObjectSlotIndex & InSlotIndex , const FSmartObjectUserID & InUser = { } )
: SmartObjectID ( InSmartObjectID ) , SlotIndex ( InSlotIndex ) , UserID ( InUser )
{ }
FSmartObjectClaimHandle ( )
{ }
bool operator = = ( const FSmartObjectClaimHandle & Other ) const
{
return IsValid ( ) & & Other . IsValid ( )
& & SmartObjectID = = Other . SmartObjectID
& & SlotIndex = = Other . SlotIndex
& & UserID = = Other . UserID ;
}
2021-11-26 15:48:13 -05:00
bool operator ! = ( const FSmartObjectClaimHandle & Other ) const
{
return ! ( * this = = Other ) ;
}
2021-09-28 13:33:00 -04:00
FString Describe ( ) const
{
return FString : : Printf ( TEXT ( " Object:%s Slot:%s User:%s " ) , * SmartObjectID . Describe ( ) , * SlotIndex . Describe ( ) , * UserID . Describe ( ) ) ;
}
void Invalidate ( ) { * this = InvalidHandle ; }
bool IsValid ( ) const
{
return SmartObjectID . IsValid ( )
& & SlotIndex . IsValid ( )
& & UserID . IsValid ( ) ;
}
static const FSmartObjectClaimHandle InvalidHandle ;
UPROPERTY ( Transient )
FSmartObjectID SmartObjectID ;
UPROPERTY ( Transient )
FSmartObjectSlotIndex SlotIndex ;
FSmartObjectUserID UserID ;
} ;
/** Delegate to notify when a given slot gets invalidated and the interaction must be aborted */
DECLARE_DELEGATE_TwoParams ( FOnSlotInvalidated , const FSmartObjectClaimHandle & , ESmartObjectSlotState /* Current State */ ) ;
/**
2021-11-26 15:48:13 -05:00
* Struct to store and manage state of a runtime instance associated to a given slot definition
2021-09-28 13:33:00 -04:00
*/
USTRUCT ( )
struct FSmartObjectSlotRuntimeData
{
GENERATED_BODY ( )
public :
/* Provide default constructor to be able to compile template instantiation 'UScriptStruct::TCppStructOps<FSmartObjectSlotRuntimeData>' */
/* Also public to pass void 'UScriptStruct::TCppStructOps<FSmartObjectSlotRuntimeData>::ConstructForTests(void *)' */
FSmartObjectSlotRuntimeData ( ) { }
2021-11-29 11:34:31 -05:00
ESmartObjectSlotState GetState ( ) const { return State ; }
2021-09-28 13:33:00 -04:00
protected :
/** Struct could have been nested inside the subsystem but not possible with USTRUCT */
friend class USmartObjectSubsystem ;
friend struct FSmartObjectRuntime ;
2021-11-02 11:12:43 -04:00
explicit FSmartObjectSlotRuntimeData ( const FSmartObjectSlotIndex & InSlotIndex ) : SlotIndex ( InSlotIndex ) { }
2021-09-28 13:33:00 -04:00
bool Claim ( const FSmartObjectUserID & InUser ) ;
FString Describe ( ) const { return FString : : Printf ( TEXT ( " User:%s Slot:%s " ) , * User . Describe ( ) , * SlotIndex . Describe ( ) ) ; }
static const FSmartObjectSlotRuntimeData InvalidSlot ;
/** Current availability state of the slot */
ESmartObjectSlotState State = ESmartObjectSlotState : : Free ;
/** Id of the user that reserves or uses the slot */
FSmartObjectUserID User ;
2021-11-26 15:48:13 -05:00
/** Index of the slot in the smart object definition to which this runtime data is associated to */
2021-09-28 13:33:00 -04:00
FSmartObjectSlotIndex SlotIndex ;
/** Delegate used to notify when a slot gets invalidated. See RegisterSlotInvalidationCallback */
FOnSlotInvalidated OnSlotInvalidatedDelegate ;
} ;
/**
2021-11-26 15:48:13 -05:00
* Struct to store and manage state of a runtime instance associated to a given smart object definition
2021-09-28 13:33:00 -04:00
*/
USTRUCT ( )
struct FSmartObjectRuntime
{
GENERATED_BODY ( )
public :
const FSmartObjectID & GetRegisteredID ( ) const { return RegisteredID ; }
const FTransform & GetTransform ( ) const { return Transform ; }
2021-11-26 15:48:13 -05:00
const USmartObjectDefinition & GetDefinition ( ) const { checkf ( Definition ! = nullptr , TEXT ( " Initialized from a valid reference from the constructor " ) ) ; return * Definition ; }
2021-11-29 11:34:31 -05:00
ESmartObjectSlotState GetSlotState ( const uint32 SlotIndex ) const ;
2021-09-28 13:33:00 -04:00
/* Provide default constructor to be able to compile template instantiation 'UScriptStruct::TCppStructOps<FSmartObjectRuntime>' */
/* Also public to pass void 'UScriptStruct::TCppStructOps<FSmartObjectRuntime>::ConstructForTests(void *)' */
FSmartObjectRuntime ( ) : SharedOctreeID ( MakeShareable ( new FSmartObjectOctreeID ( ) ) ) { }
private :
/** Struct could have been nested inside the subsystem but not possible with USTRUCT */
friend class USmartObjectSubsystem ;
2021-11-26 15:48:13 -05:00
explicit FSmartObjectRuntime ( const USmartObjectDefinition & Definition ) ;
2021-09-28 13:33:00 -04:00
const FGameplayTagContainer & GetTags ( ) const { return Tags ; }
void SetTransform ( const FTransform & Value ) { Transform = Value ; }
2021-11-02 11:12:43 -04:00
void SetRegisteredID ( const FSmartObjectID Value ) { RegisteredID = Value ; }
2021-09-28 13:33:00 -04:00
const FSmartObjectOctreeIDSharedRef & GetSharedOctreeID ( ) const { return SharedOctreeID ; }
void SetOctreeID ( const FSmartObjectOctreeIDSharedRef Value ) { SharedOctreeID = Value ; }
const FBoxCenterAndExtent & GetBounds ( ) const { return Bounds ; }
void SetBounds ( const FBox & Value ) { Bounds = Value ; }
2021-11-26 15:48:13 -05:00
FString Describe ( ) const { return FString : : Printf ( TEXT ( " Instance using defintion \' %s \' Reg: %s " ) , * GetDefinition ( ) . Describe ( ) , * LexToString ( SharedOctreeID - > ID . IsValidId ( ) ) ) ; }
2021-09-28 13:33:00 -04:00
/**
* @ param OutFreeSlots function will set ' false ' at taken slots ' indices
* @ return the number of free slots found
*/
uint32 FindFreeSlots ( TBitArray < > & OutFreeSlots ) const ;
/**
* Reserves the slot associated to the provided handle by marking it as ' claimed ' .
* @ param ClaimHandle Handle identifying a user / slot pair
* @ return whether or not the slot was successfully claimed
*/
bool ClaimSlot ( const FSmartObjectClaimHandle & ClaimHandle ) ;
/**
* Mark an available slot as ' occupied ' .
* @ param ClaimHandle Handle identifying a user / slot pair
* @ return whether or not the slot was successfully marked as ' occupied '
*/
bool UseSlot ( const FSmartObjectClaimHandle & ClaimHandle ) ;
/**
* Releases the slot associated to the provided handle by marking it as ' free ' .
* The operation will ensure if the slot is not currently claimed or in use by the user associated to the handle .
* @ param ClaimHandle A valid handle identifying a user / slot pair
* @ param bAborted Indicates if the slot must be released because the slot has been invalidated by the system ( e . g . unregistered object )
* @ return whether or not the slot was successfully freed
*/
bool ReleaseSlot ( const FSmartObjectClaimHandle & ClaimHandle , const bool bAborted ) ;
/** Runtime data associated to each defined slot */
UPROPERTY ( )
TArray < FSmartObjectSlotRuntimeData > SlotsRuntimeData ;
2021-11-26 15:48:13 -05:00
/** Associated smart object definition */
UPROPERTY ( )
const USmartObjectDefinition * Definition = nullptr ;
2021-09-28 13:33:00 -04:00
/** Instance specific transform */
FTransform Transform ;
/** Instance specific bounds */
FBoxCenterAndExtent Bounds ;
/** Tags applied to the current instance */
FGameplayTagContainer Tags ;
/** RegisteredID != FSmartObject::InvalidID when registered with SmartObjectSubsystem */
FSmartObjectID RegisteredID ;
/** Reference to the associated octree node ID */
FSmartObjectOctreeIDSharedRef SharedOctreeID ;
} ;