Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 90 additions & 8 deletions crates/codegen/src/unrealcpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,10 +609,10 @@ impl Lang for UnrealCpp<'_> {
// First, collect and generate all optional types
let optional_types = collect_optional_types(module);
for optional_name in optional_types {
let module_name_pascal = self.module_name.to_case(Case::Pascal);
let filename = format!(
"Source/{module_name_pascal}/Public/ModuleBindings/Optionals/{module_name_pascal}{optional_name}.g.h"
);
let module_name = &self.module_name;
let module_name_pascal = module_name.to_case(Case::Pascal);
let filename =
format!("Source/{module_name}/Public/ModuleBindings/Optionals/{module_name_pascal}{optional_name}.g.h");

let content = generate_optional_type(&optional_name, module, &self.get_api_macro(), self.module_name);
files.push(OutputFile {
Expand Down Expand Up @@ -1033,7 +1033,10 @@ fn generate_context_structs(output: &mut UnrealCppAutogen, module: &ModuleDef, a
writeln!(output, "{{");
writeln!(output, "\tGENERATED_BODY()");
writeln!(output);
writeln!(output, "\tFContextBase() = default;");
writeln!(
output,
"\tFContextBase() : Db(nullptr), Reducers(nullptr), SetReducerFlags(nullptr), Conn(nullptr) {{}};"
);
writeln!(output, "\tFContextBase(UDbConnection* InConn);");
writeln!(output);
writeln!(output, "\tUPROPERTY(BlueprintReadOnly, Category = \"SpacetimeDB\")");
Expand Down Expand Up @@ -1061,6 +1064,44 @@ fn generate_context_structs(output: &mut UnrealCppAutogen, module: &ModuleDef, a
writeln!(output, "}};");
writeln!(output);

// BPLib for FContextBase - Needed to allow inheritance in Blueprint
writeln!(output, "UCLASS()");
writeln!(
output,
"class {api_macro} UContextBaseBpLib : public UBlueprintFunctionLibrary"
);
writeln!(output, "{{");
writeln!(output, "\tGENERATED_BODY()");
writeln!(output);
writeln!(output, "private:");

writeln!(output, "\tUFUNCTION(BlueprintPure, Category=\"SpacetimeDB\")");
writeln!(
output,
"\tstatic URemoteTables* GetDb(const FContextBase& Ctx) {{ return Ctx.Db; }}"
);
writeln!(output);
writeln!(output, "\tUFUNCTION(BlueprintPure, Category=\"SpacetimeDB\")");
writeln!(
output,
"\tstatic URemoteReducers* GetReducers(const FContextBase& Ctx) {{ return Ctx.Reducers; }}"
);
writeln!(output);
writeln!(output, "\tUFUNCTION(BlueprintPure, Category=\"SpacetimeDB\")");
writeln!(
output,
"\tstatic USetReducerFlags* GetSetReducerFlags(const FContextBase& Ctx) {{ return Ctx.SetReducerFlags; }}"
);
writeln!(output);
writeln!(output, "\tUFUNCTION(BlueprintPure, Category=\"SpacetimeDB\")");
writeln!(
output,
"\tstatic bool IsActive(const FContextBase& Ctx) {{ return Ctx.IsActive(); }}"
);

writeln!(output, "}};");
writeln!(output);

// ---------------------------------------------------------------------
// Per-module typed Reducer tagged union + typed Event
// ---------------------------------------------------------------------
Expand Down Expand Up @@ -1091,7 +1132,7 @@ fn generate_context_structs(output: &mut UnrealCppAutogen, module: &ModuleDef, a
writeln!(output);
writeln!(output, "public:");
writeln!(output, " UPROPERTY(BlueprintReadOnly, Category = \"SpacetimeDB\")");
writeln!(output, " EReducerTag Tag;");
writeln!(output, " EReducerTag Tag = static_cast<EReducerTag>(0);");
writeln!(output);
write!(output, " TVariant<");
{
Expand Down Expand Up @@ -3485,7 +3526,8 @@ fn autogen_cpp_struct(
for (orig_name, ty) in product_type.into_iter() {
let field_name = orig_name.deref().to_case(Case::Pascal);
let ty_str = cpp_ty_fmt_with_module(module, ty, module_name).to_string();
let field_decl = format!("{ty_str} {field_name}");
let init_str = cpp_ty_init_fmt_impl(ty);
let field_decl = format!("{ty_str} {field_name}{init_str}");

// Check if the type is blueprintable
if is_blueprintable(module, ty) {
Expand Down Expand Up @@ -3818,7 +3860,10 @@ fn autogen_cpp_sum(

writeln!(output);

writeln!(output, " UPROPERTY(BlueprintReadOnly)\n E{name}Tag Tag;\n");
writeln!(
output,
" UPROPERTY(BlueprintReadOnly)\n E{name}Tag Tag = static_cast<E{name}Tag>(0);\n"
);

/* 4a. Static factories per variant -------------------------------- */
for (variant_name, variant_type) in &sum_type.variants {
Expand Down Expand Up @@ -4157,6 +4202,43 @@ fn cpp_ty_fmt_impl<'a>(
})
}

// For UPROPERTY() Unreal expects initialization values for certain types
// (e.g. bools default to true if not explicitly initialized to false).
fn cpp_ty_init_fmt_impl<'a>(ty: &'a AlgebraicTypeUse) -> impl fmt::Display + 'a {
fmt_fn(move |f| match ty {
AlgebraicTypeUse::Primitive(p) => f.write_str(match p {
PrimitiveType::Bool => " = false",
PrimitiveType::I8 => " = 0",
PrimitiveType::U8 => " = 0",
PrimitiveType::I16 => " = 0",
PrimitiveType::U16 => " = 0",
PrimitiveType::I32 => " = 0",
PrimitiveType::U32 => " = 0",
PrimitiveType::I64 => " = 0",
PrimitiveType::U64 => " = 0",
PrimitiveType::F32 => " = 0.0f",
PrimitiveType::F64 => " = 0.0",
PrimitiveType::I128 => "",
PrimitiveType::U128 => "",
PrimitiveType::I256 => "",
PrimitiveType::U256 => "",
}),
AlgebraicTypeUse::Array(_elem) => f.write_str(""),
AlgebraicTypeUse::String => f.write_str(""),
AlgebraicTypeUse::Identity => f.write_str(""),
AlgebraicTypeUse::ConnectionId => f.write_str(""),
AlgebraicTypeUse::Timestamp => f.write_str(""),
AlgebraicTypeUse::TimeDuration => f.write_str(""),
AlgebraicTypeUse::ScheduleAt => f.write_str(""),
AlgebraicTypeUse::Unit => f.write_str(""),
// --------- references to user-defined types ---------
AlgebraicTypeUse::Ref(_r) => f.write_str(""),
// Options use the generated optional types
AlgebraicTypeUse::Option(_inner) => f.write_str(""),
AlgebraicTypeUse::Never => unreachable!("never type"),
})
}

// Given an `AlgebraicTypeUse`, add every referenced type’s generated
// header name (`"<FTypeName>.g.h"`) into `out` (a `HashSet` avoids dups).
fn collect_includes_for_type(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void ULeaderboardWidget::CollectPlayers(TArray<FLeaderboardEntry>& Out) const
// 4) Keep top 10
if (Out.Num() > 10)
{
Out.SetNum(10, /*bAllowShrinking*/ false);
Out.SetNum(10, EAllowShrinking::No);
}

// 5) Append local player if not already present and has Mass > 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
#include "BSATN/UEBSATNHelpers.h"
#include "ModuleBindings/Tables/EntityTable.g.h"
#include "ModuleBindings/Tables/MoveAllPlayersTimerTable.g.h"
#include "ModuleBindings/Tables/CircleDecayTimerTable.g.h"
#include "ModuleBindings/Tables/EntityTable.g.h"
#include "ModuleBindings/Tables/FoodTable.g.h"
#include "ModuleBindings/Tables/CircleRecombineTimerTable.g.h"
#include "ModuleBindings/Tables/ConfigTable.g.h"
#include "ModuleBindings/Tables/ConsumeEntityTimerTable.g.h"
#include "ModuleBindings/Tables/PlayerTable.g.h"
#include "ModuleBindings/Tables/ConfigTable.g.h"
#include "ModuleBindings/Tables/FoodTable.g.h"
#include "ModuleBindings/Tables/CircleTable.g.h"
#include "ModuleBindings/Tables/PlayerTable.g.h"
#include "ModuleBindings/Tables/ConsumeEntityTimerTable.g.h"
#include "ModuleBindings/Tables/SpawnFoodTimerTable.g.h"
#include "ModuleBindings/Tables/CircleDecayTimerTable.g.h"
#include "ModuleBindings/Tables/CircleRecombineTimerTable.g.h"
#include "ModuleBindings/Tables/EntityTable.g.h"
#include "ModuleBindings/Tables/CircleTable.g.h"
#include "ModuleBindings/Tables/PlayerTable.g.h"

static FReducer DecodeReducer(const FReducerEvent& Event)
{
Expand Down Expand Up @@ -110,17 +110,17 @@ UDbConnection::UDbConnection(const FObjectInitializer& ObjectInitializer) : Supe

RegisterTable<FEntityType, UEntityTable, FEventContext>(TEXT("logged_out_entity"), Db->LoggedOutEntity);
RegisterTable<FMoveAllPlayersTimerType, UMoveAllPlayersTimerTable, FEventContext>(TEXT("move_all_players_timer"), Db->MoveAllPlayersTimer);
RegisterTable<FCircleDecayTimerType, UCircleDecayTimerTable, FEventContext>(TEXT("circle_decay_timer"), Db->CircleDecayTimer);
RegisterTable<FEntityType, UEntityTable, FEventContext>(TEXT("entity"), Db->Entity);
RegisterTable<FConsumeEntityTimerType, UConsumeEntityTimerTable, FEventContext>(TEXT("consume_entity_timer"), Db->ConsumeEntityTimer);
RegisterTable<FPlayerType, UPlayerTable, FEventContext>(TEXT("player"), Db->Player);
RegisterTable<FConfigType, UConfigTable, FEventContext>(TEXT("config"), Db->Config);
RegisterTable<FFoodType, UFoodTable, FEventContext>(TEXT("food"), Db->Food);
RegisterTable<FCircleType, UCircleTable, FEventContext>(TEXT("circle"), Db->Circle);
RegisterTable<FSpawnFoodTimerType, USpawnFoodTimerTable, FEventContext>(TEXT("spawn_food_timer"), Db->SpawnFoodTimer);
RegisterTable<FCircleDecayTimerType, UCircleDecayTimerTable, FEventContext>(TEXT("circle_decay_timer"), Db->CircleDecayTimer);
RegisterTable<FCircleRecombineTimerType, UCircleRecombineTimerTable, FEventContext>(TEXT("circle_recombine_timer"), Db->CircleRecombineTimer);
RegisterTable<FConfigType, UConfigTable, FEventContext>(TEXT("config"), Db->Config);
RegisterTable<FPlayerType, UPlayerTable, FEventContext>(TEXT("logged_out_player"), Db->LoggedOutPlayer);
RegisterTable<FEntityType, UEntityTable, FEventContext>(TEXT("entity"), Db->Entity);
RegisterTable<FCircleType, UCircleTable, FEventContext>(TEXT("logged_out_circle"), Db->LoggedOutCircle);
RegisterTable<FPlayerType, UPlayerTable, FEventContext>(TEXT("player"), Db->Player);
RegisterTable<FConsumeEntityTimerType, UConsumeEntityTimerTable, FEventContext>(TEXT("consume_entity_timer"), Db->ConsumeEntityTimer);
RegisterTable<FSpawnFoodTimerType, USpawnFoodTimerTable, FEventContext>(TEXT("spawn_food_timer"), Db->SpawnFoodTimer);
RegisterTable<FCircleType, UCircleTable, FEventContext>(TEXT("circle"), Db->Circle);
RegisterTable<FPlayerType, UPlayerTable, FEventContext>(TEXT("logged_out_player"), Db->LoggedOutPlayer);
}

FContextBase::FContextBase(UDbConnection* InConn)
Expand Down Expand Up @@ -157,33 +157,33 @@ void URemoteTables::Initialize()
/** Creating tables */
LoggedOutEntity = NewObject<UEntityTable>(this);
MoveAllPlayersTimer = NewObject<UMoveAllPlayersTimerTable>(this);
CircleDecayTimer = NewObject<UCircleDecayTimerTable>(this);
Entity = NewObject<UEntityTable>(this);
ConsumeEntityTimer = NewObject<UConsumeEntityTimerTable>(this);
Player = NewObject<UPlayerTable>(this);
Config = NewObject<UConfigTable>(this);
Food = NewObject<UFoodTable>(this);
Circle = NewObject<UCircleTable>(this);
SpawnFoodTimer = NewObject<USpawnFoodTimerTable>(this);
CircleDecayTimer = NewObject<UCircleDecayTimerTable>(this);
CircleRecombineTimer = NewObject<UCircleRecombineTimerTable>(this);
Config = NewObject<UConfigTable>(this);
LoggedOutPlayer = NewObject<UPlayerTable>(this);
Entity = NewObject<UEntityTable>(this);
LoggedOutCircle = NewObject<UCircleTable>(this);
Player = NewObject<UPlayerTable>(this);
ConsumeEntityTimer = NewObject<UConsumeEntityTimerTable>(this);
SpawnFoodTimer = NewObject<USpawnFoodTimerTable>(this);
Circle = NewObject<UCircleTable>(this);
LoggedOutPlayer = NewObject<UPlayerTable>(this);
/**/

/** Initialization */
LoggedOutEntity->PostInitialize();
MoveAllPlayersTimer->PostInitialize();
CircleDecayTimer->PostInitialize();
Entity->PostInitialize();
ConsumeEntityTimer->PostInitialize();
Player->PostInitialize();
Config->PostInitialize();
Food->PostInitialize();
Circle->PostInitialize();
SpawnFoodTimer->PostInitialize();
CircleDecayTimer->PostInitialize();
CircleRecombineTimer->PostInitialize();
Config->PostInitialize();
LoggedOutPlayer->PostInitialize();
Entity->PostInitialize();
LoggedOutCircle->PostInitialize();
Player->PostInitialize();
ConsumeEntityTimer->PostInitialize();
SpawnFoodTimer->PostInitialize();
Circle->PostInitialize();
LoggedOutPlayer->PostInitialize();
/**/
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.

// This was generated using spacetimedb cli version 1.4.0 (commit dc59211c1453848981aeb2efce2249c9a07947b2).
// This was generated using spacetimedb cli version 1.4.0 (commit 26e99fe5e5b8848cccde94ec4c1a56148977dfa1).

#pragma once
#include "CoreMinimal.h"
Expand Down Expand Up @@ -79,7 +79,7 @@ struct CLIENT_UNREAL_API FContextBase
{
GENERATED_BODY()

FContextBase() = default;
FContextBase() : Db(nullptr), Reducers(nullptr), SetReducerFlags(nullptr), Conn(nullptr) {};
FContextBase(UDbConnection* InConn);

UPROPERTY(BlueprintReadOnly, Category = "SpacetimeDB")
Expand All @@ -103,6 +103,25 @@ struct CLIENT_UNREAL_API FContextBase

};

UCLASS()
class CLIENT_UNREAL_API UContextBaseBpLib : public UBlueprintFunctionLibrary
{
GENERATED_BODY()

private:
UFUNCTION(BlueprintPure, Category="SpacetimeDB")
static URemoteTables* GetDb(const FContextBase& Ctx) { return Ctx.Db; }

UFUNCTION(BlueprintPure, Category="SpacetimeDB")
static URemoteReducers* GetReducers(const FContextBase& Ctx) { return Ctx.Reducers; }

UFUNCTION(BlueprintPure, Category="SpacetimeDB")
static USetReducerFlags* GetSetReducerFlags(const FContextBase& Ctx) { return Ctx.SetReducerFlags; }

UFUNCTION(BlueprintPure, Category="SpacetimeDB")
static bool IsActive(const FContextBase& Ctx) { return Ctx.IsActive(); }
};

UENUM(BlueprintType, Category = "SpacetimeDB")
enum class EReducerTag : uint8
{
Expand All @@ -127,7 +146,7 @@ struct CLIENT_UNREAL_API FReducer

public:
UPROPERTY(BlueprintReadOnly, Category = "SpacetimeDB")
EReducerTag Tag;
EReducerTag Tag = static_cast<EReducerTag>(0);

TVariant<FCircleDecayArgs, FCircleRecombineArgs, FConnectArgs, FConsumeEntityArgs, FDisconnectArgs, FEnterGameArgs, FMoveAllPlayersArgs, FPlayerSplitArgs, FRespawnArgs, FSpawnFoodArgs, FSuicideArgs, FUpdatePlayerInputArgs> Data;

Expand Down Expand Up @@ -899,37 +918,37 @@ class CLIENT_UNREAL_API URemoteTables : public UObject
UMoveAllPlayersTimerTable* MoveAllPlayersTimer;

UPROPERTY(BlueprintReadOnly, Category="SpacetimeDB")
UCircleDecayTimerTable* CircleDecayTimer;
UConsumeEntityTimerTable* ConsumeEntityTimer;

UPROPERTY(BlueprintReadOnly, Category="SpacetimeDB")
UEntityTable* Entity;
UPlayerTable* Player;

UPROPERTY(BlueprintReadOnly, Category="SpacetimeDB")
UFoodTable* Food;
UConfigTable* Config;

UPROPERTY(BlueprintReadOnly, Category="SpacetimeDB")
UCircleRecombineTimerTable* CircleRecombineTimer;
UFoodTable* Food;

UPROPERTY(BlueprintReadOnly, Category="SpacetimeDB")
UConfigTable* Config;
UCircleTable* Circle;

UPROPERTY(BlueprintReadOnly, Category="SpacetimeDB")
UPlayerTable* LoggedOutPlayer;
USpawnFoodTimerTable* SpawnFoodTimer;

UPROPERTY(BlueprintReadOnly, Category="SpacetimeDB")
UCircleTable* LoggedOutCircle;
UCircleDecayTimerTable* CircleDecayTimer;

UPROPERTY(BlueprintReadOnly, Category="SpacetimeDB")
UPlayerTable* Player;
UCircleRecombineTimerTable* CircleRecombineTimer;

UPROPERTY(BlueprintReadOnly, Category="SpacetimeDB")
UConsumeEntityTimerTable* ConsumeEntityTimer;
UEntityTable* Entity;

UPROPERTY(BlueprintReadOnly, Category="SpacetimeDB")
USpawnFoodTimerTable* SpawnFoodTimer;
UCircleTable* LoggedOutCircle;

UPROPERTY(BlueprintReadOnly, Category="SpacetimeDB")
UCircleTable* Circle;
UPlayerTable* LoggedOutPlayer;

};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class CLIENT_UNREAL_API UCircleTable : public URemoteTable

void PostInitialize();

/** Update function for circle table*/
/** Update function for logged_out_circle table*/
FTableAppliedDiff<FCircleType> Update(TArray<FWithBsatn<FCircleType>> InsertsRef, TArray<FWithBsatn<FCircleType>> DeletesRef);

/** Number of subscribed rows currently in the cache */
Expand Down Expand Up @@ -135,7 +135,7 @@ class CLIENT_UNREAL_API UCircleTable : public URemoteTable
FOnCircleDelete OnDelete;

private:
const FString TableName = TEXT("circle");
const FString TableName = TEXT("logged_out_circle");

TSharedPtr<UClientCache<FCircleType>> Data;
};
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class CLIENT_UNREAL_API UPlayerTable : public URemoteTable

void PostInitialize();

/** Update function for player table*/
/** Update function for logged_out_player table*/
FTableAppliedDiff<FPlayerType> Update(TArray<FWithBsatn<FPlayerType>> InsertsRef, TArray<FWithBsatn<FPlayerType>> DeletesRef);

/** Number of subscribed rows currently in the cache */
Expand Down Expand Up @@ -138,7 +138,7 @@ class CLIENT_UNREAL_API UPlayerTable : public URemoteTable
FOnPlayerDelete OnDelete;

private:
const FString TableName = TEXT("player");
const FString TableName = TEXT("logged_out_player");

TSharedPtr<UClientCache<FPlayerType>> Data;
};
Loading
Loading