From 4b116bf9da591721d6cec00442dd7ba1da08e21d Mon Sep 17 00:00:00 2001
From: martinluckyrobots <martinliu73@gmail.com>
Date: Wed, 2 Apr 2025 13:40:55 +0800
Subject: [PATCH] Optimize CaptureSetting, GoalTask, etc.

---
 .../Private/LuckyRobotsFunctionLibrary.cpp    |  47 ++++++
 .../Private/LuckyRobotsGameInstance.cpp       |  77 +++++++++
 .../Public/LuckyRobotsFunctionLibrary.h       |   7 +
 .../Public/LuckyRobotsGameInstance.h          |  33 ++++
 Source/Luckyrobots/Public/SharedDef.h         | 156 +++++++++++++++++-
 5 files changed, 311 insertions(+), 9 deletions(-)

diff --git a/Source/Luckyrobots/Private/LuckyRobotsFunctionLibrary.cpp b/Source/Luckyrobots/Private/LuckyRobotsFunctionLibrary.cpp
index 3a574c33..8bc3eabd 100644
--- a/Source/Luckyrobots/Private/LuckyRobotsFunctionLibrary.cpp
+++ b/Source/Luckyrobots/Private/LuckyRobotsFunctionLibrary.cpp
@@ -4,6 +4,8 @@
 #include "LuckyRobotsFunctionLibrary.h"
 #include "LuckyRobotsGameInstance.h"
 #include "GameFramework/GameUserSettings.h"
+#include "Kismet/GameplayStatics.h"
+#include "SG_CaptureSetting.h"
 
 ULuckyRobotsGameInstance* ULuckyRobotsFunctionLibrary::GetLuckyRobotsGameInstance(const UObject* WorldContextObject)
 {
@@ -76,4 +78,49 @@ void ULuckyRobotsFunctionLibrary::UpdateQualitySettings(const UObject* WorldCont
 			GameUserSettings->ApplySettings(true);
 		}
 	}
+}
+
+FCaptureSettingsData ULuckyRobotsFunctionLibrary::LoadCaptureSettings()
+{
+	FCaptureSettingsData DefaultCaptureSetting;
+	DefaultCaptureSetting.FolderName = FText::FromString("robotdata");
+	DefaultCaptureSetting.FileName = FText::FromString("FILE");
+	DefaultCaptureSetting.WritesPerSec = FText::FromString("1");
+	DefaultCaptureSetting.NumberOfPeople = FText::FromString("1");
+	DefaultCaptureSetting.NumberOfObjects = FText::FromString("1");
+	DefaultCaptureSetting.NumberOfCaptures = FText::FromString("1");
+
+	USG_CaptureSetting* SaveGame = nullptr;
+	SaveGame = Cast<USG_CaptureSetting>(UGameplayStatics::LoadGameFromSlot("SGCaptureSettings", 0));
+	if (SaveGame)
+	{
+		return SaveGame->CaptureSetting;
+	}
+	else
+	{
+		SaveGame = Cast<USG_CaptureSetting>(UGameplayStatics::CreateSaveGameObject(USG_CaptureSetting::StaticClass()));
+		if (SaveGame)
+		{
+			SaveGame->CaptureSetting = DefaultCaptureSetting;
+			UGameplayStatics::SaveGameToSlot(SaveGame, "SGCaptureSettings", 0);
+		}
+	}
+
+	return DefaultCaptureSetting;
+}
+
+void ULuckyRobotsFunctionLibrary::SaveCaptureSettings(FCaptureSettingsData CaptureSetting)
+{
+	USG_CaptureSetting* SaveGame = nullptr;
+	SaveGame = Cast<USG_CaptureSetting>(UGameplayStatics::LoadGameFromSlot("SGCaptureSettings", 0));
+	if (!SaveGame)
+	{
+		SaveGame = Cast<USG_CaptureSetting>(UGameplayStatics::CreateSaveGameObject(USG_CaptureSetting::StaticClass()));
+	}
+
+	if (SaveGame)
+	{
+		SaveGame->CaptureSetting = CaptureSetting;
+		UGameplayStatics::SaveGameToSlot(SaveGame, "SGCaptureSettings", 0);
+	}
 }
\ No newline at end of file
diff --git a/Source/Luckyrobots/Private/LuckyRobotsGameInstance.cpp b/Source/Luckyrobots/Private/LuckyRobotsGameInstance.cpp
index 78d52314..2dbcb649 100644
--- a/Source/Luckyrobots/Private/LuckyRobotsGameInstance.cpp
+++ b/Source/Luckyrobots/Private/LuckyRobotsGameInstance.cpp
@@ -3,3 +3,80 @@
 
 #include "LuckyRobotsGameInstance.h"
 
+void ULuckyRobotsGameInstance::ClearTaskList()
+{
+	TaskList.Empty();
+}
+
+void ULuckyRobotsGameInstance::AddTask(FGoalsTaskData TaskData)
+{
+	TaskList.Add(TaskData);
+}
+void ULuckyRobotsGameInstance::RemoveTask(FGoalsTaskData TaskData)
+{
+	TaskList.Remove(TaskData);
+}
+
+void ULuckyRobotsGameInstance::RemoveTaskByGoalType(EGoalType GoalType)
+{
+	for (auto Task : TaskList)
+	{
+		if (Task.GoalType == GoalType)
+		{
+			RemoveTask(Task);
+			break;
+		}
+	}
+}
+
+int ULuckyRobotsGameInstance::GetTaskNum()
+{
+	return TaskList.Num();
+}
+
+void ULuckyRobotsGameInstance::SetTask(int Index, FGoalsTaskData TaskData)
+{
+	if (TaskList.IsValidIndex(Index))
+	{
+		TaskList[Index] = TaskData;
+	}
+	else
+	{
+		for (int i = TaskList.Num(); i < Index; i++)
+		{
+			FGoalsTaskData TempTaskData;
+			AddTask(TempTaskData);
+		}
+		AddTask(TaskData);
+	}
+}
+
+bool ULuckyRobotsGameInstance::GetTask(int Index, FGoalsTaskData& TaskData)
+{
+	if (TaskList.IsValidIndex(Index))
+	{
+		TaskData = TaskList[Index];
+		return true;
+	}
+
+	return false;
+}
+
+void ULuckyRobotsGameInstance::ReSetTaskList()
+{
+	TArray<FGoalsTaskData> TempTaskList;
+	for (auto Task : TaskList)
+	{
+		Task.bIsStart = false;
+		Task.bIsStart = false;
+		Task.bActive = false;
+		TempTaskList.Add(Task);
+	}
+
+	TaskList = TempTaskList;
+}
+
+TArray<FGoalsTaskData> ULuckyRobotsGameInstance::GetTaskList()
+{
+	return TaskList;
+}
\ No newline at end of file
diff --git a/Source/Luckyrobots/Public/LuckyRobotsFunctionLibrary.h b/Source/Luckyrobots/Public/LuckyRobotsFunctionLibrary.h
index d55be048..96e487f1 100644
--- a/Source/Luckyrobots/Public/LuckyRobotsFunctionLibrary.h
+++ b/Source/Luckyrobots/Public/LuckyRobotsFunctionLibrary.h
@@ -8,6 +8,7 @@
 #include "LuckyRobotsFunctionLibrary.generated.h"
 
 class ULuckyRobotsGameInstance;
+class USG_CaptureSetting;
 /**
  * 
  */
@@ -27,4 +28,10 @@ public:
 
 	UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject"))
 	static void UpdateQualitySettings(const UObject* WorldContextObject);
+
+	UFUNCTION(BlueprintCallable)
+	static FCaptureSettingsData LoadCaptureSettings();
+
+	UFUNCTION(BlueprintCallable)
+	static void SaveCaptureSettings(FCaptureSettingsData CaptureSetting);
 };
diff --git a/Source/Luckyrobots/Public/LuckyRobotsGameInstance.h b/Source/Luckyrobots/Public/LuckyRobotsGameInstance.h
index dbfc7a67..2f517383 100644
--- a/Source/Luckyrobots/Public/LuckyRobotsGameInstance.h
+++ b/Source/Luckyrobots/Public/LuckyRobotsGameInstance.h
@@ -33,7 +33,40 @@ public:
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
 	EQualityEnum CurrentSelectQuality = EQualityEnum::Epic;
 
+	UPROPERTY(EditAnywhere, BlueprintReadWrite)
+	TArray<FGoalsTaskData> TaskList;
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite)
+	FGoalsTaskData TempTask;
+
 public:
 	UFUNCTION(BlueprintImplementableEvent)
 	void DoGetDispatch(const FString& EventName, USIOJsonValue* EventData);
+
+	UFUNCTION(BlueprintCallable)
+	void ClearTaskList();
+
+	UFUNCTION(BlueprintCallable)
+	void AddTask(FGoalsTaskData TaskData);
+
+	UFUNCTION(BlueprintCallable)
+	void RemoveTask(FGoalsTaskData TaskData);
+
+	UFUNCTION(BlueprintCallable)
+	void RemoveTaskByGoalType(EGoalType GoalType);
+
+	UFUNCTION(BlueprintPure)
+	int GetTaskNum();
+
+	UFUNCTION(BlueprintCallable)
+	void SetTask(int Index, FGoalsTaskData TaskData);
+
+	UFUNCTION(BlueprintCallable)
+	bool GetTask(int Index, FGoalsTaskData& TaskData);
+
+	UFUNCTION(BlueprintCallable)
+	void ReSetTaskList();
+
+	UFUNCTION(BlueprintPure)
+	TArray<FGoalsTaskData> GetTaskList();
 };
diff --git a/Source/Luckyrobots/Public/SharedDef.h b/Source/Luckyrobots/Public/SharedDef.h
index be25e5c3..6ab9acd4 100644
--- a/Source/Luckyrobots/Public/SharedDef.h
+++ b/Source/Luckyrobots/Public/SharedDef.h
@@ -75,7 +75,27 @@ enum class EGoalType : uint8
 {
 	GrabAndPull	 					UMETA(DisplayName = "Grab and Pull"),
 	GrabAndRotate 					UMETA(DisplayName = "Grab and Rotate"),
-
+	GrabAndOpen 					UMETA(DisplayName = "Grab and Open"),
+	PickAndPlace 					UMETA(DisplayName = "Pick and Place"),
+	Pick 							UMETA(DisplayName = "Pick"),
+	GrabAndInsert 					UMETA(DisplayName = "Grab and Insert"),
+	Find 							UMETA(DisplayName = "Find"),
+	Point 							UMETA(DisplayName = "Point"),
+	PointWithLaserPointer 			UMETA(DisplayName = "Point with Laser Pointer"),
+	RotateHand 						UMETA(DisplayName = "Rotate Hand"),
+	SliceDice 						UMETA(DisplayName = "Slice/Dice"),
+	Wipe 							UMETA(DisplayName = "Wipe"),
+	FoldUnfold 						UMETA(DisplayName = "Fold/Unfold"),
+	ArrangeOrganize 				UMETA(DisplayName = "Arrange/Organize"),
+	PressButton 					UMETA(DisplayName = "Press Button"),
+	PourDispense 					UMETA(DisplayName = "Pour/Dispense"),
+	NavigateSimpleEnvironments 		UMETA(DisplayName = "Navigate Simple Environments"),
+	NavigateComplexTerrain 			UMETA(DisplayName = "Navigate Complex Terrain"),
+	ClimbStairsOrRamps 				UMETA(DisplayName = "Climb Stairs or Ramps"),
+	BalanceStabilize 				UMETA(DisplayName = "Balance/Stabilize"),
+	DockingAndCharging 				UMETA(DisplayName = "Docking and Charging"),
+	ChangeGripper 					UMETA(DisplayName = "Change Gripper"),
+	Place 							UMETA(DisplayName = "Place")
 };
 
 USTRUCT(BlueprintType)
@@ -131,6 +151,32 @@ public:
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
 	TArray<ERobotsCategories> RobotTypeList;
+
+	bool operator==(const FLevelData& Other) const
+	{
+		return ID == Other.ID &&
+			LevelEnum == Other.LevelEnum &&
+			LevelType == Other.LevelType &&
+			LevelObject == Other.LevelObject &&
+			LevelImage == Other.LevelImage &&
+			bActive == Other.bActive &&
+			RobotTypeList == Other.RobotTypeList; 
+	}
+
+	FLevelData& operator=(const FLevelData& Other)
+	{
+		if (this != &Other) 
+		{
+			ID = Other.ID;
+			LevelEnum = Other.LevelEnum;
+			LevelType = Other.LevelType;
+			LevelObject = Other.LevelObject;
+			LevelImage = Other.LevelImage;
+			bActive = Other.bActive;
+			RobotTypeList = Other.RobotTypeList;
+		}
+		return *this;
+	}
 };
 
 USTRUCT(BlueprintType)
@@ -148,7 +194,7 @@ public:
 	FTransform TargetLocation;
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
-	AActor* TargetActor;
+	TSoftObjectPtr<UObject> TargetActor;
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
 	bool bIsComplate;
@@ -161,6 +207,34 @@ public:
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
 	bool bActive;
+
+	bool operator==(const FGoalsTaskData& Other) const
+	{
+		return GoalType == Other.GoalType &&
+			bIsStart == Other.bIsStart &&
+			TargetLocation.Equals(Other.TargetLocation, 0.01f) &&  
+			TargetActor == Other.TargetActor &&
+			bIsComplate == Other.bIsComplate &&
+			DropOffLocation.Equals(Other.DropOffLocation, 0.01f) &&
+			ObjectName == Other.ObjectName &&
+			bActive == Other.bActive;
+	}
+
+	FGoalsTaskData& operator=(const FGoalsTaskData& Other)
+	{
+		if (this != &Other) 
+		{
+			GoalType = Other.GoalType;
+			bIsStart = Other.bIsStart;
+			TargetLocation = Other.TargetLocation;
+			TargetActor = Other.TargetActor;
+			bIsComplate = Other.bIsComplate;
+			DropOffLocation = Other.DropOffLocation;
+			ObjectName = Other.ObjectName;
+			bActive = Other.bActive;
+		}
+		return *this;
+	}
 };
 
 USTRUCT(BlueprintType)
@@ -169,13 +243,13 @@ struct FCaptureSettingsData : public FTableRowBase
 	GENERATED_BODY()
 public:
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
-	FText FolderName;
+	FText FolderName = FText::FromString("robotdata");
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
-	FText FileName;
+	FText FileName = FText::FromString("FILE");
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
-	FText WritesPerSec;
+	FText WritesPerSec = FText::FromString("1");
 
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
@@ -203,20 +277,84 @@ public:
 	bool bPeople;
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
-	FText NumberOfPeople;
+	FText NumberOfPeople = FText::FromString("1");
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
 	bool bObjects;
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
-	FText NumberOfObjects; 
+	FText NumberOfObjects = FText::FromString("1");
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
-	TArray<UStaticMeshComponent*> RandomMeshes;
+	TArray<TSoftObjectPtr<UStaticMeshComponent>> RandomMeshes;
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
 	bool bInfiniteCapture; 
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
-	FText NumberOfCaptures;
+	FText NumberOfCaptures = FText::FromString("1");
+
+	bool operator==(const FCaptureSettingsData& Other) const
+	{
+		return FolderName.EqualTo(Other.FolderName) &&
+			FileName.EqualTo(Other.FileName) &&
+			WritesPerSec.EqualTo(Other.WritesPerSec) &&
+			IsScenario == Other.IsScenario &&
+			TaskList == Other.TaskList && 
+			bLight == Other.bLight &&
+			bMaterials == Other.bMaterials &&
+			bRobotPosition == Other.bRobotPosition &&
+			bPets == Other.bPets &&
+			NumberOfPets.EqualTo(Other.NumberOfPets) &&
+			bPeople == Other.bPeople &&
+			NumberOfPeople.EqualTo(Other.NumberOfPeople) &&
+			bObjects == Other.bObjects &&
+			NumberOfObjects.EqualTo(Other.NumberOfObjects) &&
+			RandomMeshes == Other.RandomMeshes &&  
+			bInfiniteCapture == Other.bInfiniteCapture &&
+			NumberOfCaptures.EqualTo(Other.NumberOfCaptures);
+	}
+
+	FCaptureSettingsData& operator=(const FCaptureSettingsData& Other)
+	{
+		if (this != &Other) 
+		{
+			FolderName = Other.FolderName;
+			FileName = Other.FileName;
+			WritesPerSec = Other.WritesPerSec;
+			IsScenario = Other.IsScenario;
+			TaskList = Other.TaskList;
+			bLight = Other.bLight;
+			bMaterials = Other.bMaterials;
+			bRobotPosition = Other.bRobotPosition;
+			bPets = Other.bPets;
+			NumberOfPets = Other.NumberOfPets;
+			bPeople = Other.bPeople;
+			NumberOfPeople = Other.NumberOfPeople;
+			bObjects = Other.bObjects;
+			NumberOfObjects = Other.NumberOfObjects;
+			RandomMeshes = Other.RandomMeshes;
+			bInfiniteCapture = Other.bInfiniteCapture;
+			NumberOfCaptures = Other.NumberOfCaptures;
+		}
+		return *this;
+	}
+};
+
+USTRUCT(BlueprintType)
+struct FAllGoalListData : public FTableRowBase
+{
+	GENERATED_BODY()
+public:
+	UPROPERTY(EditAnywhere, BlueprintReadWrite)
+	EGoalType GoalType;
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite)
+	FString Example;
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite)
+	TSubclassOf<UUserWidget> Widget;
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite)
+	bool bIsActive;
 };
-- 
2.47.2