I used dependency inversion 2 lectures ago during the challenge. So I didn’t have to have ServerRow call Mainmenu. I also made ServerRow contain a button. In my version I had to create a new ServerRowInterface, so I’m not sure it’s actually more simple.
/**
* Interface for a ServerRow widget.
*/
class SHIPPY_API ServerRowInterface
{
public:
virtual void ServerRowJoin(const FString &Address) = 0;
};
/**
* A single server in the server search menu.
*/
UCLASS()
class SHIPPY_API UServerRow : public UUserWidget
{
GENERATED_BODY()
FString Address;
ServerRowInterface* Interface;
public:
UPROPERTY(meta = (BindWidget))
class UButton* JoinButton;
UPROPERTY(meta = (BindWidget))
class UTextBlock* ServerNameText;
bool Initialize() override;
void SetInterface(ServerRowInterface* Interface);
void SetServer(const FString& Name, const FString& Address);
UFUNCTION()
void OnJoinClicked();
};
Then in my MainMenu.cpp I have a public function to add servers, and another to reset.
void UMainMenu::SearchClearResults()
{
SearchList->ClearChildren();
}
void UMainMenu::SearchAddServer(const FString& name, const FString& address)
{
auto row = CreateWidget<UServerRow>(GetWorld(), ServerRowClass);
row->SetInterface(this);
SearchList->AddChild(row);
row->SetServer(name, address);
}
void UMainMenu::ServerRowJoin(const FString &address)
{
UE_LOG(LogShippy, Log, TEXT("UMainMenu::ServerRowJoin: %s"), *address);
Interface->MainMenuJoinGame(address);
}
The Interface->MainMenuJoinGame(address)
line is the same one that was used when typing an IP address.
Using this method, GameInstance only knows about MainMenu. MainMenu only knows about MainMenuInterface and ServerRows, and ServerRow only knows about ServerRowInterface.
I like doing the challenges, because then I can see how others approach the problem. It’s neat to see how you created a list control, and I used ugly buttons.