Adding Status and Last server response handled but not tested
This commit is contained in:
@ -44,6 +44,11 @@
|
||||
"Name": "DTFluxUtilities",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default"
|
||||
},
|
||||
{
|
||||
"Name": "DTFluxAPIStatus",
|
||||
"Type": "Editor",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
],
|
||||
"Plugins": [
|
||||
|
||||
118
Resources/DTFluxServerStatusWhite.svg
Normal file
118
Resources/DTFluxServerStatusWhite.svg
Normal file
@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
sodipodi:docname="DTFluxServerStatusProject.svg"
|
||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
||||
inkscape:export-filename="..\..\..\0000WorkTechnique\0002dev\Yotta2025\Plugins\DTFluxApi\Resources\DTFluxServerStatusWhite.svg"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:document-units="px"
|
||||
inkscape:export-bgcolor="#ffffff00"
|
||||
inkscape:zoom="12.473806"
|
||||
inkscape:cx="2.4852078"
|
||||
inkscape:cy="16.715027"
|
||||
inkscape:window-width="3440"
|
||||
inkscape:window-height="1351"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="1"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" />
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:2.00998;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 9.9141729,1.5371294 H 2.0032533 V 30.462871 h 7.8293644"
|
||||
id="path1" />
|
||||
<rect
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1.80686;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="rect2"
|
||||
width="19.193144"
|
||||
height="4.2450275"
|
||||
x="6.4034286"
|
||||
y="3.8339815" />
|
||||
<rect
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1.74838;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="rect3"
|
||||
width="19.251621"
|
||||
height="3.9626296"
|
||||
x="6.483469"
|
||||
y="24.212114" />
|
||||
<ellipse
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:2.03983;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path3"
|
||||
cx="16.10928"
|
||||
cy="16.480982"
|
||||
rx="4.8213382"
|
||||
ry="4.8742285" />
|
||||
<path
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:0.744524;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 15.911604,16.712764 2.263593,-1.701009"
|
||||
id="path4" />
|
||||
<path
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:1.2784;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 16.417491,11.616727 V 9.7754388"
|
||||
id="path5" />
|
||||
<rect
|
||||
style="display:none;fill:none;stroke:#f9f9f9;stroke-width:2.034;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect5"
|
||||
width="18.966003"
|
||||
height="10.100974"
|
||||
x="6.5169978"
|
||||
y="11.082275" />
|
||||
<path
|
||||
style="fill:none;stroke:#f9f9f9;stroke-width:2.00998;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 22.304385,30.58532 h 7.91092 V 1.6595782 h -7.829364"
|
||||
id="path6" />
|
||||
<ellipse
|
||||
style="fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:7.96575;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path7"
|
||||
cx="8.8708906"
|
||||
cy="5.9564953"
|
||||
rx="0.48769841"
|
||||
ry="0.4282518" />
|
||||
<ellipse
|
||||
style="display:none;fill:#000000;fill-opacity:1;stroke:#f9f9f9;stroke-width:7.96575;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="ellipse7"
|
||||
cx="8.8708906"
|
||||
cy="13.527604"
|
||||
rx="0.48769841"
|
||||
ry="0.4282518" />
|
||||
<ellipse
|
||||
style="display:none;fill:#000000;fill-opacity:1;stroke:#f9f9f9;stroke-width:7.96575;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="ellipse8"
|
||||
cx="8.8708906"
|
||||
cy="18.456623"
|
||||
rx="0.48769841"
|
||||
ry="0.4282518" />
|
||||
<ellipse
|
||||
style="display:inline;fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:7.96575;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="ellipse9"
|
||||
cx="8.8708906"
|
||||
cy="26.246185"
|
||||
rx="0.48769841"
|
||||
ry="0.4282518" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
34
Source/DTFluxAPIStatus/DTFluxAPIStatus.Build.cs
Normal file
34
Source/DTFluxAPIStatus/DTFluxAPIStatus.Build.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class DTFluxAPIStatus : ModuleRules
|
||||
{
|
||||
public DTFluxAPIStatus(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
}
|
||||
);
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"Projects",
|
||||
"DTFluxNetwork",
|
||||
"DTFluxProjectSettings",
|
||||
"DTFluxCore",
|
||||
"EditorStyle",
|
||||
"ToolWidgets", // Nécessaire pour FSlimHorizontalToolBarBuilder
|
||||
"UnrealEd",
|
||||
"Settings"
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
111
Source/DTFluxAPIStatus/Private/DTFluxAPIStatusModule.cpp
Normal file
111
Source/DTFluxAPIStatus/Private/DTFluxAPIStatusModule.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
#include "DTFluxAPIStatusModule.h"
|
||||
|
||||
#include "LevelEditor.h"
|
||||
#include "widgets/DTFluxStatusWidget.h"
|
||||
#include "widgets/styles/DTFluxStatusStyle.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FDTFluxAPIStatusModule"
|
||||
|
||||
DEFINE_LOG_CATEGORY(logDTFluxStatus);
|
||||
|
||||
FName DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::StatusTabId = "DTFluxStatusTab";
|
||||
FText DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::StatusTabDisplayName = FText::FromString(TEXT("DTFlux Status"));
|
||||
|
||||
|
||||
void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::StartupModule()
|
||||
{
|
||||
InitMenuExtension();
|
||||
RegisterStatusTab();
|
||||
FDTFluxStatusStyle::RegisterStyle();
|
||||
}
|
||||
|
||||
|
||||
#pragma region MenuExtension
|
||||
|
||||
|
||||
void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::InitMenuExtension()
|
||||
{
|
||||
FLevelEditorModule& LevelEditorModule =
|
||||
FModuleManager::LoadModuleChecked<FLevelEditorModule>(TEXT("LevelEditor"));
|
||||
// FDTFluxAPIModule& DTFluxApi =
|
||||
// FModuleManager::LoadModuleChecked<FDTFluxAPIModule>(TEXT("DTFluxAPI"));
|
||||
const TSharedPtr<FExtender> MenuExtender = MakeShareable(new FExtender());
|
||||
|
||||
MenuExtender->AddMenuBarExtension(
|
||||
"Help",
|
||||
EExtensionHook::Before,
|
||||
nullptr,
|
||||
FMenuBarExtensionDelegate::CreateRaw(this, &FDTFluxAPIStatusModule::AddMenu)
|
||||
);
|
||||
LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::AddMenu(FMenuBarBuilder& MenuBarBuilder)
|
||||
{
|
||||
MenuBarBuilder.AddPullDownMenu(
|
||||
FText::FromString("DTFlux"),
|
||||
FText::FromString("DTFlux API Tools"),
|
||||
FNewMenuDelegate::CreateRaw(this, &FDTFluxAPIStatusModule::FillMenu)
|
||||
);
|
||||
}
|
||||
|
||||
void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::FillMenu(FMenuBuilder& MenuBuilder)
|
||||
{
|
||||
MenuBuilder.BeginSection(NAME_None, FText::FromString("DTFlux API"));
|
||||
MenuBuilder.AddMenuEntry(
|
||||
FText::FromString("Status"),
|
||||
FText::FromString("Launch DTFlux Status"),
|
||||
FSlateIcon(FDTFluxStatusStyle::GetStyleSetName(), "LevelEditor.Tab.Icon"),
|
||||
FExecuteAction::CreateRaw(this, &FDTFluxAPIStatusModule::OnButtonClicked)
|
||||
);
|
||||
MenuBuilder.EndSection();
|
||||
|
||||
}
|
||||
|
||||
void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::OnButtonClicked()
|
||||
{
|
||||
FGlobalTabmanager::Get()->TryInvokeTab(StatusTabId);
|
||||
UE_LOG(LogTemp, Log, TEXT("Status Tab Launched"))
|
||||
}
|
||||
|
||||
#pragma endregion EditorTab
|
||||
|
||||
#pragma region
|
||||
void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::RegisterStatusTab()
|
||||
{
|
||||
FTabSpawnerEntry& SpawnerEntry =
|
||||
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(
|
||||
StatusTabId,
|
||||
FOnSpawnTab::CreateRaw(this, &FDTFluxAPIStatusModule::OnSpawnTab)
|
||||
)
|
||||
.SetDisplayName(StatusTabDisplayName)
|
||||
.SetTooltipText(FText::FromString(TEXT("Status of DTFlux API external connections")));
|
||||
}
|
||||
|
||||
TSharedRef<SDockTab> DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::OnSpawnTab(const FSpawnTabArgs& SpawnTabArgs)
|
||||
{
|
||||
|
||||
|
||||
return
|
||||
SNew(
|
||||
SDockTab
|
||||
)
|
||||
.TabRole(ETabRole::NomadTab)
|
||||
// .ShouldAutosize(true)
|
||||
[
|
||||
SNew(SDTFluxStatusWidget)
|
||||
];
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
void DTFLUXAPISTATUS_API FDTFluxAPIStatusModule::ShutdownModule()
|
||||
{
|
||||
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(StatusTabId);
|
||||
FDTFluxStatusStyle::UnregisterStyle();
|
||||
|
||||
}
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FDTFluxAPIStatusModule, DTFluxAPIStatus)
|
||||
367
Source/DTFluxAPIStatus/Private/DTFluxStatusWidget.cpp
Normal file
367
Source/DTFluxAPIStatus/Private/DTFluxStatusWidget.cpp
Normal file
@ -0,0 +1,367 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "widgets/DTFluxStatusWidget.h"
|
||||
|
||||
#include "SlateOptMacros.h"
|
||||
#include "DTFluxAPIStatusModule.h"
|
||||
#include "EditorStyleSet.h"
|
||||
#include "ISettingsCategory.h"
|
||||
#include "ISettingsContainer.h"
|
||||
#include "ISettingsModule.h"
|
||||
#include "ISettingsSection.h"
|
||||
#include "Styling/SlateIconFinder.h"
|
||||
#include "Types/Enum/DTFluxCoreEnum.h"
|
||||
#include "Subsystems/DTFluxNetworkSubsystem.h"
|
||||
#include "Framework/MultiBox/MultiBoxBuilder.h"
|
||||
|
||||
|
||||
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
||||
void SDTFluxStatusWidget::OnOpenSettingsClicked()
|
||||
{
|
||||
UE_LOG(logDTFluxStatus, Warning, TEXT("Settings Clicked !!!!"));
|
||||
ISettingsModule& SettingsModule = FModuleManager::LoadModuleChecked<ISettingsModule>("Settings");
|
||||
SettingsModule.ShowViewer("Project", "DTFluxProjectSettings", "DTFluxNetworkSettings");
|
||||
}
|
||||
|
||||
FReply SDTFluxStatusWidget::OnRaceDatasClicked()
|
||||
{
|
||||
DTFlux->SendRequest(EDTFluxRequestType::RaceData);
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
FReply SDTFluxStatusWidget::OnTeamListClicked()
|
||||
{
|
||||
DTFlux->SendRequest(EDTFluxRequestType::TeamList);
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
void SDTFluxStatusWidget::Construct(const FArguments& InArgs)
|
||||
{
|
||||
|
||||
DTFlux =
|
||||
GEngine->GetEngineSubsystem<UDTFluxNetworkSubsystem>();
|
||||
ConnectionActionButtonText.Set(
|
||||
DTFlux->WsStatus != EDTFluxConnectionStatus::Connected ?
|
||||
FText::FromString("Connect") :
|
||||
FText::FromString("Disconnect")
|
||||
);
|
||||
|
||||
bCanSupportFocus = true;
|
||||
|
||||
|
||||
|
||||
|
||||
FSlimHorizontalToolBarBuilder ToolBarBuilder(
|
||||
nullptr,
|
||||
FMultiBoxCustomization::None,
|
||||
nullptr,
|
||||
false
|
||||
);
|
||||
|
||||
ToolBarBuilder.BeginSection("Settings");
|
||||
{
|
||||
ToolBarBuilder.AddToolBarButton(
|
||||
FUIAction(FExecuteAction::CreateSP(this, &SDTFluxStatusWidget::OnOpenSettingsClicked)),
|
||||
NAME_None,
|
||||
INVTEXT("DTFlux Settings"),
|
||||
INVTEXT("Ouvrir les paramètres DTFlux"),
|
||||
FSlateIcon(FAppStyle::GetAppStyleSetName(), "Icons.Settings")
|
||||
);
|
||||
}
|
||||
ToolBarBuilder.EndSection();
|
||||
|
||||
|
||||
|
||||
FSlateFontInfo TitleTextFont = FCoreStyle::Get().GetFontStyle(FName("EmbossedText"));
|
||||
TitleTextFont.Size = 15;
|
||||
ChildSlot
|
||||
[
|
||||
#pragma region ToolBarSection
|
||||
SNew(SVerticalBox)
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
|
||||
[
|
||||
SNew(SBox)
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+SHorizontalBox::Slot()
|
||||
.FillWidth(2.0)
|
||||
[
|
||||
SNew(SSpacer)
|
||||
]
|
||||
+SHorizontalBox::Slot()
|
||||
.AutoWidth()
|
||||
.FillWidth(1.0)
|
||||
.VAlign(VAlign_Center)
|
||||
.HAlign(HAlign_Right)
|
||||
[
|
||||
ToolBarBuilder.MakeWidget()
|
||||
]
|
||||
]
|
||||
]
|
||||
#pragma endregion
|
||||
#pragma region WebsocketStatusSection
|
||||
// Main VerticalBox
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
[
|
||||
SNew(SBorder)
|
||||
.Padding(6.0f)
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+SHorizontalBox::Slot()
|
||||
.VAlign(VAlign_Center)
|
||||
.HAlign(HAlign_Center)
|
||||
.MaxWidth(175.0)
|
||||
.MinWidth(150.0)
|
||||
[
|
||||
SNew(STextBlock )
|
||||
.Text(FText::FromString(TEXT("Websocket connection :")))
|
||||
.Justification(ETextJustify::Left)
|
||||
]
|
||||
+SHorizontalBox::Slot()
|
||||
.VAlign(VAlign_Center)
|
||||
.MinWidth(50.0)
|
||||
.MaxWidth(100.0)
|
||||
[
|
||||
SAssignNew( WsStatusText, STextBlock)
|
||||
.Text(this, &SDTFluxStatusWidget::GetWebSocketStatusText)
|
||||
.Justification(ETextJustify::Left)
|
||||
.ColorAndOpacity(this, &SDTFluxStatusWidget::GetWebSocketStatusColor)
|
||||
]
|
||||
+SHorizontalBox::Slot()
|
||||
.MaxWidth(100.0)
|
||||
.MinWidth(30.0)
|
||||
[
|
||||
SAssignNew(ConnectionActionButton, SButton)
|
||||
.Text(this, &SDTFluxStatusWidget::GetWebConnectActionButtonText)
|
||||
.ForegroundColor_Raw(this, &SDTFluxStatusWidget::GetWebConnectActionButtonColor)
|
||||
.OnClicked(this,&SDTFluxStatusWidget::OnConnectionActionButtonClicked)
|
||||
.VAlign(VAlign_Center)
|
||||
.HAlign(HAlign_Center)
|
||||
.ContentPadding(1.5f)
|
||||
]
|
||||
]
|
||||
]
|
||||
#pragma endregion
|
||||
#pragma region DataModelControlSection
|
||||
+SVerticalBox::Slot()
|
||||
.VAlign(VAlign_Fill)
|
||||
.HAlign(HAlign_Fill)
|
||||
.AutoHeight()
|
||||
[
|
||||
SNew(SBox)
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+SHorizontalBox::Slot()
|
||||
[
|
||||
SNew(SButton)
|
||||
.Text(FText::FromString("Get RaceDatas"))
|
||||
.OnClicked(this, &SDTFluxStatusWidget::OnRaceDatasClicked)
|
||||
]
|
||||
+SHorizontalBox::Slot()
|
||||
[
|
||||
SNew(SButton)
|
||||
.Text(FText::FromString("Get TeamList"))
|
||||
.OnClicked(this, &SDTFluxStatusWidget::OnTeamListClicked)
|
||||
]
|
||||
]
|
||||
]
|
||||
#pragma endregion
|
||||
#pragma region HTTPStatusSection
|
||||
// +SVerticalBox::Slot()
|
||||
// .AutoHeight()
|
||||
// [
|
||||
// SNew(SHorizontalBox)
|
||||
// +SHorizontalBox::Slot()
|
||||
// [
|
||||
// SNew(STextBlock)
|
||||
// .Text(FText::FromString(TEXT("HTTP connection :")))
|
||||
// .Justification(ETextJustify::Left)
|
||||
// ]
|
||||
// +SHorizontalBox::Slot()
|
||||
// [
|
||||
// SNew(STextBlock)
|
||||
// .Text(FText::FromString(TEXT("invalid")))
|
||||
// .Justification(ETextJustify::Center)
|
||||
// .ColorAndOpacity(FColor::Red)
|
||||
// ]
|
||||
// +SHorizontalBox::Slot()
|
||||
// [
|
||||
// SNew(SButton)
|
||||
// .Text(FText::FromString(TEXT("Connection test")))
|
||||
// ]
|
||||
// ]
|
||||
#pragma endregion
|
||||
#pragma region ContestsDataSection
|
||||
// +SVerticalBox::Slot()
|
||||
// .AutoHeight()
|
||||
// .VAlign(VAlign_Fill)
|
||||
// .HAlign(HAlign_Fill)
|
||||
// [
|
||||
// SNew(SBorder)
|
||||
// .Padding(1.5f)
|
||||
// .VAlign(VAlign_Fill)
|
||||
// .HAlign(HAlign_Fill)
|
||||
// [
|
||||
// SNew(STextBlock)
|
||||
// .Justification(ETextJustify::Left)
|
||||
// .Text(FText::FromString("Contest :"))
|
||||
// .ColorAndOpacity(FColor::White)
|
||||
// ]
|
||||
// ]
|
||||
// +SVerticalBox::Slot()
|
||||
// .AutoHeight()
|
||||
// .VAlign(VAlign_Center)
|
||||
// .HAlign(HAlign_Fill)
|
||||
// [
|
||||
// SNew(SBorder)
|
||||
// .Padding(1.0f)
|
||||
// .VAlign(VAlign_Center)
|
||||
// .HAlign(HAlign_Fill)
|
||||
// [
|
||||
// SNew(SDatastorageView, DTFlux)
|
||||
// ]
|
||||
// ]
|
||||
#pragma endregion
|
||||
#pragma region ParticipantsDataSection
|
||||
// +SVerticalBox::Slot()
|
||||
// .AutoHeight()
|
||||
// [
|
||||
// SNew(SHorizontalBox)
|
||||
// +SHorizontalBox::Slot()
|
||||
// [
|
||||
// SNew(STextBlock)
|
||||
// .Text(FText::FromString(TEXT("Participants")))
|
||||
// .Justification(ETextJustify::Left)
|
||||
// ]
|
||||
// +SHorizontalBox::Slot()
|
||||
// [
|
||||
// SNew(SButton)
|
||||
// .Text(FText::FromString(TEXT("Show")))
|
||||
// ]
|
||||
// ]
|
||||
#pragma endregion
|
||||
#pragma region EventsSection
|
||||
// +SVerticalBox::Slot()
|
||||
// .AutoHeight()
|
||||
// [
|
||||
// SNew(SHorizontalBox)
|
||||
// +SHorizontalBox::Slot()
|
||||
// [
|
||||
// SNew(STextBlock)
|
||||
// .Text(FText::FromString(TEXT("Future Events")))
|
||||
// .Justification(ETextJustify::Left)
|
||||
// ]
|
||||
// +SHorizontalBox::Slot()
|
||||
// [
|
||||
// SNew(SButton)
|
||||
// .Text(FText::FromString(TEXT("Show")))
|
||||
// ]
|
||||
// ]
|
||||
#pragma endregion
|
||||
#pragma region SequencesSection
|
||||
// +SVerticalBox::Slot()
|
||||
// .AutoHeight()
|
||||
// [
|
||||
// SNew(SHorizontalBox)
|
||||
// +SHorizontalBox::Slot()
|
||||
// [
|
||||
// SNew(STextBlock)
|
||||
// .Text(FText::FromString(TEXT("Sequence On Air")))
|
||||
// .Justification(ETextJustify::Left)
|
||||
// ]
|
||||
// +SHorizontalBox::Slot()
|
||||
// [
|
||||
// SNew(SButton)
|
||||
// .Text(FText::FromString(TEXT("Show")))
|
||||
// ]
|
||||
// ]
|
||||
#pragma endregion
|
||||
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
FText SDTFluxStatusWidget::GetWebSocketStatusText() const
|
||||
{
|
||||
|
||||
FString Status =
|
||||
UEnum::GetDisplayValueAsText(DTFlux->WsStatus).ToString();
|
||||
return
|
||||
FText::FromString(Status);
|
||||
// FText::FromString("Unknown");
|
||||
|
||||
}
|
||||
|
||||
FText SDTFluxStatusWidget::GetWebConnectActionButtonText() const
|
||||
{
|
||||
switch (DTFlux->WsStatus)
|
||||
{
|
||||
case EDTFluxConnectionStatus::Connected:
|
||||
return FText::FromString("Disconnect");
|
||||
default:
|
||||
return FText::FromString("Connect");
|
||||
}
|
||||
}
|
||||
|
||||
FReply SDTFluxStatusWidget::OnConnectionActionButtonClicked()
|
||||
{
|
||||
if(DTFlux)
|
||||
{
|
||||
switch (DTFlux->WsStatus)
|
||||
{
|
||||
case EDTFluxConnectionStatus::Connected:
|
||||
DTFlux->Reconnect();
|
||||
break;
|
||||
default:
|
||||
DTFlux->Connect();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FReply::Handled();
|
||||
}
|
||||
FSlateColor SDTFluxStatusWidget::GetWebSocketStatusColor() const
|
||||
{
|
||||
FColor Color;
|
||||
switch (DTFlux->WsStatus)
|
||||
{
|
||||
case EDTFluxConnectionStatus::Unset:
|
||||
Color = FColor::Orange;
|
||||
break;
|
||||
case EDTFluxConnectionStatus::Connected:
|
||||
Color = FColor::Green;
|
||||
break;
|
||||
case EDTFluxConnectionStatus::NotConnected:
|
||||
Color = FColor::Orange;
|
||||
break;
|
||||
case EDTFluxConnectionStatus::Closed:
|
||||
Color = FColor::Magenta;
|
||||
break;
|
||||
default:
|
||||
Color = FColor::Red;
|
||||
break;
|
||||
}
|
||||
return FSlateColor(Color);
|
||||
}
|
||||
|
||||
FSlateColor SDTFluxStatusWidget::GetWebConnectActionButtonColor() const
|
||||
{
|
||||
FColor Color= FColor::Green;
|
||||
switch (DTFlux->WsStatus)
|
||||
{
|
||||
case EDTFluxConnectionStatus::Connected:
|
||||
Color = FColor::Red;
|
||||
break;
|
||||
default:
|
||||
Color = FColor::Green;
|
||||
break;
|
||||
}
|
||||
return FSlateColor(Color);
|
||||
}
|
||||
|
||||
|
||||
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
46
Source/DTFluxAPIStatus/Private/styles/DTFluxStatusStyle.cpp
Normal file
46
Source/DTFluxAPIStatus/Private/styles/DTFluxStatusStyle.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "widgets/styles/DTFluxStatusStyle.h"
|
||||
|
||||
#include "Interfaces/IPluginManager.h"
|
||||
#include "Styling/SlateStyleRegistry.h"
|
||||
#include "Styling/SlateStyleMacros.h"
|
||||
|
||||
#define RootToContentDir Style->RootToContentDir
|
||||
|
||||
TSharedPtr<ISlateStyle> FDTFluxStatusStyle::StyleSet = nullptr;
|
||||
|
||||
void FDTFluxStatusStyle::RegisterStyle()
|
||||
{
|
||||
if(StyleSet.IsValid()) return;
|
||||
|
||||
StyleSet = Create();
|
||||
FSlateStyleRegistry::RegisterSlateStyle(*StyleSet);
|
||||
}
|
||||
|
||||
void FDTFluxStatusStyle::UnregisterStyle()
|
||||
{
|
||||
if(StyleSet.IsValid())
|
||||
{
|
||||
FSlateStyleRegistry::UnRegisterSlateStyle(*StyleSet);
|
||||
ensure(StyleSet.IsUnique());
|
||||
StyleSet.Reset();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void FDTFluxStatusStyle::ReloadTextures()
|
||||
{
|
||||
}
|
||||
|
||||
TSharedPtr<ISlateStyle> FDTFluxStatusStyle::Create()
|
||||
{
|
||||
TSharedPtr<FSlateStyleSet> Style = MakeShareable(new FSlateStyleSet("DTFluxAPIStatusStyle"));
|
||||
Style->SetContentRoot(IPluginManager::Get().FindPlugin("DTFluxAPI")->GetBaseDir()/TEXT("Resources"));
|
||||
|
||||
Style->Set("LevelEditor.Tab.Icon", new IMAGE_BRUSH_SVG("DTFluxServerStatusWhite", FVector2d(16)) );
|
||||
return Style;
|
||||
}
|
||||
|
||||
31
Source/DTFluxAPIStatus/Public/DTFluxAPIStatusModule.h
Normal file
31
Source/DTFluxAPIStatus/Public/DTFluxAPIStatusModule.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
DTFLUXAPISTATUS_API DECLARE_LOG_CATEGORY_EXTERN(logDTFluxStatus, All, All);
|
||||
|
||||
class DTFLUXAPISTATUS_API FDTFluxAPIStatusModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
|
||||
#pragma region MenuExtention
|
||||
void InitMenuExtension();
|
||||
void AddMenu(FMenuBarBuilder& MenuBarBuilder);
|
||||
void FillMenu(FMenuBuilder& MenuBuilder);
|
||||
void OnButtonClicked();
|
||||
// void OnWsEvent(TEnumAsByte<EDTFluxWsStatus> WsResponseEvent) const;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region EditorTab
|
||||
void RegisterStatusTab();
|
||||
TSharedRef<SDockTab> OnSpawnTab(const FSpawnTabArgs& SpawnTabArgs);
|
||||
private:
|
||||
static FName StatusTabId;
|
||||
static FText StatusTabDisplayName;
|
||||
|
||||
TSharedPtr<class SDTFluxStatusWidget> StatusWidget;
|
||||
#pragma endregion
|
||||
};
|
||||
44
Source/DTFluxAPIStatus/Public/widgets/DTFluxStatusWidget.h
Normal file
44
Source/DTFluxAPIStatus/Public/widgets/DTFluxStatusWidget.h
Normal file
@ -0,0 +1,44 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Widgets/SCompoundWidget.h"
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class UDTFluxNetworkSubsystem;
|
||||
class SSuperListView;
|
||||
|
||||
class DTFLUXAPISTATUS_API SDTFluxStatusWidget : public SCompoundWidget
|
||||
{
|
||||
public:
|
||||
SLATE_BEGIN_ARGS(SDTFluxStatusWidget)
|
||||
{
|
||||
}
|
||||
|
||||
SLATE_END_ARGS()
|
||||
|
||||
void OnOpenSettingsClicked();
|
||||
FReply OnRaceDatasClicked();
|
||||
FReply OnTeamListClicked();
|
||||
/** Constructs this widget with InArgs */
|
||||
void Construct(const FArguments& InArgs);
|
||||
TAttribute<FText> ConnectionActionButtonText;
|
||||
FReply OnConnectionActionButtonClicked();
|
||||
|
||||
private:
|
||||
UDTFluxNetworkSubsystem* DTFlux = nullptr;
|
||||
// // TODO make a struct
|
||||
FText GetWebSocketStatusText() const;
|
||||
FText GetWebConnectActionButtonText() const;
|
||||
FSlateColor GetWebSocketStatusColor() const;
|
||||
FSlateColor GetWebConnectActionButtonColor() const;
|
||||
TSharedPtr<STextBlock> WsStatusText;
|
||||
TSharedPtr<SButton> ConnectionActionButton;
|
||||
|
||||
|
||||
|
||||
};
|
||||
@ -0,0 +1,35 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Styling/ISlateStyle.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class DTFLUXAPISTATUS_API FDTFluxStatusStyle
|
||||
{
|
||||
|
||||
public:
|
||||
static void RegisterStyle();
|
||||
static void UnregisterStyle();
|
||||
|
||||
static void ReloadTextures();
|
||||
|
||||
static const ISlateStyle& Get()
|
||||
{
|
||||
return *StyleSet;
|
||||
}
|
||||
|
||||
static const FName& GetStyleSetName()
|
||||
{
|
||||
return StyleSet->GetStyleSetName();
|
||||
}
|
||||
|
||||
private:
|
||||
static TSharedPtr<ISlateStyle> Create();
|
||||
static TSharedPtr<ISlateStyle> StyleSet;
|
||||
};
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ public class DTFluxCore : ModuleRules
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core","JsonUtilities"
|
||||
"Core",
|
||||
}
|
||||
);
|
||||
|
||||
@ -21,6 +21,7 @@ public class DTFluxCore : ModuleRules
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"JsonUtilities",
|
||||
"OutputLog",
|
||||
"Json",
|
||||
|
||||
}
|
||||
|
||||
@ -36,18 +36,20 @@ void UDTFluxModelAsset::AddPerson(const FDTFluxPerson& InPerson)
|
||||
|
||||
void UDTFluxModelAsset::AddParticipant(const FDTFluxParticipant& InParticipant, const int ContestId)
|
||||
{
|
||||
UE_LOG(logDTFluxCore, Error, TEXT("%i Person in Participant %i"), InParticipant.GetTeammateNum(), InParticipant.Bib);
|
||||
FDTFluxContest TargetContest;
|
||||
if(GetContestById(ContestId, TargetContest))
|
||||
{
|
||||
if(!PersonExists(InParticipant.Person1))
|
||||
TArray<FDTFluxPerson> Teammate = InParticipant.Teammate;
|
||||
for(auto& Person : InParticipant.Teammate)
|
||||
{
|
||||
AddPerson(InParticipant.Person1);
|
||||
}
|
||||
if(InParticipant.Person2 != 0)
|
||||
UE_LOG(logDTFluxCore, Error, TEXT("AddParticipant() DTFlux Person %s %s %s"),
|
||||
*Person.FirstName, *Person.LastName, *Person.Gender);
|
||||
if(!PersonExists(Person))
|
||||
{
|
||||
if(!PersonExists(InParticipant.Person2))
|
||||
{
|
||||
AddPerson(InParticipant.Person2);
|
||||
UE_LOG(logDTFluxCore, Error, TEXT("AddParticipant() DTFlux Person %s %s %s doesnot exists, adding..."),
|
||||
*Person.FirstName, *Person.LastName, *Person.Gender);
|
||||
AddPerson(Person);
|
||||
}
|
||||
}
|
||||
Participants.Add(InParticipant.Bib, InParticipant);
|
||||
@ -79,30 +81,24 @@ void UDTFluxModelAsset::AddContestRanking(const FDTFluxContestRankings& NewConte
|
||||
ContestRankings.Add(NewContestRankings.ContestId, NewContestRankings);
|
||||
}
|
||||
|
||||
bool UDTFluxModelAsset::UpdateStageRanking(const FDTFluxStageRankings& InStageRankings)
|
||||
void UDTFluxModelAsset::UpdateOrCreateStageRanking(const FDTFluxStageRankings& InStageRankings)
|
||||
{
|
||||
const int ContestId = InStageRankings.ContestId;
|
||||
const int StageId = InStageRankings.StageId;
|
||||
int Index = 0;
|
||||
int StageRankingArraySize = StageRankings.Num()-1;
|
||||
for(auto Ranking : StageRankings)
|
||||
{
|
||||
if(Ranking.ContestId == ContestId && Ranking.StageId == StageId)
|
||||
{
|
||||
Index++;
|
||||
break;
|
||||
}
|
||||
Index++;
|
||||
}
|
||||
if(Index != StageRankingArraySize )
|
||||
{
|
||||
StageRankings[Index] = InStageRankings;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
FDTFluxStageKey StageKey = InStageRankings.GetCompositeKey();
|
||||
StageRankings.FindOrAdd(StageKey) = InStageRankings;
|
||||
}
|
||||
|
||||
bool UDTFluxModelAsset::UpdateSplitRanking(const FDTFluxStageRankings& InStageRankings)
|
||||
void UDTFluxModelAsset::AddStageRanking(const FDTFluxStageRankings& InStageRankings)
|
||||
{
|
||||
return true;
|
||||
StageRankings.Add(InStageRankings.GetCompositeKey(), InStageRankings);
|
||||
}
|
||||
|
||||
void UDTFluxModelAsset::AddSplitRanking(const FDTFluxSplitRankings& InSplitRanking)
|
||||
{
|
||||
SplitRankings.Add(InSplitRanking.GetCompositeKey(), InSplitRanking);
|
||||
}
|
||||
|
||||
void UDTFluxModelAsset::UpdateOrCreateSplitRanking(const FDTFluxSplitRankings& InSplitRankings)
|
||||
{
|
||||
FDTFluxSplitKey SplitKey = InSplitRankings.GetCompositeKey();
|
||||
SplitRankings.FindOrAdd(SplitKey) = InSplitRankings;
|
||||
}
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Types/Objects/DTFluxPursuitManager.h"
|
||||
|
||||
void UDTFluxPursuitManager::InitForStage(const FDTFluxStageRankings& StageRankings)
|
||||
{
|
||||
}
|
||||
|
||||
TArray<FDTFluxPursuit> UDTFluxPursuitManager::GetNextPursuits(int MaxPursuit)
|
||||
{
|
||||
//TODO : Implement me !!!
|
||||
return PursuitParticipants;
|
||||
}
|
||||
|
||||
TArray<FDTFluxPursuit> UDTFluxPursuitManager::GetPursuits(int FromIndex, int MaxPursuit)
|
||||
{
|
||||
//TODO : Implement me !!!
|
||||
return PursuitParticipants;
|
||||
}
|
||||
|
||||
FDateTime UDTFluxPursuitManager::GetMassStart()
|
||||
{
|
||||
//TODO : Implement me !!!
|
||||
return MassStart;
|
||||
}
|
||||
|
||||
FText UDTFluxPursuitManager::GetFormattedName(FDTFluxPursuit& InPursuit, const int MaxChar,
|
||||
const FString OverflowChar)
|
||||
{
|
||||
return InPursuit.GetFormattedName(MaxChar, OverflowChar);
|
||||
}
|
||||
|
||||
FText UDTFluxPursuitManager::DisplayPursuit(FDTFluxPursuit& InPursuit, const int MaxWidth,
|
||||
const FString NameOverflowChar)
|
||||
{
|
||||
return InPursuit.DisplayPursuit(MaxWidth, NameOverflowChar);
|
||||
}
|
||||
|
||||
bool UDTFluxPursuitManager::IsUnique(const FDTFluxPursuit& InPursuit)
|
||||
{
|
||||
return InPursuit.IsUnique();
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Types/Objects/UDTFluxParticipantFactory.h"
|
||||
|
||||
bool UDTFluxParticipantFactory::CreateParticipantFomJson(const FString& JsonString, FDTFluxParticipant& OutParticipant)
|
||||
{
|
||||
TSharedPtr<FJsonObject> JsonObject;
|
||||
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(JsonString);
|
||||
if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
|
||||
{
|
||||
return UDTFluxParticipantFactory::CreateFromJsonCpp(JsonObject, OutParticipant);
|
||||
}
|
||||
else
|
||||
{
|
||||
OutParticipant = FDTFluxParticipant();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool UDTFluxParticipantFactory::CreateFromJsonCpp(const TSharedPtr<FJsonObject> JsonObject, FDTFluxParticipant& OutParticipant)
|
||||
{
|
||||
OutParticipant = FDTFluxParticipant::CreateFromJson(JsonObject);
|
||||
return OutParticipant == 0;
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Types/Struct/DTFluxCompositeKey.h"
|
||||
@ -0,0 +1,30 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Types/Struct/DTFluxPursuitStructs.h"
|
||||
|
||||
|
||||
FDTFluxPursuit::FDTFluxPursuit()
|
||||
{
|
||||
}
|
||||
|
||||
FDTFluxPursuit::~FDTFluxPursuit()
|
||||
{
|
||||
}
|
||||
|
||||
FText FDTFluxPursuit::GetFormattedName(const int MaxChar, const FString OverflowChar)
|
||||
{
|
||||
//TODO: Implement Me !!!
|
||||
return Participants[0].GetConcatFormattedName(MaxChar, OverflowChar);
|
||||
}
|
||||
|
||||
FText FDTFluxPursuit::DisplayPursuit(const int MaxWidth, const FString NameOverflowChar)
|
||||
{
|
||||
//TODO: Implement Me !!!
|
||||
return Participants[0].GetConcatFormattedName(MaxWidth, NameOverflowChar);
|
||||
}
|
||||
|
||||
bool FDTFluxPursuit::IsUnique() const
|
||||
{
|
||||
return Participants.Num() == 1;
|
||||
}
|
||||
@ -10,13 +10,13 @@ void FDTFluxContestRanking::Dump() const
|
||||
Rank, Bib, *Gap, *Time );
|
||||
};
|
||||
|
||||
void FDTFluxStageRanking::Dump() const
|
||||
{
|
||||
UE_LOG(logDTFluxCore, Log, TEXT("RANKING : %02d. Participant bib %d %s %s %s %s %s"),
|
||||
Rank, Bib, *Gap, *TimeSwim,
|
||||
*TimeTransition, *TimeRun, *StartTime.ToString());
|
||||
}
|
||||
|
||||
// void FDTFluxStageRanking::Dump() const
|
||||
// {
|
||||
// UE_LOG(logDTFluxCore, Log, TEXT("RANKING : %02d. Participant bib %d %s %s %s %s %s"),
|
||||
// Rank, Bib, *Gap, *TimeSwim,
|
||||
// *TimeTransition, *TimeRun, *StartTime.ToString());
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Types/Struct/DTFluxSplitSensor.h"
|
||||
@ -4,104 +4,150 @@
|
||||
#include "Types/Struct/DTFluxTeamListStruct.h"
|
||||
|
||||
|
||||
bool FDTFluxParticipant::IsTeam() const
|
||||
{
|
||||
return Person2.FirstName.IsEmpty() && Person2.LastName.IsEmpty();
|
||||
}
|
||||
|
||||
|
||||
void FDTFluxParticipant::Dump() const
|
||||
void FDTFluxParticipant::AddTeammate(const FDTFluxPerson& Person)
|
||||
{
|
||||
FString EliteStr = "NO";
|
||||
if(Elite)
|
||||
{
|
||||
EliteStr = "YES";
|
||||
Teammate.Add(Person);
|
||||
}
|
||||
UE_LOG(logDTFluxCore, Log, TEXT("PARTICIPANT with bib: %03d"), Bib);
|
||||
UE_LOG(logDTFluxCore, Log, TEXT("Fullname : %s %s"), *Person1.FirstName, *Person1.LastName);
|
||||
|
||||
void FDTFluxParticipant::AddTeammate(const FString LastName, const FString FirstName, const FString Gender)
|
||||
{
|
||||
}
|
||||
|
||||
FText FDTFluxParticipant::GetFormattedName(const int MaxChar, const FString OverflowChars)
|
||||
{
|
||||
// Vérifie les cas limites
|
||||
if (MaxChar <= 0)
|
||||
{
|
||||
return FText::GetEmpty();
|
||||
}
|
||||
FString FirstName;
|
||||
FString LastName;
|
||||
if(IsTeam())
|
||||
{
|
||||
UE_LOG(logDTFluxCore, Log, TEXT("Teamate : %s %s"), *Person2.FirstName, *Person2.LastName);
|
||||
UE_LOG(logDTFluxCore, Log, TEXT("Team name : %s"), *Team);
|
||||
LastName = Team;
|
||||
}
|
||||
UE_LOG(logDTFluxCore, Log, TEXT("Club : %s, Category : %s, IsElite : %s, Status : %s"),
|
||||
*Club, *Category, *EliteStr, *UEnum::GetValueAsString(Status));
|
||||
// Récupère la première lettre du prénom en majuscule
|
||||
FString Initial;
|
||||
if (!FirstName.IsEmpty())
|
||||
{
|
||||
Initial = FirstName.Left(1).ToUpper() + " ";
|
||||
}
|
||||
|
||||
FString FDTFluxParticipant::GetParticipantFormatedName(bool Truncate, int MaxSize) const
|
||||
{
|
||||
FString ParticipantName;
|
||||
if(Truncate)
|
||||
{
|
||||
if(IsTeam())
|
||||
{
|
||||
//Concatenate the team name;
|
||||
if(Team.Len() > MaxSize - 3)
|
||||
{
|
||||
return Team.Left(MaxSize - 3).Append(TEXT("..."));
|
||||
}
|
||||
return Team;
|
||||
}
|
||||
if(Person1.FirstName.Contains("-") )
|
||||
{
|
||||
FString Formated = "";
|
||||
//Compound Firstname
|
||||
TArray<FString> Out;
|
||||
Person1.FirstName.ParseIntoArray(Out,TEXT("-"),true);
|
||||
for(const auto& Str : Out)
|
||||
{
|
||||
Formated.Append(Str.Left(1).ToUpper()).Append(".");
|
||||
}
|
||||
// TODO : Camel Case handling for LastName
|
||||
Formated.Append(" ").Append(*Person1.LastName);
|
||||
UE_LOG(logDTFluxCore, Log, TEXT("Firstname is with space compound. Formated Name %s length %02d MAX Size : %02d"),
|
||||
*Formated, Formated.Len(), MaxSize);
|
||||
if(Formated.Len() >= MaxSize)
|
||||
{
|
||||
UE_LOG(logDTFluxCore, Log, TEXT("Reducing %s Formated"), *Formated);
|
||||
// Nom complet en majuscules
|
||||
FString FormattedLastName = LastName.ToUpper();
|
||||
|
||||
return Formated.Left(MaxSize - 3).Append("...");
|
||||
}
|
||||
return Formated;
|
||||
}
|
||||
if(Person1.FirstName.Contains(" "))
|
||||
// Construction du nom final
|
||||
FString FullName = Initial + FormattedLastName;
|
||||
|
||||
// Tronque si nécessaire
|
||||
if (FullName.Len() > MaxChar)
|
||||
{
|
||||
FString Formated = "";
|
||||
//Compound Firstname
|
||||
TArray<FString> Out;
|
||||
Person1.FirstName.ParseIntoArray(Out,TEXT(" "),true);
|
||||
for(const auto& Str : Out)
|
||||
// On essaie de garder autant de caractères que possible
|
||||
const int32 AvailableLength = MaxChar - Initial.Len();
|
||||
if (AvailableLength <= 0)
|
||||
{
|
||||
Formated.Append(Str.Left(1).ToUpper()).Append(".");
|
||||
// Pas assez de place pour le nom → juste l'initiale ?
|
||||
return FText::FromString(Initial);
|
||||
}
|
||||
// TODO : Camel Case handling for LastName
|
||||
Formated.Append(" ").Append(*Person1.LastName);
|
||||
UE_LOG(logDTFluxCore, Log, TEXT("Firstname is with space compound. Formated Name %s length %02d MAX Size : %02d"),
|
||||
*Formated, Formated.Len(), MaxSize);
|
||||
if(Formated.Len() >= MaxSize)
|
||||
|
||||
// Coupe le nom pour qu’il rentre dans la limite
|
||||
const int32 TruncateLength = FMath::Min(AvailableLength, FormattedLastName.Len());
|
||||
FullName = Initial + FormattedLastName.Left(TruncateLength);
|
||||
|
||||
// Si on a coupé trop court, on ajoute le suffixe
|
||||
if (FormattedLastName.Len() > TruncateLength)
|
||||
{
|
||||
UE_LOG(logDTFluxCore, Log, TEXT("Reducing %s Formated"), *Formated);
|
||||
return Formated.Left(MaxSize - 3).Append("...");
|
||||
}
|
||||
return Formated;
|
||||
}
|
||||
FString Formated = Person1.FirstName.Left(1).Append(". ");
|
||||
Formated.Append(Person1.LastName);
|
||||
UE_LOG(logDTFluxCore, Log, TEXT("Firstname is not compound. Formated Name %s length %02d MAX Size : %02d"),
|
||||
*Formated, Formated.Len(), MaxSize);
|
||||
if(Formated.Len() >= MaxSize)
|
||||
// On vérifie qu'il reste de la place pour le suffixe
|
||||
const int32 CurrentLength = FullName.Len();
|
||||
const int32 OverflowLength = OverflowChars.Len();
|
||||
|
||||
if (CurrentLength + OverflowLength <= MaxChar)
|
||||
{
|
||||
UE_LOG(logDTFluxCore, Log, TEXT("Reducing %s Formated"), *Formated);
|
||||
return Formated.Left(MaxSize - 3).Append("...");
|
||||
}
|
||||
return Formated;
|
||||
FullName += OverflowChars;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!IsTeam())
|
||||
// Il faut tronquer davantage pour faire de la place au suffixe
|
||||
const int32 RemainingSpace = MaxChar - CurrentLength;
|
||||
if (RemainingSpace > 0)
|
||||
{
|
||||
return FString::Printf(TEXT("%s %s"), *Person1.FirstName, *Person2.LastName);
|
||||
FullName = FullName.Left(MaxChar - OverflowLength) + OverflowChars;
|
||||
}
|
||||
return Team;
|
||||
else
|
||||
{
|
||||
FullName = FullName.Left(MaxChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FText::FromString(FullName);
|
||||
}
|
||||
|
||||
FText FDTFluxParticipant::GetConcatFormattedName(const int MaxChar, const FString OverflowChar)
|
||||
{
|
||||
FString BibText = FString::FromInt(Bib) + " ";
|
||||
FText FormattedName = GetFormattedName(MaxChar - BibText.Len(), OverflowChar );
|
||||
return FText::FromString(BibText + FormattedName.ToString());
|
||||
}
|
||||
|
||||
// Constructeur privé depuis JSON
|
||||
FDTFluxParticipant::FDTFluxParticipant(const TSharedPtr<FJsonObject>& JsonObject)
|
||||
: Bib(JsonObject->GetIntegerField(TEXT("bib")))
|
||||
, ContestId(JsonObject->GetIntegerField(TEXT("contestId")))
|
||||
, Category(JsonObject->GetStringField(TEXT("category")))
|
||||
, Club(JsonObject->GetStringField(TEXT("club")))
|
||||
, Elite(JsonObject->GetBoolField(TEXT("elite")))
|
||||
, Status(static_cast<EDTFluxParticipantStatusType>(JsonObject->GetIntegerField(TEXT("status"))))
|
||||
, Team(JsonObject->GetStringField(TEXT("team")))
|
||||
, bIsMassStartParticipant(false)
|
||||
, LastSplitId(-1)
|
||||
{
|
||||
UE_LOG(logDTFluxCore, Error, TEXT("Ctor with JSON Object"))
|
||||
for(uint8 Index = 1; ; Index++)
|
||||
{
|
||||
FString FirstNameKey = Index == 1 ? "firstName" : FString::Printf(TEXT("firstName%i"), Index);
|
||||
FString LastNameKey = Index == 1 ? "lastName" : FString::Printf(TEXT("lastName%i"), Index);
|
||||
FString GenderKey = Index == 1 ? "gender" : FString::Printf(TEXT("gender%i"), Index);
|
||||
// max 10 Persons
|
||||
if(Index >= 10)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (!JsonObject->HasField(FirstNameKey) && !JsonObject->HasField(LastNameKey)
|
||||
&& !JsonObject->HasField(GenderKey))
|
||||
{
|
||||
UE_LOG(logDTFluxCore, Error, TEXT("No Corresponding Field!!!"))
|
||||
break;
|
||||
}
|
||||
const FString FirstName = JsonObject->GetStringField(FirstNameKey);
|
||||
const FString LastName = JsonObject->GetStringField(LastNameKey);
|
||||
const FString Gender = JsonObject->GetStringField(GenderKey);
|
||||
if (FirstName.IsEmpty() && LastName.IsEmpty())
|
||||
continue;
|
||||
FDTFluxPerson Person;
|
||||
Person.FirstName = FirstName;
|
||||
Person.LastName = LastName;
|
||||
Person.Gender = Gender;
|
||||
Teammate.Add(Person);
|
||||
}
|
||||
UE_LOG(logDTFluxCore, Error, TEXT("Ctor with JSON Object Teammate is now %i long"), Teammate.Num());
|
||||
|
||||
}
|
||||
|
||||
FDTFluxParticipant FDTFluxParticipant::CreateFromJson(const TSharedPtr<FJsonObject>& JsonObject)
|
||||
{
|
||||
return FDTFluxParticipant(JsonObject);
|
||||
}
|
||||
|
||||
int FDTFluxParticipant::GetTeammateNum() const
|
||||
{
|
||||
return Teammate.Num();
|
||||
}
|
||||
|
||||
bool FDTFluxParticipant::IsTeam()
|
||||
{
|
||||
return Teammate.Num() < 1;
|
||||
}
|
||||
@ -5,6 +5,7 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "Dom/JsonObject.h"
|
||||
#include "Types/Struct/DTFluxCompositeKey.h"
|
||||
#include "Types/Struct/DTFluxRaceDataStructs.h"
|
||||
#include "DTFluxModelAsset.generated.h"
|
||||
|
||||
@ -37,10 +38,10 @@ public:
|
||||
TMap<int /*ContestId*/, FDTFluxContestRankings> ContestRankings;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
|
||||
TArray<FDTFluxStageRankings> StageRankings;
|
||||
TMap<FDTFluxStageKey, FDTFluxStageRankings> StageRankings;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
|
||||
TArray<FDTFluxStageRankings> SplitRankings;
|
||||
TMap<FDTFluxSplitKey, FDTFluxSplitRankings> SplitRankings;
|
||||
|
||||
UFUNCTION(BlueprintCallable, CallInEditor, Category="DTFlux|ModelAsset")
|
||||
void AddContest(const FDTFluxContest &Contest);
|
||||
@ -60,11 +61,17 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Contest|Utils")
|
||||
FString GetContestNameForId(const int InContestID);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Contest|Utils")
|
||||
bool UpdateStageRanking(const FDTFluxStageRankings& InStageRankings);
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Stage")
|
||||
void UpdateOrCreateStageRanking(const FDTFluxStageRankings& InStageRankings);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Contest|Utils")
|
||||
bool UpdateSplitRanking(const FDTFluxStageRankings& InStageRankings);
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Stage")
|
||||
void AddStageRanking(const FDTFluxStageRankings& InStageRankings);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Split")
|
||||
void UpdateOrCreateSplitRanking(const FDTFluxSplitRankings& InSplitRankings);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Split")
|
||||
void AddSplitRanking(const FDTFluxSplitRankings& InSplitRanking);
|
||||
|
||||
UFUNCTION()
|
||||
void AddContestRanking(const FDTFluxContestRankings& NewContestRankings);
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "DTFluxCoreEnum.generated.h"
|
||||
|
||||
|
||||
UENUM(BlueprintType)
|
||||
@ -22,5 +23,7 @@ enum class EDTFluxConnectionStatus : uint8
|
||||
{
|
||||
Unset = 0 UMETA(DisplayName="Unset"),
|
||||
Connected = 1 << 0 UMETA(DisplayName="Connected"),
|
||||
Error = 2 << 1 UMETA(DisplayName="Error")
|
||||
Error = 1 << 1 UMETA(DisplayName="Error"),
|
||||
Closed = 1 << 2 UMETA(DisplayName="Closed"),
|
||||
NotConnected= 1 << 3 UMETA(DisplayName="NotConnected")
|
||||
};
|
||||
|
||||
@ -17,6 +17,7 @@ enum class EDTFluxParticipantStatusType : uint8
|
||||
DNF = 3 UMETA(DisplayName="Abandon"),
|
||||
DNS = 4 UMETA(DisplayName="NonPartant"),
|
||||
NotLinedUp = 5 UMETA(DisplayName="NonPresentAuDépart"),
|
||||
Unknown = 1 << 4 UMETA(DisplayName="Unknown")
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,63 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Types/Struct/DTFluxPursuitStructs.h"
|
||||
#include "Types/Struct/DTFluxRankingStructs.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "DTFluxPursuitManager.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(BlueprintType)
|
||||
class DTFLUXCORE_API UDTFluxPursuitManager : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"), Transient)
|
||||
TArray<FDTFluxPursuit> PursuitParticipants;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
|
||||
FDateTime MassStart;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
|
||||
int ContestId;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
|
||||
int StageId;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
|
||||
void InitForStage(const FDTFluxStageRankings& StageRankings);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
|
||||
TArray<FDTFluxPursuit> GetNextPursuits(int MaxPursuit);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
|
||||
TArray<FDTFluxPursuit> GetPursuits(int FromIndex = 0, int MaxPursuit=10);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
|
||||
FDateTime GetMassStart();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
|
||||
static FText GetFormattedName(FDTFluxPursuit& InPursuit, const int MaxChar = 10, const FString OverflowChar = FString(TEXT("...")));
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
|
||||
static FText DisplayPursuit(FDTFluxPursuit& InPursuit, const int MaxWidth = 14, const FString NameOverflowChar = FString(TEXT("...")));
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
|
||||
static bool IsUnique(const FDTFluxPursuit& InPursuit);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
private:
|
||||
|
||||
UPROPERTY(VisibleAnywhere, Category="DTFlux|Pursuit", meta=(Keywords="Poursuit pursuit poursuit"))
|
||||
int CurrentIndex;
|
||||
};
|
||||
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "Types/Struct/DTFluxTeamListStruct.h"
|
||||
#include "UDTFluxParticipantFactory.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class DTFLUXCORE_API UDTFluxParticipantFactory : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Factory")
|
||||
static bool CreateParticipantFomJson(const FString& JsonString, FDTFluxParticipant& OutParticipant );
|
||||
|
||||
static bool CreateFromJsonCpp(const TSharedPtr<FJsonObject> JsonObject, FDTFluxParticipant& OutParticipant);
|
||||
};
|
||||
100
Source/DTFluxCore/Public/Types/Struct/DTFluxCompositeKey.h
Normal file
100
Source/DTFluxCore/Public/Types/Struct/DTFluxCompositeKey.h
Normal file
@ -0,0 +1,100 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "DTFluxCompositeKey.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct DTFLUXCORE_API FDTFluxStageKey
|
||||
{
|
||||
GENERATED_BODY()
|
||||
FDTFluxStageKey() = default;
|
||||
FDTFluxStageKey(const int InContestId, const int InStageId )
|
||||
:ContestId(InContestId)
|
||||
, StageId(InStageId){};
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="DTFlux|Model")
|
||||
int ContestId = -1;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="DTFlux|Model")
|
||||
int StageId = -1;
|
||||
|
||||
friend uint32 GetTypeHash(const FDTFluxStageKey& Key)
|
||||
{
|
||||
return HashCombine(
|
||||
GetTypeHash(Key.ContestId),
|
||||
GetTypeHash(Key.StageId)
|
||||
);
|
||||
}
|
||||
|
||||
bool operator==(const FDTFluxStageKey& Other) const
|
||||
{
|
||||
return ContestId == Other.ContestId && StageId == Other.StageId;
|
||||
}
|
||||
FString GetDisplayName() const
|
||||
{
|
||||
return FString::Printf(TEXT("Contest%i -| Stage%i"), ContestId, StageId);
|
||||
}
|
||||
|
||||
FText GetTooltipText() const
|
||||
{
|
||||
return FText::Format(INVTEXT("Contest{0}|Stage{1}"),
|
||||
FText::AsNumber(ContestId),
|
||||
FText::AsNumber(StageId));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct DTFLUXCORE_API FDTFluxSplitKey
|
||||
{
|
||||
GENERATED_BODY()
|
||||
FDTFluxSplitKey() = default;
|
||||
FDTFluxSplitKey(const int InContestId, const int InStageId, const int InSplitId )
|
||||
:ContestId(InContestId)
|
||||
, StageId(InStageId)
|
||||
, SplitId(InSplitId){};
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="DTFlux|Model")
|
||||
int ContestId = -1;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="DTFlux|Model")
|
||||
int StageId = -1;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="DTFlux|Model")
|
||||
int SplitId = -1;
|
||||
|
||||
friend uint32 GetTypeHash(const FDTFluxSplitKey& Key)
|
||||
{
|
||||
return HashCombine(
|
||||
GetTypeHash(Key.ContestId),
|
||||
GetTypeHash(Key.StageId),
|
||||
GetTypeHash(Key.SplitId)
|
||||
);
|
||||
}
|
||||
|
||||
bool operator==(const FDTFluxSplitKey& Other) const
|
||||
{
|
||||
return ContestId == Other.ContestId && StageId == Other.StageId && SplitId == Other.SplitId;
|
||||
}
|
||||
FString GetDisplayName() const
|
||||
{
|
||||
return FString::Printf(TEXT("Contest%i | Stage%i | Split%i"), ContestId, StageId, SplitId);
|
||||
}
|
||||
|
||||
FText GetTooltipText() const
|
||||
{
|
||||
return FText::Format(INVTEXT("Contest{0}|Stage{1}|Split{2}"),
|
||||
FText::AsNumber(ContestId),
|
||||
FText::AsNumber(StageId),
|
||||
FText::AsNumber(SplitId)
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
38
Source/DTFluxCore/Public/Types/Struct/DTFluxPursuitStructs.h
Normal file
38
Source/DTFluxCore/Public/Types/Struct/DTFluxPursuitStructs.h
Normal file
@ -0,0 +1,38 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "DTFluxTeamListStruct.h"
|
||||
#include "DTFluxPursuitStructs.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
USTRUCT(BlueprintType, Blueprintable)
|
||||
struct DTFLUXCORE_API FDTFluxPursuit
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
FDTFluxPursuit();
|
||||
FDTFluxPursuit(const TArray<FDTFluxParticipant>& InParticipants) : Participants(InParticipants){};
|
||||
|
||||
~FDTFluxPursuit();
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category="DTFlux|Pursuit")
|
||||
TArray<FDTFluxParticipant> Participants;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category="DTFlux|Pursuit")
|
||||
FDateTime StartTime;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category="DTFlux|Pursuit")
|
||||
int IndexMultiple = 0;
|
||||
|
||||
FText GetFormattedName(const int MaxChar = 15, const FString OverflowChar = FString(TEXT("...")));
|
||||
FText DisplayPursuit(const int MaxWidth = 20, const FString NameOverflowChar = FString(TEXT("...")));
|
||||
bool IsUnique() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "DTFluxCompositeKey.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "DTFluxRankingStructs.generated.h"
|
||||
|
||||
@ -58,7 +59,7 @@ public:
|
||||
* Representing a stage ranking for a participant
|
||||
*/
|
||||
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||
struct DTFLUXCORE_API FDTFluxStageRanking
|
||||
struct DTFLUXCORE_API FDTFluxDetailedRankingItem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
@ -91,19 +92,76 @@ public:
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FDTFluxStageRankings
|
||||
struct FDTFluxDetailedRankings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(BlueprintReadWrite,Category="DTFlux|Model|Ranking", VisibleAnywhere)
|
||||
TArray<FDTFluxStageRanking> Rankings;
|
||||
UPROPERTY(BlueprintReadWrite,Category="DTFlux|Model|Ranking", VisibleAnywhere)
|
||||
int ContestId;
|
||||
UPROPERTY(BlueprintReadWrite,Category="DTFlux|Model|Ranking", VisibleAnywhere)
|
||||
int StageId;
|
||||
UPROPERTY(BlueprintReadWrite,Category="DTFlux|Model|Ranking", VisibleAnywhere)
|
||||
int SplitId;
|
||||
TArray<FDTFluxDetailedRankingItem> Rankings;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct FDTFluxStageRanking
|
||||
* Representing a stage ranking for a participant
|
||||
* This struct is only a cosmetic Struct
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FDTFluxStageRanking : public FDTFluxDetailedRankingItem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @struct FDTFluxSplitRanking
|
||||
* Representing a split ranking for a participant
|
||||
* This struct is only a cosmetic Struct
|
||||
*/
|
||||
USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||
struct DTFLUXCORE_API FDTFluxSplitRanking : public FDTFluxStageRanking
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @struct FDTFluxStageRankings
|
||||
* StageRanking Container Struct
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FDTFluxStageRankings : public FDTFluxDetailedRankings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
inline FDTFluxStageKey GetKeyFrom(const FDTFluxStageRankings& InRankings)
|
||||
{
|
||||
return FDTFluxStageKey(InRankings.ContestId, InRankings.StageId);
|
||||
}
|
||||
inline FDTFluxStageKey GetCompositeKey() const
|
||||
{
|
||||
return FDTFluxStageKey(ContestId, StageId);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FDTFluxSplitRankings : public FDTFluxDetailedRankings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(BlueprintReadWrite,Category="DTFlux|Model|Ranking", VisibleAnywhere)
|
||||
int SplitId;
|
||||
inline static FDTFluxSplitKey GetKeyFrom(const FDTFluxSplitRankings& InRankings)
|
||||
{
|
||||
return FDTFluxSplitKey(InRankings.ContestId, InRankings.StageId, InRankings.SplitId);
|
||||
}
|
||||
inline FDTFluxSplitKey GetCompositeKey() const
|
||||
{
|
||||
return FDTFluxSplitKey(ContestId, StageId, SplitId);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
37
Source/DTFluxCore/Public/Types/Struct/DTFluxSplitSensor.h
Normal file
37
Source/DTFluxCore/Public/Types/Struct/DTFluxSplitSensor.h
Normal file
@ -0,0 +1,37 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "DTFluxTeamListStruct.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "DTFluxSplitSensor.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FDTFluxSplitSensorInfo
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
FDTFluxSplitSensorInfo() = default;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
|
||||
int Bib = -1;
|
||||
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
|
||||
int ContestId = -1;
|
||||
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
|
||||
int StageId = -1;
|
||||
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
|
||||
int SplitId = -1;
|
||||
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
|
||||
FString Time = "";
|
||||
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
|
||||
FString Gap = "-";
|
||||
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
|
||||
int Rank;
|
||||
|
||||
};
|
||||
|
||||
@ -43,20 +43,7 @@ public:
|
||||
FString Club;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct FDTFluxTeamListDefinition
|
||||
* Struct representing the Participant List definition
|
||||
* Used to exchange data between Objects in the system
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct DTFLUXCORE_API FDTFluxTeamListDefinition
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY()
|
||||
// ReSharper disable once IdentifierTypo
|
||||
TArray<FDTFluxTeamListItemDefinition> Datas;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@ -101,14 +88,36 @@ USTRUCT(BlueprintType, Category="DTFlux|Model")
|
||||
struct DTFLUXCORE_API FDTFluxParticipant
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
friend class UDTFluxModelAsset;
|
||||
friend class UDTFluxParticipantFactory;
|
||||
public:
|
||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
|
||||
// Constructeur public par défaut requis par Unreal
|
||||
FDTFluxParticipant()
|
||||
: Bib(-1)
|
||||
,ContestId(-1)
|
||||
, Elite(false)
|
||||
, Status(static_cast<EDTFluxParticipantStatusType>(0))
|
||||
, bIsMassStartParticipant(false)
|
||||
, LastSplitId(0)
|
||||
{
|
||||
Teammate.Reset();
|
||||
}
|
||||
|
||||
|
||||
bool operator == ( int Rhs) const
|
||||
{
|
||||
return Rhs == 0 && Bib == -1 && Team.IsEmpty() && Club.IsEmpty() && ContestId == -1
|
||||
&& Teammate.IsEmpty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category="DTFlux|model", EditAnywhere)
|
||||
int Bib = -1;
|
||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
|
||||
FDTFluxPerson Person1;
|
||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
|
||||
FDTFluxPerson Person2;
|
||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
|
||||
UPROPERTY(BlueprintReadOnly, Category="DTFlux|model", EditAnywhere)
|
||||
int ContestId = -1;
|
||||
UPROPERTY(BlueprintReadOnly, Category="DTFlux|model", EditAnywhere)
|
||||
FString Category;
|
||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
|
||||
FString Club;
|
||||
@ -121,9 +130,58 @@ public:
|
||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model", EditAnywhere)
|
||||
bool bIsMassStartParticipant = false;
|
||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|model")
|
||||
int LastSplitId = 0;
|
||||
bool IsTeam() const;
|
||||
void Dump() const;
|
||||
FString GetParticipantFormatedName(bool Truncate = false, int MaxSize = 20) const;
|
||||
int LastSplitId = -1;
|
||||
|
||||
// void Dump() const;
|
||||
void AddTeammate(const FDTFluxPerson& Person);
|
||||
void AddTeammate(const FString LastName, const FString FirstName, const FString Gender);
|
||||
FText GetFormattedName(const int MaxChar = 15, const FString OverflowChar = FString("..."));
|
||||
FText GetConcatFormattedName(const int MaxChar = 20, const FString OverflowChar = FString("..."));
|
||||
|
||||
private:
|
||||
|
||||
// --- Constructeur privé ---
|
||||
explicit FDTFluxParticipant(const TSharedPtr<FJsonObject>& JsonObject);
|
||||
|
||||
protected:
|
||||
UPROPERTY(Category="DTFlux|model", VisibleAnywhere)
|
||||
TArray<FDTFluxPerson> Teammate;
|
||||
// Méthode publique pour construire à partir d'un JSON (utilisée par la factory)
|
||||
static FDTFluxParticipant CreateFromJson(const TSharedPtr<FJsonObject>& JsonObject);
|
||||
int GetTeammateNum() const;
|
||||
bool IsTeam();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @struct FDTFluxTeamListDefinition
|
||||
* Struct representing the Participant List definition
|
||||
* Used to exchange data between Objects in the system
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct DTFLUXCORE_API FDTFluxTeamListDefinition
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY()
|
||||
// ReSharper disable once IdentifierTypo
|
||||
TArray<FDTFluxParticipant> Participants;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FDTFluxTeamStatusUpdate
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
FDTFluxTeamStatusUpdate() = default;
|
||||
FDTFluxTeamStatusUpdate(const int InBib, const int InStatus)
|
||||
:Bib(InBib)
|
||||
, Status(static_cast<EDTFluxParticipantStatusType>(InStatus)){};
|
||||
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Participant")
|
||||
int Bib = -1;
|
||||
UPROPERTY(BlueprintReadWrite, Category="DTFlux|Participant")
|
||||
EDTFluxParticipantStatusType Status = EDTFluxParticipantStatusType::Unknown;
|
||||
};
|
||||
@ -20,6 +20,7 @@ public class DTFluxCoreSubsystem : ModuleRules
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"UnrealEd",
|
||||
"DTFluxNetwork",
|
||||
"DTFluxProjectSettings",
|
||||
"DTFluxCore",
|
||||
|
||||
@ -6,8 +6,10 @@
|
||||
|
||||
#include "DTFluxCoreSubsystemModule.h"
|
||||
#include "DTFluxGeneralSettings.h"
|
||||
#include "FileHelpers.h"
|
||||
#include "Assets/DTFluxModelAsset.h"
|
||||
#include "Subsystems/DTFluxNetworkSubsystem.h"
|
||||
#include "UObject/SavePackage.h"
|
||||
|
||||
void UDTFluxCoreSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
||||
{
|
||||
@ -17,22 +19,26 @@ void UDTFluxCoreSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
||||
{
|
||||
const UDTFluxGeneralSettings* GeneralSettings = GetDefault<UDTFluxGeneralSettings>();
|
||||
TSoftObjectPtr<UDTFluxModelAsset> ModelAsset = GeneralSettings->ModelAsset;
|
||||
DataStorage = ModelAsset.LoadSynchronous();
|
||||
// UE_LOG(logDTFluxCore, Log, TEXT("GeneralSettings is nullptr -> %s"), GeneralSettings == nullptr ? TEXT("TRUE") : TEXT("FALSE"));
|
||||
// UE_LOG(logDTFluxCore, Log, TEXT("ModelAsset isNull() -> %s"), ModelAsset.IsNull() ? TEXT("TRUE") : TEXT("FALSE"));
|
||||
// UE_LOG(logDTFluxCore, Log, TEXT("ModelAsset IsValid() -> %s"), ModelAsset.IsValid() ? TEXT("TRUE") : TEXT("FALSE"));
|
||||
// UE_LOG(logDTFluxCore, Log, TEXT("DataStorage is nullptr -> %s"), DataStorage == nullptr ? TEXT("TRUE") : TEXT("FALSE"));
|
||||
// if(ModelAsset.IsValid())
|
||||
// {
|
||||
// }
|
||||
// UE_LOG(logDTFluxCore, Error, TEXT("ModelAsset Not Valid"));
|
||||
DataStorage = DataStorage = Cast<UDTFluxModelAsset>(ModelAsset.LoadSynchronous());
|
||||
if(!DataStorage)
|
||||
{
|
||||
UE_LOG(logDTFluxCore, Error, TEXT("DataStorage Not Valid"));
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// MakeStorageEditable(DataStorage);
|
||||
// }
|
||||
}
|
||||
|
||||
//TODO REMOVE This as it's only for testing purpose
|
||||
NetworkSubsystem = GEngine->GetEngineSubsystem<UFDTFluxNetworkSubsystem>();
|
||||
NetworkSubsystem = GEngine->GetEngineSubsystem<UDTFluxNetworkSubsystem>();
|
||||
if(NetworkSubsystem->WsStatus != EDTFluxConnectionStatus::Connected)
|
||||
{
|
||||
RegisterDelegates();
|
||||
NetworkSubsystem->Connect();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void UDTFluxCoreSubsystem::Deinitialize()
|
||||
@ -40,18 +46,66 @@ void UDTFluxCoreSubsystem::Deinitialize()
|
||||
Super::Deinitialize();
|
||||
}
|
||||
|
||||
void UDTFluxCoreSubsystem::SaveDataStorage()
|
||||
{
|
||||
if(DataStorage)
|
||||
{
|
||||
DataStorage->MarkPackageDirty();
|
||||
UPackage* Package = DataStorage->GetPackage();
|
||||
if(Package->IsDirty())
|
||||
{
|
||||
FString PackageName = Package->GetName();
|
||||
FString FileExtension = FPackageName::GetAssetPackageExtension();
|
||||
FString FilePath = FPaths::ConvertRelativePathToFull(FPaths::ProjectContentDir() / PackageName.Replace(TEXT("/"), TEXT("/")) + FileExtension);
|
||||
FString LongPackageName = DataStorage->GetOutermost()->GetName();
|
||||
FString RealAssetPath;
|
||||
bool bExists = FPackageName::DoesPackageExist(PackageName);
|
||||
if (!bExists)
|
||||
{
|
||||
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("Le package n'existe pas ou est un redirecteur"));
|
||||
}
|
||||
bool bSuccess = FPackageName::SearchForPackageOnDisk(LongPackageName, &RealAssetPath);
|
||||
|
||||
if (bSuccess && !RealAssetPath.IsEmpty())
|
||||
{
|
||||
UE_LOG(logDTFluxCoreSubsystem, Log, TEXT("Vrai path trouvé : %s"), *RealAssetPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Aucun path valide trouvé pour sauvegarder l'asset"));
|
||||
}
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Saving DataAsset to %s"), *FilePath);
|
||||
TSoftObjectPtr<UDTFluxModelAsset> ModelAsset = GetDefault<UDTFluxGeneralSettings>()->ModelAsset;
|
||||
FString RealPath = ModelAsset->GetPathName();
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("SoftObjectPath to %s"), *RealPath);
|
||||
|
||||
FSavePackageArgs Args;
|
||||
Args.TopLevelFlags = RF_Public | RF_Standalone;
|
||||
Args.bSlowTask = false;
|
||||
Args.SaveFlags = SAVE_None;
|
||||
GEditor->SavePackage(Package, DataStorage, *FilePath, Args);
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("DataAsset Saved"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UDTFluxCoreSubsystem::RegisterDelegates()
|
||||
{
|
||||
if(NetworkSubsystem)
|
||||
{
|
||||
NetworkSubsystem->OnReceivedRaceData().AddDynamic(this, &UDTFluxCoreSubsystem::ParseRaceData);
|
||||
NetworkSubsystem->OnReceivedTeamList().AddDynamic(this, &UDTFluxCoreSubsystem::ParseTeamList);
|
||||
NetworkSubsystem->OnReceivedContestRanking().AddDynamic(this, &UDTFluxCoreSubsystem::ParseContestRanking);
|
||||
NetworkSubsystem->OnReceivedStageRanking().BindUFunction(this, "ParseStageOrSplitRanking");
|
||||
NetworkSubsystem->OnReceivedRaceData().BindUFunction(this, "ProcessRaceData");
|
||||
NetworkSubsystem->OnReceivedTeamList().BindUFunction(this, "ProcessTeamList");
|
||||
NetworkSubsystem->OnReceivedContestRanking().BindUFunction(this, "ProcessContestRanking");
|
||||
NetworkSubsystem->OnReceivedStageRanking().BindUFunction(this, "ProcessStageRanking");
|
||||
NetworkSubsystem->OnReceivedSplitRanking().BindUFunction(this, "ProcessSplitRanking");
|
||||
NetworkSubsystem->OnReceivedTeamUpdate().BindUFunction(this, "ProcessTeamList");
|
||||
NetworkSubsystem->OnReceivedTeamStatusUpdate().BindUFunction(this, "ProcessTeamStatusUpdate");
|
||||
NetworkSubsystem->OnReceivedSplitSensor().BindUFunction(this, "ProcessSplitSensor");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void UDTFluxCoreSubsystem::ParseRaceData(const FDTFluxRaceData& RaceDataDefinition)
|
||||
void UDTFluxCoreSubsystem::ProcessRaceData(const FDTFluxRaceData& RaceDataDefinition)
|
||||
{
|
||||
|
||||
if( RaceDataDefinition.Datas.Num() > 0 )
|
||||
@ -69,66 +123,65 @@ void UDTFluxCoreSubsystem::ParseRaceData(const FDTFluxRaceData& RaceDataDefiniti
|
||||
{
|
||||
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("DataStorage is null"));
|
||||
}
|
||||
SaveDataStorage();
|
||||
return;
|
||||
}
|
||||
UE_LOG(logDTFluxCoreSubsystem, Error, TEXT("RaceDataDefinition is empty !!!"));
|
||||
|
||||
|
||||
}
|
||||
|
||||
void UDTFluxCoreSubsystem::ParseTeamList(const FDTFluxTeamListDefinition& TeamListDefinition)
|
||||
void UDTFluxCoreSubsystem::ProcessTeamList(const FDTFluxTeamListDefinition& TeamListDefinition)
|
||||
{
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Received TeamList with %i Items"), TeamListDefinition.Datas.Num());
|
||||
for(auto InParticipantDefinition : TeamListDefinition.Datas)
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Received TeamList with %i Items"), TeamListDefinition.Participants.Num());
|
||||
for(const auto& Participant : TeamListDefinition.Participants)
|
||||
{
|
||||
FDTFluxParticipant NewParticipant;
|
||||
NewParticipant.Person1.Gender = InParticipantDefinition.Gender;
|
||||
NewParticipant.Person1.FirstName = InParticipantDefinition.FirstName;
|
||||
NewParticipant.Person1.LastName = InParticipantDefinition.LastName;
|
||||
if(InParticipantDefinition.Team != "")
|
||||
{
|
||||
NewParticipant.Person2.Gender = InParticipantDefinition.Gender2;
|
||||
NewParticipant.Person2.FirstName = InParticipantDefinition.FirstName2;
|
||||
NewParticipant.Person2.LastName = InParticipantDefinition.LastName2;
|
||||
}
|
||||
NewParticipant.Bib = InParticipantDefinition.Bib;
|
||||
NewParticipant.Category = InParticipantDefinition.Category;
|
||||
NewParticipant.Club = InParticipantDefinition.Club;
|
||||
NewParticipant.Status = static_cast<EDTFluxParticipantStatusType>(InParticipantDefinition.Status);
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Add Participant %s %s in %i ContestId"),
|
||||
*NewParticipant.Person1.FirstName, *NewParticipant.Person1.LastName, InParticipantDefinition.ContestId );
|
||||
DataStorage->AddParticipant(NewParticipant, InParticipantDefinition.ContestId);
|
||||
}
|
||||
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Add Participant %i in %i ContestId"),
|
||||
Participant.Bib, Participant.ContestId );
|
||||
|
||||
DataStorage->AddParticipant(Participant, Participant.ContestId);
|
||||
}
|
||||
|
||||
void UDTFluxCoreSubsystem::ParseContestRanking(const FDTFluxContestRankings& ContestRankings)
|
||||
|
||||
}
|
||||
|
||||
void UDTFluxCoreSubsystem::ProcessContestRanking(const FDTFluxContestRankings& ContestRankings)
|
||||
{
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Received ContestRankings with %i Items"), ContestRankings.Rankings.Num());
|
||||
FDTFluxContestRankings NewContestRankings = ContestRankings;
|
||||
NewContestRankings.SetName( DataStorage->GetContestNameForId(ContestRankings.ContestId));
|
||||
DataStorage->AddContestRanking(NewContestRankings);
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("ContestRankings added for Contest %s"), *NewContestRankings.ContestName);
|
||||
DataStorage->MarkPackageDirty();
|
||||
|
||||
}
|
||||
|
||||
void UDTFluxCoreSubsystem::ParseStageOrSplitRanking(const FDTFluxStageRankings& StageOrSplitRankings)
|
||||
void UDTFluxCoreSubsystem::ProcessStageRanking(const FDTFluxStageRankings& StageRankings)
|
||||
{
|
||||
if(StageOrSplitRankings.SplitId == -1)
|
||||
{
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Received StageRankings with %i Items"), StageOrSplitRankings.Rankings.Num());
|
||||
if(!DataStorage->UpdateStageRanking(StageOrSplitRankings))
|
||||
{
|
||||
DataStorage->StageRankings.Add(StageOrSplitRankings);
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Received StageRankings with %i Items"), StageRankings.Rankings.Num());
|
||||
DataStorage->UpdateOrCreateStageRanking(StageRankings);
|
||||
DataStorage->MarkPackageDirty();
|
||||
}
|
||||
}
|
||||
else
|
||||
void UDTFluxCoreSubsystem::ProcessSplitRanking(const FDTFluxSplitRankings& SplitRankings)
|
||||
{
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Received SplitRankings with %i Items"), StageOrSplitRankings.Rankings.Num());
|
||||
}
|
||||
UE_LOG(logDTFluxCoreSubsystem, Warning, TEXT("Received SplitRanking with %i Items"), SplitRankings.Rankings.Num());
|
||||
DataStorage->UpdateOrCreateSplitRanking(SplitRankings);
|
||||
DataStorage->MarkPackageDirty();
|
||||
|
||||
}
|
||||
|
||||
void UDTFluxCoreSubsystem::OnDataReceived()
|
||||
void UDTFluxCoreSubsystem::ProcessTeamStatusUpdate()
|
||||
{
|
||||
//TODO IMPLEMENT ME !!!!
|
||||
}
|
||||
|
||||
void UDTFluxCoreSubsystem::ProcessSplitSensor()
|
||||
{
|
||||
//TODO IMPLEMENT ME !!!!
|
||||
}
|
||||
|
||||
|
||||
void UDTFluxCoreSubsystem::SendRequest(const FString& Message)
|
||||
{
|
||||
if(NetworkSubsystem)
|
||||
@ -191,5 +244,3 @@ void UDTFluxCoreSubsystem::RefreshStorage()
|
||||
{
|
||||
// TODO Implement this
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
|
||||
|
||||
class UFDTFluxNetworkSubsystem;
|
||||
class UDTFluxNetworkSubsystem;
|
||||
/** Forward Decl */
|
||||
class UDTFluxModelAsset;
|
||||
|
||||
@ -82,26 +82,29 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Core Subsystem")
|
||||
void RefreshStorage();
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
// ~Subsystem Interface
|
||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||
virtual void Deinitialize() override;
|
||||
// ~Subsystem Interface
|
||||
void SaveDataStorage();
|
||||
private:
|
||||
UFDTFluxNetworkSubsystem* NetworkSubsystem = nullptr;
|
||||
UDTFluxNetworkSubsystem* NetworkSubsystem = nullptr;
|
||||
|
||||
UFUNCTION()
|
||||
void ParseRaceData(const FDTFluxRaceData& RaceDataDefinition);
|
||||
void ProcessRaceData(const FDTFluxRaceData& RaceDataDefinition);
|
||||
UFUNCTION()
|
||||
void ParseTeamList(const FDTFluxTeamListDefinition& TeamListDefinition);
|
||||
void ProcessTeamList(const FDTFluxTeamListDefinition& TeamListDefinition);
|
||||
UFUNCTION()
|
||||
void ParseContestRanking(const FDTFluxContestRankings& ContestRankings);
|
||||
void ProcessContestRanking(const FDTFluxContestRankings& ContestRankings);
|
||||
UFUNCTION()
|
||||
void ParseStageOrSplitRanking(const FDTFluxStageRankings& StageOrSplitRankings);
|
||||
void ProcessStageRanking(const FDTFluxStageRankings& StageRankings);
|
||||
UFUNCTION()
|
||||
void OnDataReceived();
|
||||
void ProcessSplitRanking(const FDTFluxSplitRankings& SplitRankings);
|
||||
UFUNCTION()
|
||||
void ProcessTeamStatusUpdate();
|
||||
UFUNCTION()
|
||||
void ProcessSplitSensor();
|
||||
UFUNCTION()
|
||||
void SendRequest(const FString& Message);
|
||||
UFUNCTION()
|
||||
|
||||
@ -17,6 +17,24 @@ FDTFluxWebSocketClient::FDTFluxWebSocketClient()
|
||||
FDTFluxWebSocketClient::LastId++;
|
||||
}
|
||||
|
||||
bool FDTFluxWebSocketClient::CanSend() const
|
||||
{
|
||||
return Ws.IsValid();
|
||||
}
|
||||
|
||||
TSharedPtr<FDTFluxWebSocketClient> FDTFluxWebSocketClient::GetClient(
|
||||
const TArray<TSharedPtr<FDTFluxWebSocketClient>> InClients, const FName InName)
|
||||
{
|
||||
for(auto Client: InClients)
|
||||
{
|
||||
if(Client->ClientId == InName)
|
||||
{
|
||||
return Client;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FDTFluxWebSocketClient::Connect()
|
||||
{
|
||||
Ws = FWebSocketsModule::Get().CreateWebSocket(WsAddress);
|
||||
@ -79,9 +97,12 @@ void FDTFluxWebSocketClient::AddError(const FDTFluxWsClientError Error)
|
||||
}
|
||||
|
||||
void FDTFluxWebSocketClient::Send(const FString& Message) const
|
||||
{
|
||||
if(Ws.IsValid())
|
||||
{
|
||||
Ws->Send(Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FDTFluxWebSocketClient::Bind_Internal()
|
||||
|
||||
@ -12,17 +12,30 @@
|
||||
#include "Struct/DTFluxRequestStructs.h"
|
||||
#include "Struct/DTFluxRaceDataServerResponse.h"
|
||||
#include "Struct/DTFluxRankingServerResponse.h"
|
||||
#include "Struct/DTFluxSplitSensorServerResponse.h"
|
||||
#include "Struct/DTFluxTeamListServerResponse.h"
|
||||
#include "Types/Objects/UDTFluxParticipantFactory.h"
|
||||
#include "Types/Struct/DTFluxRaceDataStructs.h"
|
||||
#include "Types/Struct/DTFluxSplitSensor.h"
|
||||
|
||||
|
||||
void UFDTFluxNetworkSubsystem::Connect()
|
||||
void UDTFluxNetworkSubsystem::Connect()
|
||||
{
|
||||
WsClient->SetAddress(ConstructWsAddress(WsSettings.Address, WsSettings.Path, WsSettings.Port));
|
||||
WsClient->Connect();
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::SendRequest(const EDTFluxRequestType RequestType, int InContestId, int InStageId,
|
||||
void UDTFluxNetworkSubsystem::Disconnect()
|
||||
{
|
||||
WsClient->Disconnect();
|
||||
}
|
||||
|
||||
void UDTFluxNetworkSubsystem::Reconnect()
|
||||
{
|
||||
ReconnectWs(FName("Ws_Client_0"));
|
||||
}
|
||||
|
||||
void UDTFluxNetworkSubsystem::SendRequest(const EDTFluxRequestType RequestType, int InContestId, int InStageId,
|
||||
int InSplitId)
|
||||
{
|
||||
FString Message;
|
||||
@ -52,12 +65,24 @@ void UFDTFluxNetworkSubsystem::SendRequest(const EDTFluxRequestType RequestType,
|
||||
SendMessage(Message);
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::SendMessage(const FString& Message)
|
||||
void UDTFluxNetworkSubsystem::SendMessage(const FString& Message)
|
||||
{
|
||||
UE_LOG(logDTFluxCore, Warning, TEXT("Sending Message %s"), *Message);
|
||||
|
||||
|
||||
if(WsClient.IsValid() && WsClient->CanSend())
|
||||
{
|
||||
WsClient->Send(Message);
|
||||
UE_LOG(logDTFluxNetwork, Log, TEXT("Can send request"));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Error, TEXT("[Websocket Not Connected]. Connect before sending requests..."));
|
||||
}
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
||||
void UDTFluxNetworkSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
||||
{
|
||||
Super::Initialize(Collection);
|
||||
FDTFluxCoreModule& DTFluxCore = FModuleManager::Get().LoadModuleChecked<FDTFluxCoreModule>("DTFluxCore");
|
||||
@ -81,22 +106,17 @@ void UFDTFluxNetworkSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
||||
}
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::Deinitialize()
|
||||
void UDTFluxNetworkSubsystem::Deinitialize()
|
||||
{
|
||||
Super::Deinitialize();
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::WsSettingsChanged(const FDTFluxWsSettings& NewWsSettings)
|
||||
void UDTFluxNetworkSubsystem::WsSettingsChanged(const FDTFluxWsSettings& NewWsSettings)
|
||||
{
|
||||
// TODO Implement a ClientSelector To retrieve impacted WsClients and populate changes or maybe create a delegate
|
||||
bool bNeedsReload = WsSettings != NewWsSettings;
|
||||
|
||||
WsSettings = NewWsSettings;
|
||||
// UE_LOG(logDTFluxNetwork, Warning, TEXT("WSocket Settings Changed \n\t Address : %s Path : %s Port : %i\n\tbShouldConnectAtStatup : %s, bShouldAutoReconnectOnClosed %s, bShouldAutoReconnectOnError %s"),
|
||||
// *NewWsSettings.Address, *NewWsSettings.Path, NewWsSettings.Port,
|
||||
// NewWsSettings.bShouldConnectAtStartup ? TEXT("True") : TEXT("False"),
|
||||
// NewWsSettings.bShouldAutoReconnectOnClosed ? TEXT("True") : TEXT("False"),
|
||||
// NewWsSettings.bShouldAutoReconnectOnError ? TEXT("True") : TEXT("False") );
|
||||
if( bNeedsReload || WsSettings.bShouldConnectAtStartup)
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("WSocket Settings needs Reloding client"))
|
||||
@ -105,46 +125,46 @@ void UFDTFluxNetworkSubsystem::WsSettingsChanged(const FDTFluxWsSettings& NewWsS
|
||||
}
|
||||
|
||||
|
||||
void UFDTFluxNetworkSubsystem::HttpSettingsChanged(const FDTFluxHttpSettings& NewHttpSettings)
|
||||
void UDTFluxNetworkSubsystem::HttpSettingsChanged(const FDTFluxHttpSettings& NewHttpSettings)
|
||||
{
|
||||
// TODO Implement a ClientSelector To retrieve impacted HttpClients and populate changes or maybe create a delegate
|
||||
HttpSettings = NewHttpSettings;
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::ReconnectWs(const FName WsClientId)
|
||||
void UDTFluxNetworkSubsystem::ReconnectWs(const FName WsClientId)
|
||||
{
|
||||
FString NewAddress = ConstructWsAddress(WsSettings.Address, WsSettings.Path, WsSettings.Port);
|
||||
WsClient->SetAddress(NewAddress);
|
||||
WsClient->Reconnect();
|
||||
}
|
||||
void UFDTFluxNetworkSubsystem::ReconnectHttp(const FName WsClientId)
|
||||
void UDTFluxNetworkSubsystem::ReconnectHttp(const FName WsClientId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::RegisterWebSocketEvents()
|
||||
void UDTFluxNetworkSubsystem::RegisterWebSocketEvents()
|
||||
{
|
||||
OnWsConnectedEventDelegateHandle =
|
||||
WsClient->RegisterConnectedEvent().AddUObject(this, &UFDTFluxNetworkSubsystem::OnWebSocketConnected_Subsystem);
|
||||
WsClient->RegisterConnectedEvent().AddUObject(this, &UDTFluxNetworkSubsystem::OnWebSocketConnected_Subsystem);
|
||||
OnWsConnectionErrorEventDelegateHandle =
|
||||
WsClient->RegisterConnectionError()
|
||||
.AddUObject(this, &UFDTFluxNetworkSubsystem::OnWebSocketConnectionError_Subsystem);
|
||||
.AddUObject(this, &UDTFluxNetworkSubsystem::OnWebSocketConnectionError_Subsystem);
|
||||
OnWsClosedEventDelegateHandle =
|
||||
WsClient->RegisterClosedEvent()
|
||||
.AddUObject(this, &UFDTFluxNetworkSubsystem::OnWebSocketClosedEvent_Subsystem);
|
||||
.AddUObject(this, &UDTFluxNetworkSubsystem::OnWebSocketClosedEvent_Subsystem);
|
||||
OnWsMessageEventDelegateHandle =
|
||||
WsClient->RegisterMessageEvent()
|
||||
.AddUObject(this, &UFDTFluxNetworkSubsystem::OnWebSocketMessageEvent_Subsystem);
|
||||
.AddUObject(this, &UDTFluxNetworkSubsystem::OnWebSocketMessageEvent_Subsystem);
|
||||
OnWsMessageSentEventDelegateHandle =
|
||||
WsClient->RegisterMessageSentEvent()
|
||||
.AddUObject(this, &UFDTFluxNetworkSubsystem::OnWebSocketMessageSentEvent_Subsystem);
|
||||
.AddUObject(this, &UDTFluxNetworkSubsystem::OnWebSocketMessageSentEvent_Subsystem);
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::RegisterHttpEvents()
|
||||
void UDTFluxNetworkSubsystem::RegisterHttpEvents()
|
||||
{
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::UnregisterWebSocketEvents()
|
||||
void UDTFluxNetworkSubsystem::UnregisterWebSocketEvents()
|
||||
{
|
||||
if(OnWsConnectedEventDelegateHandle.IsValid())
|
||||
{
|
||||
@ -168,50 +188,72 @@ void UFDTFluxNetworkSubsystem::UnregisterWebSocketEvents()
|
||||
}
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::UnregisterHttpEvents()
|
||||
void UDTFluxNetworkSubsystem::UnregisterHttpEvents()
|
||||
{
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::OnWebSocketConnected_Subsystem()
|
||||
void UDTFluxNetworkSubsystem::OnWebSocketConnected_Subsystem()
|
||||
{
|
||||
WsStatus = EDTFluxConnectionStatus::Connected;
|
||||
OnWebSocketConnected.Broadcast();
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Ws Is Connected with %s"), *WsClient->GetAddress())
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::OnWebSocketConnectionError_Subsystem(const FString& Error)
|
||||
void UDTFluxNetworkSubsystem::OnWebSocketConnectionError_Subsystem(const FString& Error)
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Ws Error with %s : %s"), *WsClient->GetAddress(), *Error);
|
||||
WsStatus = EDTFluxConnectionStatus::Error;
|
||||
if(WsSettings.bShouldAutoReconnectOnError)
|
||||
{
|
||||
WsClient->Reconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::OnWebSocketClosedEvent_Subsystem(int32 StatusCode, const FString& Reason, bool bWasClean)
|
||||
void UDTFluxNetworkSubsystem::OnWebSocketClosedEvent_Subsystem(int32 StatusCode, const FString& Reason, bool bWasClean)
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Ws Error with %s :\n Reason : %s \tStatusCode : %i, bWasClean : %s"),
|
||||
*WsClient->GetAddress(), *Reason, StatusCode, bWasClean ? TEXT("True") : TEXT("False"));
|
||||
WsStatus = EDTFluxConnectionStatus::Closed;
|
||||
}
|
||||
|
||||
//TODO reforge API to keep track of Requests
|
||||
void UFDTFluxNetworkSubsystem::OnWebSocketMessageEvent_Subsystem(const FString& MessageString)
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Ws %s :\nMessage Received : %s"), *WsClient->GetAddress(), *MessageString);
|
||||
//Do Something With the message
|
||||
FDTFluxServerResponse Response;
|
||||
Response.ReceivedAt = FDateTime::Now();
|
||||
Response.RawMessage = MessageString;
|
||||
Response.FailureReason = FText::FromString("--");
|
||||
if(FJsonObjectConverter::JsonObjectStringToUStruct(MessageString, &Response, 0, 0, false, &(Response.FailureReason)))
|
||||
{
|
||||
if(Response.Code == -1)
|
||||
{
|
||||
// return DataReceived.Broadcast(Response);
|
||||
if(Response.Type.Contains("race-data"))
|
||||
void UDTFluxNetworkSubsystem::ParseTeamListResponse(const FDTFluxServerResponse& ServerResponse)
|
||||
{
|
||||
TSharedPtr<FJsonObject> JsonObject;
|
||||
TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(ServerResponse.RawMessage);
|
||||
|
||||
if (!FJsonSerializer::Deserialize(Reader, JsonObject) || !JsonObject.IsValid())
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Error, TEXT("JSON invalide : %s"), *ServerResponse.RawMessage);
|
||||
return;
|
||||
}
|
||||
const TArray<TSharedPtr<FJsonValue>>* DataArray;
|
||||
if (!JsonObject->TryGetArrayField(TEXT("datas"), DataArray))
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Error, TEXT("Aucun champ 'datas' trouvé dans le team-list"));
|
||||
return;
|
||||
}
|
||||
FDTFluxTeamListDefinition TeamListDefinition;
|
||||
for (const TSharedPtr<FJsonValue>& Value : *DataArray)
|
||||
{
|
||||
if (Value->Type == EJson::Object)
|
||||
{
|
||||
const TSharedPtr<FJsonObject> Item = Value->AsObject();
|
||||
|
||||
FDTFluxParticipant Participant;
|
||||
UDTFluxParticipantFactory::CreateFromJsonCpp(Item, Participant);
|
||||
TeamListDefinition.Participants.Add(Participant);
|
||||
}
|
||||
}
|
||||
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Inserting %i Participants [%s]"), TeamListDefinition.Participants.Num(),
|
||||
OnTeamListReceived.ExecuteIfBound(TeamListDefinition) ? TEXT("SUCCESS_SEND") : TEXT("NOT_BOUNDED"));
|
||||
}
|
||||
|
||||
void UDTFluxNetworkSubsystem::ParseRaceData(const FDTFluxServerResponse& Response)
|
||||
{
|
||||
FDTFluxRaceDataResponse RaceData;
|
||||
FJsonObjectConverter::JsonObjectStringToUStruct<FDTFluxRaceDataResponse>(Response.RawMessage, &RaceData);
|
||||
if(FJsonObjectConverter::JsonObjectStringToUStruct<FDTFluxRaceDataResponse>(Response.RawMessage, &RaceData))
|
||||
{
|
||||
//convert
|
||||
FDTFluxRaceData RaceDataDefinition;
|
||||
for(auto Contest : RaceData.Datas)
|
||||
@ -256,22 +298,18 @@ void UFDTFluxNetworkSubsystem::OnWebSocketMessageEvent_Subsystem(const FString&
|
||||
}
|
||||
RaceDataDefinition.Datas.Add(NewContest);
|
||||
}
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Sending %i Contests"), RaceDataDefinition.Datas.Num());
|
||||
return OnRaceDataReceived.Broadcast(RaceDataDefinition);
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Sending %i Contests, [%s]"), RaceDataDefinition.Datas.Num(),
|
||||
OnRaceDataReceived.ExecuteIfBound(RaceDataDefinition) ? TEXT("SUCCESS_SEND") : TEXT("NOT_BOUNDED"));
|
||||
return;
|
||||
}
|
||||
if(Response.Type.Contains("team-list"))
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Ws Team-List Data"));
|
||||
FDTFluxTeamListDefinition TeamListDefinition;
|
||||
FJsonObjectConverter::JsonObjectStringToUStruct<FDTFluxTeamListDefinition>(Response.RawMessage, &TeamListDefinition);
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Ws Team-List Data Sent"));
|
||||
return OnTeamListReceived.Broadcast(TeamListDefinition);
|
||||
UE_LOG(logDTFluxNetwork, Error, TEXT("ParseRaceData() for JSON Response : %s"), *Response.RawMessage);
|
||||
}
|
||||
if(Response.Type.Contains("contest-ranking"))
|
||||
|
||||
void UDTFluxNetworkSubsystem::ParseContestRanking(const FDTFluxServerResponse& Response)
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Ws Contest-Ranking Data"));
|
||||
FDTFluxContestRankingResponse ContestRankingResponse;
|
||||
FJsonObjectConverter::JsonObjectStringToUStruct<FDTFluxContestRankingResponse>(Response.RawMessage, &ContestRankingResponse);
|
||||
if(FJsonObjectConverter::JsonObjectStringToUStruct<FDTFluxContestRankingResponse>(Response.RawMessage, &ContestRankingResponse))
|
||||
{
|
||||
FDTFluxContestRankings ContestRankings;
|
||||
ContestRankings.ContestId = ContestRankingResponse.ContestID;
|
||||
for(auto& RankingItem : ContestRankingResponse.Datas)
|
||||
@ -279,27 +317,146 @@ void UFDTFluxNetworkSubsystem::OnWebSocketMessageEvent_Subsystem(const FString&
|
||||
FDTFluxContestRanking Temp = RankingItem;
|
||||
ContestRankings.Rankings.Add(Temp);
|
||||
}
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Ws ContestRanking Data Sent for Contest %i"), ContestRankings.ContestId);
|
||||
return OnContestRankingReceived.Broadcast(ContestRankings);
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Ws ContestRanking Data Sent for Contest %i, [%s]"), ContestRankings.ContestId,
|
||||
OnContestRankingReceived.ExecuteIfBound(ContestRankings) ? TEXT("SUCCESS_SEND") : TEXT("NOT_BOUNDED"));
|
||||
return;
|
||||
}
|
||||
UE_LOG(logDTFluxNetwork, Error, TEXT("ParseContestRanking() for JSON Response : %s"), *Response.RawMessage);
|
||||
|
||||
}
|
||||
|
||||
void UDTFluxNetworkSubsystem::ParseStageRankingResponse(const FDTFluxServerResponse& Response)
|
||||
{
|
||||
FDTFluxStageRankingResponse RankingResponse;
|
||||
if(FJsonObjectConverter::JsonObjectStringToUStruct<FDTFluxStageRankingResponse>(Response.RawMessage, &RankingResponse))
|
||||
{
|
||||
FDTFluxStageRankings NewRankings;
|
||||
NewRankings.ContestId = Response.ContestID;
|
||||
NewRankings.StageId = Response.StageID;
|
||||
NewRankings.Rankings = static_cast<TArray<FDTFluxDetailedRankingItem>>(RankingResponse.Datas);
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("StageRanking Data Sent for Contest %i, Stage %i\n[Result] : %s"),
|
||||
NewRankings.ContestId, NewRankings.StageId,
|
||||
OnStageRankingReceived.ExecuteIfBound(NewRankings) ? TEXT("SUCCESS_SEND") : TEXT("NOT_BOUNDED")
|
||||
);
|
||||
return;
|
||||
}
|
||||
UE_LOG(logDTFluxNetwork, Error, TEXT("ParseStageRankingResponse() for JSON Response : %s"), *Response.RawMessage);
|
||||
}
|
||||
|
||||
void UDTFluxNetworkSubsystem::ParseSplitRankingResponse(const FDTFluxServerResponse& Response)
|
||||
{
|
||||
FDTFluxSplitRankingResponse SplitRankingResponse;
|
||||
if(FJsonObjectConverter::JsonObjectStringToUStruct<FDTFluxSplitRankingResponse>(Response.RawMessage, &SplitRankingResponse))
|
||||
{
|
||||
FDTFluxSplitRankings NewSplitRankings;
|
||||
NewSplitRankings.ContestId = Response.ContestID;
|
||||
NewSplitRankings.StageId = Response.StageID;
|
||||
NewSplitRankings.SplitId = Response.SplitID;
|
||||
NewSplitRankings.Rankings = static_cast<TArray<FDTFluxDetailedRankingItem>>(SplitRankingResponse.Datas);
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("SplitRanking Data Sent for Contest %i, Stage %i and Split %i\n[Result] : %s"),
|
||||
NewSplitRankings.ContestId, NewSplitRankings.StageId, NewSplitRankings.SplitId,
|
||||
OnSplitRankingReceived.ExecuteIfBound(NewSplitRankings) ? TEXT("SUCCESS_SEND") : TEXT("NOT_BOUNDED"));
|
||||
return;
|
||||
}
|
||||
UE_LOG(logDTFluxNetwork, Error, TEXT("ParseSplitRankingResponse() for JSON Response : %s"), *Response.RawMessage);
|
||||
|
||||
}
|
||||
|
||||
void UDTFluxNetworkSubsystem::ParseStatusUpdateResponse(const FDTFluxServerResponse& Response)
|
||||
{
|
||||
FDTFluxTeamStatusUpdate StatusUpdateResponse;
|
||||
|
||||
if (FJsonObjectConverter::JsonObjectStringToUStruct<FDTFluxTeamStatusUpdate>(Response.RawMessage, &StatusUpdateResponse))
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Status Update for bib %i \n[Result] : %s\n"),
|
||||
StatusUpdateResponse.Bib,
|
||||
OnTeamStatusUpdateReceived.ExecuteIfBound(StatusUpdateResponse) ? TEXT("SUCCESS_SEND") : TEXT("NOT_BOUNDED"));
|
||||
return;
|
||||
}
|
||||
UE_LOG(logDTFluxNetwork, Error, TEXT("ParseStatusUpdateResponse() for JSON Response : %s"), *Response.RawMessage);
|
||||
}
|
||||
|
||||
void UDTFluxNetworkSubsystem::ParseSplitSensorResponse(const FDTFluxServerResponse& Response)
|
||||
{
|
||||
FDTFluxSplitSensorResponse SplitSensorResponse;
|
||||
if(FJsonObjectConverter::JsonObjectStringToUStruct(Response.RawMessage, &SplitSensorResponse))
|
||||
{
|
||||
for(const auto& SplitSensorInfoResponse : SplitSensorResponse.Datas)
|
||||
{
|
||||
FDTFluxSplitSensorInfo NewSplitSensorInfo;
|
||||
NewSplitSensorInfo.Bib = SplitSensorInfoResponse.Bib;
|
||||
NewSplitSensorInfo.ContestId = SplitSensorInfoResponse.ContestID;
|
||||
NewSplitSensorInfo.StageId = SplitSensorInfoResponse.StageID;
|
||||
NewSplitSensorInfo.SplitId = SplitSensorInfoResponse.SplitID;
|
||||
NewSplitSensorInfo.Time = SplitSensorInfoResponse.Time;
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Status Update for bib %i in Contest %i, Stage %i in split %i\n[Result] : %s\n"),
|
||||
NewSplitSensorInfo.Bib, NewSplitSensorInfo.ContestId, NewSplitSensorInfo.StageId, NewSplitSensorInfo.SplitId,
|
||||
OnSplitSensorReceived.ExecuteIfBound(NewSplitSensorInfo) ? TEXT("SUCCESS_SEND") : TEXT("NOT_BOUNDED"));
|
||||
}
|
||||
}
|
||||
UE_LOG(logDTFluxNetwork, Error, TEXT("ParseSplitSensorResponse() failed for JSON Response : %s"), *Response.RawMessage);
|
||||
}
|
||||
|
||||
//TODO reforge API to keep track of Requests
|
||||
void UDTFluxNetworkSubsystem::OnWebSocketMessageEvent_Subsystem(const FString& MessageString)
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Client %s :\nMessage Received : %s"), *WsClient->GetAddress(), *MessageString);
|
||||
//Do Something With the message
|
||||
FDTFluxServerResponse Response;
|
||||
Response.ReceivedAt = FDateTime::Now();
|
||||
Response.RawMessage = MessageString;
|
||||
Response.FailureReason = FText::FromString("--");
|
||||
if(FJsonObjectConverter::JsonObjectStringToUStruct(MessageString, &Response, 0, 0, false, &(Response.FailureReason)))
|
||||
{
|
||||
if(Response.Code == -1)
|
||||
{
|
||||
// return DataReceived.Broadcast(Response);
|
||||
if(Response.Type.Contains("race-data"))
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Race-Data Received"));
|
||||
return ParseRaceData(Response);
|
||||
}
|
||||
if(Response.Type.Contains("team-list"))
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Team-List Received"));
|
||||
return ParseTeamListResponse(Response);
|
||||
}
|
||||
if(Response.Type.Contains("contest-ranking"))
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Contest-Ranking Received"));
|
||||
return ParseContestRanking(Response);
|
||||
}
|
||||
if(Response.Type.Contains("stage-ranking") )
|
||||
{
|
||||
// StageRanking
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Ws Stage-Ranking Data"));
|
||||
FDTFluxStageRankingResponse StageRankingResponse;
|
||||
FJsonObjectConverter::JsonObjectStringToUStruct<FDTFluxStageRankingResponse>(Response.RawMessage, &StageRankingResponse);
|
||||
FDTFluxStageRankings StageRankings;
|
||||
StageRankings.ContestId = StageRankingResponse.ContestId;
|
||||
StageRankings.StageId = StageRankingResponse.StageId;
|
||||
StageRankings.SplitId = StageRankingResponse.SplitId;
|
||||
for(FDTFluxStageRanking& InRanking : StageRankingResponse.Datas)
|
||||
if(Response.SplitID == -1)
|
||||
{
|
||||
FDTFluxStageRanking Temp = InRanking;
|
||||
StageRankings.Rankings.Add(InRanking);
|
||||
// StageRanking
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Stage-Ranking Data"));
|
||||
ParseStageRankingResponse(Response);
|
||||
}
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Ws StageRanking Data Sent for Contest %i and Stage %i\n[Result] : %s"),
|
||||
StageRankings.ContestId, StageRankings.StageId, OnStageRankingReceived.ExecuteIfBound(StageRankings) ? TEXT("Executed") : TEXT("Not Bound !!!"));
|
||||
return;
|
||||
else
|
||||
{
|
||||
// StageRanking
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Split-Ranking Data"));
|
||||
return ParseSplitRankingResponse(Response);
|
||||
}
|
||||
}
|
||||
if(Response.Type.Contains("split-sensor"))
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("split-sensor Data"));
|
||||
ParseSplitSensorResponse(Response);
|
||||
|
||||
}
|
||||
if(Response.Type.Contains("status-update"))
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("status-update Data"));
|
||||
ParseStatusUpdateResponse(Response);
|
||||
|
||||
}
|
||||
if(Response.Type.Contains("team-update"))
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("team-update Data"));
|
||||
ParseTeamListResponse(Response);
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,12 +466,12 @@ void UFDTFluxNetworkSubsystem::OnWebSocketMessageEvent_Subsystem(const FString&
|
||||
|
||||
}
|
||||
|
||||
void UFDTFluxNetworkSubsystem::OnWebSocketMessageSentEvent_Subsystem(const FString& MessageSent)
|
||||
void UDTFluxNetworkSubsystem::OnWebSocketMessageSentEvent_Subsystem(const FString& MessageSent)
|
||||
{
|
||||
UE_LOG(logDTFluxNetwork, Warning, TEXT("Ws %s :\nMessage Sent: %s"), *WsClient->GetAddress(), *MessageSent);
|
||||
}
|
||||
|
||||
FString UFDTFluxNetworkSubsystem::ConstructWsAddress(const FString& Address, const FString& Path, const int& Port)
|
||||
FString UDTFluxNetworkSubsystem::ConstructWsAddress(const FString& Address, const FString& Path, const int& Port)
|
||||
{
|
||||
FString NewAddress;
|
||||
if( !Address.Contains("ws://") && !Address.Contains("wss://"))
|
||||
@ -324,4 +481,5 @@ FString UFDTFluxNetworkSubsystem::ConstructWsAddress(const FString& Address, con
|
||||
NewAddress +=Address + FString(":") + FString::FromInt(Port) + Path;
|
||||
return NewAddress;
|
||||
// UE_LOG(logDTFluxNetwork, Log, TEXT("NewAddress : %s"), *NewAddress);
|
||||
|
||||
}
|
||||
|
||||
@ -53,17 +53,11 @@ public:
|
||||
|
||||
FDTFluxWebSocketClient();
|
||||
|
||||
static TSharedPtr<FDTFluxWebSocketClient> GetClient(const TArray<TSharedPtr<FDTFluxWebSocketClient>> InClients, const FName InName)
|
||||
{
|
||||
for(auto Client: InClients)
|
||||
{
|
||||
if(Client->ClientId == InName)
|
||||
{
|
||||
return Client;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
bool CanSend() const;
|
||||
|
||||
|
||||
static TSharedPtr<FDTFluxWebSocketClient> GetClient(const TArray<TSharedPtr<FDTFluxWebSocketClient>> InClients, const FName InName);
|
||||
|
||||
|
||||
void Connect();
|
||||
void Reconnect();
|
||||
|
||||
@ -33,7 +33,18 @@ public:
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct DTFLUXNETWORK_API FDTFluxStageRankingResponseItem : public FDTFluxStageRanking
|
||||
struct DTFLUXNETWORK_API FDTFluxStageRankingResponseItem : public FDTFluxDetailedRankingItem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY()
|
||||
FString Type = "team-stage-ranking";
|
||||
};
|
||||
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct DTFLUXNETWORK_API FDTFluxSplitRankingResponseItem : public FDTFluxDetailedRankingItem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@ -43,7 +54,7 @@ public:
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct DTFLUXNETWORK_API FDTFluxStageRankingResponse : public FDTFluxStageRankings
|
||||
struct DTFLUXNETWORK_API FDTFluxStageRankingResponse
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@ -56,3 +67,18 @@ public:
|
||||
// ReSharper disable once IdentifierTypo
|
||||
TArray<FDTFluxStageRankingResponseItem> Datas;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct DTFLUXNETWORK_API FDTFluxSplitRankingResponse
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY()
|
||||
FString Type = "stage-ranking";
|
||||
|
||||
|
||||
UPROPERTY()
|
||||
// ReSharper disable once IdentifierTypo
|
||||
TArray<FDTFluxSplitRankingResponseItem> Datas;
|
||||
};
|
||||
|
||||
@ -25,10 +25,7 @@ public:
|
||||
int SplitID;
|
||||
UPROPERTY()
|
||||
FString Time = "-";
|
||||
UPROPERTY()
|
||||
FString Gap = "-";
|
||||
UPROPERTY()
|
||||
int Rank;
|
||||
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
|
||||
@ -6,8 +6,11 @@
|
||||
#include "Struct/DTFluxServerResponseStruct.h"
|
||||
#include "Subsystems/EngineSubsystem.h"
|
||||
#include "Types/DTFluxNetworkSettingsTypes.h"
|
||||
#include "Types/Enum/DTfluxCoreEnum.h"
|
||||
#include "Types/Enum/DTFluxCoreEnum.h"
|
||||
#include "Types/Struct/DTFluxRaceDataStructs.h"
|
||||
#include "Types/Struct/DTFluxRankingStructs.h"
|
||||
#include "Types/Struct/DTFluxSplitSensor.h"
|
||||
#include "Types/Struct/DTFluxTeamListStruct.h"
|
||||
#include "DTFluxNetworkSubsystem.generated.h"
|
||||
|
||||
|
||||
@ -21,53 +24,79 @@ typedef TSharedPtr<FDTFluxHttpClient> FDTFluxHttpClientSP;
|
||||
*
|
||||
*/
|
||||
UCLASS(Blueprintable)
|
||||
class DTFLUXNETWORK_API UFDTFluxNetworkSubsystem : public UEngineSubsystem
|
||||
class DTFLUXNETWORK_API UDTFluxNetworkSubsystem : public UEngineSubsystem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY()
|
||||
EDTFluxConnectionStatus WsStatus = EDTFluxConnectionStatus::Unset;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnWebSocketConnected);
|
||||
UPROPERTY(BlueprintAssignable, Category="DTFlux|Network")
|
||||
FOnWebSocketConnected OnWebSocketConnected;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnRaceDataReceived, const FDTFluxRaceData&, RaceDataDefinition);
|
||||
DECLARE_DELEGATE_OneParam(FOnRaceDataReceived, const FDTFluxRaceData& /*RaceDataDefinition*/);
|
||||
FOnRaceDataReceived OnRaceDataReceived;
|
||||
FOnRaceDataReceived& OnReceivedRaceData()
|
||||
{
|
||||
return OnRaceDataReceived;
|
||||
};
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTeamListReceived, const FDTFluxTeamListDefinition&, TeamListDefinition);
|
||||
DECLARE_DELEGATE_OneParam(FOnTeamListReceived, const FDTFluxTeamListDefinition& /*TeamListDefinition*/);
|
||||
FOnTeamListReceived OnTeamListReceived;
|
||||
FOnTeamListReceived& OnReceivedTeamList()
|
||||
{
|
||||
return OnTeamListReceived;
|
||||
};
|
||||
|
||||
DECLARE_DELEGATE_OneParam(FOnStageRankingReceived, const FDTFluxStageRankings&);
|
||||
DECLARE_DELEGATE_OneParam(FOnStageRankingReceived, const FDTFluxStageRankings& /*StageRankings*/);
|
||||
FOnStageRankingReceived OnStageRankingReceived;
|
||||
FOnStageRankingReceived& OnReceivedStageRanking()
|
||||
{
|
||||
return OnStageRankingReceived;
|
||||
}
|
||||
DECLARE_DELEGATE_OneParam(FOnSplitRankingReceived, const FDTFluxSplitRankings& /*SplitRankings*/);
|
||||
FOnSplitRankingReceived OnSplitRankingReceived;
|
||||
FOnSplitRankingReceived& OnReceivedSplitRanking()
|
||||
{
|
||||
return OnSplitRankingReceived;
|
||||
}
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnContestRankingReceived, const FDTFluxContestRankings&, ContestRankings);
|
||||
DECLARE_DELEGATE_OneParam(FOnContestRankingReceived, const FDTFluxContestRankings& /*ContestRankings*/);
|
||||
FOnContestRankingReceived OnContestRankingReceived;
|
||||
FOnContestRankingReceived& OnReceivedContestRanking()
|
||||
{
|
||||
return OnContestRankingReceived;
|
||||
};
|
||||
DECLARE_DELEGATE_OneParam(FOnSplitSensorReceived, const FDTFluxSplitSensorInfo& /*ContestRankings*/);
|
||||
FOnSplitSensorReceived OnSplitSensorReceived;
|
||||
FOnSplitSensorReceived& OnReceivedSplitSensor()
|
||||
{
|
||||
return OnSplitSensorReceived;
|
||||
};
|
||||
|
||||
DECLARE_DELEGATE_OneParam(FOnTeamUpdateReceived, const FDTFluxParticipant& /*ParticipantToUpdate*/);
|
||||
FOnTeamUpdateReceived OnTeamUpdateReceived;
|
||||
FOnTeamUpdateReceived& OnReceivedTeamUpdate()
|
||||
{
|
||||
return OnTeamUpdateReceived;
|
||||
};
|
||||
|
||||
DECLARE_DELEGATE_OneParam(FOnTeamStatusUpdateReceived, const FDTFluxTeamStatusUpdate& /*TeamToUpdate*/);
|
||||
FOnTeamStatusUpdateReceived OnTeamStatusUpdateReceived;
|
||||
FOnTeamStatusUpdateReceived& OnReceivedTeamStatusUpdate()
|
||||
{
|
||||
return OnTeamStatusUpdateReceived;
|
||||
};
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Network")
|
||||
void Connect();
|
||||
//
|
||||
// UFUNCTION(BlueprintCallable, Category="DTFlux|Network")
|
||||
// void Reconnect();
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Network")
|
||||
void Disconnect();
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Network")
|
||||
void Reconnect();
|
||||
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="DTFlux|Core Subsystem")
|
||||
@ -103,6 +132,13 @@ private:
|
||||
void OnWebSocketConnected_Subsystem();
|
||||
void OnWebSocketConnectionError_Subsystem(const FString& Error);
|
||||
void OnWebSocketClosedEvent_Subsystem(int32 StatusCode , const FString& Reason, bool bWasClean);
|
||||
void ParseTeamListResponse(const FDTFluxServerResponse& ServerResponse);
|
||||
void ParseRaceData(const FDTFluxServerResponse& Response);
|
||||
void ParseContestRanking(const FDTFluxServerResponse& Response);
|
||||
void ParseStageRankingResponse(const FDTFluxServerResponse& Response);
|
||||
void ParseSplitRankingResponse(const FDTFluxServerResponse& Response);
|
||||
void ParseStatusUpdateResponse(const FDTFluxServerResponse& Response);
|
||||
void ParseSplitSensorResponse(const FDTFluxServerResponse& Response);
|
||||
void OnWebSocketMessageEvent_Subsystem(const FString& MessageString);
|
||||
void OnWebSocketMessageSentEvent_Subsystem(const FString& MessageSent);
|
||||
|
||||
|
||||
@ -21,7 +21,9 @@ public class DTFluxProjectSettings : ModuleRules
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"DeveloperSettings",
|
||||
"DTFluxCore"
|
||||
"DTFluxCore",
|
||||
"Settings",
|
||||
"DeveloperSettings"
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
@ -9,7 +9,8 @@ UDTFluxGeneralSettings::UDTFluxGeneralSettings()
|
||||
{
|
||||
CategoryName = "DTFlux API";
|
||||
|
||||
UE_LOG(logDTFluxProjectSettings, Log, TEXT("ModelAssetLoded isNull() -> %s"), ModelAsset.IsNull() ? TEXT("TRUE") : TEXT("FALSE"));
|
||||
// UE_LOG(logDTFluxProjectSettings, Log, TEXT("ModelAssetLoded isNull() -> %s"), ModelAsset.IsNull() ? TEXT("TRUE") : TEXT("FALSE"));
|
||||
//
|
||||
UE_LOG(logDTFluxProjectSettings, Log, TEXT("Category Name -> %s"), *GetCategoryName().ToString());
|
||||
|
||||
UE_LOG(logDTFluxProjectSettings, Log, TEXT("ModelAssetLoded IsValid() -> %s"), ModelAsset.IsValid() ? TEXT("TRUE") : TEXT("FALSE"));
|
||||
}
|
||||
|
||||
@ -1,16 +1,51 @@
|
||||
#include "DTFluxProjectSettingsModule.h"
|
||||
|
||||
#include "DTFluxGeneralSettings.h"
|
||||
#include "DTFluxNetworkSettings.h"
|
||||
#include "ISettingsModule.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FDTFluxProjectSettingsModule"
|
||||
|
||||
DTFLUXPROJECTSETTINGS_API DEFINE_LOG_CATEGORY(logDTFluxProjectSettings)
|
||||
|
||||
void FDTFluxProjectSettingsModule::StartupModule()
|
||||
{
|
||||
|
||||
RegisterSettings();
|
||||
}
|
||||
|
||||
void FDTFluxProjectSettingsModule::ShutdownModule()
|
||||
{
|
||||
UnregisterSettings();
|
||||
}
|
||||
|
||||
void FDTFluxProjectSettingsModule::RegisterSettings()
|
||||
{
|
||||
|
||||
if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
|
||||
{
|
||||
SettingsModule->RegisterSettings("Project", "DTFluxProjectSettings", "DTFluxGeneralSettings",
|
||||
FText::FromString("DTFlux General Settings"),
|
||||
FText::FromString("DTFluxAPI Network Settings"),
|
||||
GetMutableDefault<UDTFluxGeneralSettings>()
|
||||
);
|
||||
SettingsModule->RegisterSettings("Project", "DTFluxProjectSettings", "DTFluxNetworkSettings",
|
||||
FText::FromString("DTFlux Network Settings"),
|
||||
FText::FromString("DTFluxAPI Network Settings"),
|
||||
GetMutableDefault<UDTFluxNetworkSettings>()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void FDTFluxProjectSettingsModule::UnregisterSettings()
|
||||
{
|
||||
if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
|
||||
{
|
||||
SettingsModule->UnregisterSettings("Project", "DTFluxProjectSettings", "DTFluxGeneralSettings");
|
||||
SettingsModule->UnregisterSettings("Project", "DTFluxProjectSettings", "DTFluxNetworkSettings");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ class DTFLUXPROJECTSETTINGS_API UDTFluxGeneralSettings : public UDeveloperSettin
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
virtual bool SupportsAutoRegistration() const override{ return false; }
|
||||
UDTFluxGeneralSettings();
|
||||
UPROPERTY(Category="General", Config, EditAnywhere, BlueprintReadOnly, DisplayName="Datastorage File")
|
||||
TSoftObjectPtr<UDTFluxModelAsset> ModelAsset;
|
||||
|
||||
@ -48,7 +48,7 @@ public:
|
||||
UPROPERTY(Category="CHRONO PROXY|HTTP", Config, EditAnywhere, BlueprintReadOnly, DisplayName="HTTP Port")
|
||||
int HTTPPort = 8080;
|
||||
|
||||
|
||||
virtual bool SupportsAutoRegistration() const override{ return false; }
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
|
||||
@ -21,4 +21,7 @@ public:
|
||||
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
|
||||
void RegisterSettings();
|
||||
void UnregisterSettings();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user