WIP: Boostrapping NetSlime
- Just a old name for a set of changes to make the game framework hardened for multiplayer as well as some ease of use functionality.
This commit is contained in:
@ -18,6 +18,7 @@ using namespace gen;
|
||||
#include "GasaGen_ChangeBPActionMenu.cpp"
|
||||
#include "GasaGen_DevOptionsCache.cpp"
|
||||
#include "GasaGen_HostWidgetController.cpp"
|
||||
#include "GasaGen_NetSlime.cpp"
|
||||
|
||||
int gen_main()
|
||||
{
|
||||
@ -80,6 +81,7 @@ int gen_main()
|
||||
gen_UGasaAttributeSet();
|
||||
gen_FGasaDevOptionsCache();
|
||||
gen_UHostWidgetController();
|
||||
// gen_netslime_interfaces();
|
||||
|
||||
// One offs
|
||||
if (0)
|
||||
|
@ -13,6 +13,9 @@ using namespace gen;
|
||||
#define path_config path_source "Config/"
|
||||
#define path_module_gasa path_source "Gasa/"
|
||||
#define path_gasa_ability_system path_module_gasa "AbilitySystem/"
|
||||
#define path_gasa_actors path_module_gasa "Actors/"
|
||||
#define path_gasa_characters path_module_gasa "Characters/"
|
||||
#define path_gasa_game path_module_gasa "Game/"
|
||||
#define path_gasa_ui path_module_gasa "UI/"
|
||||
|
||||
constexpr StrC str_DECLARE_CLASS = txt("DECLARE_CLASS(");
|
||||
|
118
Project/Source/GasaGen/GasaGen_NetSlime.cpp
Normal file
118
Project/Source/GasaGen/GasaGen_NetSlime.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
// Used in the GasaGen.cpp translation unit
|
||||
#if GASA_INTELLISENSE_DIRECTIVES
|
||||
#pragma once
|
||||
#define GEN_EXPOSE_BACKEND
|
||||
#include "gen.hpp"
|
||||
#include "gen.builder.hpp"
|
||||
#include "GasaGenCommon.cpp"
|
||||
#endif
|
||||
|
||||
void gen_netslime_interface(CodeClass aclass)
|
||||
{
|
||||
CodeBody net_slime_class_interface = def_body(ECode::Class_Body);
|
||||
{
|
||||
#pragma push_macro("FORCEINLINE")
|
||||
#undef FORCEINLINE
|
||||
CodeFn DrawNetCullingSphere = parse_function( code(
|
||||
FORCEINLINE void DrawNetCullingSphere(float Duration, float Thickness) const final { Gasa::DrawNetCullingSphere(this, Duration, Thickness); }
|
||||
));
|
||||
CodeFn GetNetworkMode = parse_function( code( FORCEINLINE ENetworkMode GetNetworkMode() const { return Gasa::GetNetworkMode(this); } ));
|
||||
CodeFn IsClient = parse_function( code( FORCEINLINE bool IsClient() const { return Gasa::IsClient(this); } ));
|
||||
CodeFn IsListenServer = parse_function( code( FORCEINLINE bool IsListenServer() const { return Gasa::IsListenServer(this); } ));
|
||||
CodeFn IsNetOwner = parse_function( code( FORCEINLINE bool IsNetOwner() const { return Gasa::IsNetOwner(this); } ));
|
||||
CodeFn IsServer = parse_function( code( FORCEINLINE bool IsServer() const { return Gasa::IsServer(this); } ));
|
||||
CodeFn IsSimulatedProxy = parse_function( code( FORCEINLINE bool IsSimulatedProxy() const { return Gasa::IsSimulatedProxy(this); } ));
|
||||
CodeFn NetLog = parse_function( code(
|
||||
FORCEINLINE void NetLog( FString Message, EGasaVerbosity Verbosity = EGasaVerbosity::Log
|
||||
, FLogCategoryBase& Category = LogGasaNet
|
||||
, bool DumpStack = false
|
||||
, int32 Line = __builtin_LINE()
|
||||
, const ANSICHAR* File = __builtin_FILE()
|
||||
, const ANSICHAR* Func = __builtin_FUNCTION() )
|
||||
{
|
||||
Gasa::NetLog(this, Message, Verbosity, Category, DumpStack, Line, File, Func );
|
||||
}
|
||||
));
|
||||
CodeFn ServerAuthorized = parse_function( code( FORCEINLINE bool ServerAuthorized() const { return Gasa::ServerAuthorized(this); } ));
|
||||
#pragma pop_macro("FORCEINLINE")
|
||||
net_slime_class_interface.append(GetNetworkMode);
|
||||
net_slime_class_interface.append(IsClient);
|
||||
net_slime_class_interface.append(IsListenServer);
|
||||
net_slime_class_interface.append(IsNetOwner);
|
||||
net_slime_class_interface.append(IsServer);
|
||||
net_slime_class_interface.append(IsSimulatedProxy);
|
||||
net_slime_class_interface.append(NetLog);
|
||||
}
|
||||
|
||||
CodeBody new_body = def_body(ECode::Class_Body);
|
||||
for(Code code = aclass->Body.begin(); code != aclass->Body.end(); ++ code )
|
||||
{
|
||||
switch (code->Type)
|
||||
{
|
||||
default:
|
||||
new_body.append(code);
|
||||
break;
|
||||
|
||||
// TODO(Ed): Could this be turned into a singly? void find_and_swap_region_pragma(CodeClass, StrC region)
|
||||
// IT could return void if its assumed that the Code passed will have destructive edits to the body.
|
||||
case ECode::Preprocess_Pragma:
|
||||
{
|
||||
local_persist bool found = false;
|
||||
if (found || ! code->Content.starts_with( txt("region NetSlime")))
|
||||
{
|
||||
new_body.append(code);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add pragma
|
||||
new_body.append(code);
|
||||
++ code;
|
||||
|
||||
new_body.append( def_comment( txt("NetSlime interface is generated by GasaGen/GasaGen_NetSlime.cpp")));
|
||||
new_body.append(net_slime_class_interface);
|
||||
|
||||
while (code->Type != ECode::Preprocess_Pragma
|
||||
|| ! code->Content.starts_with(txt("endregion NetSlime")))
|
||||
++ code;
|
||||
|
||||
new_body.append(code);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
aclass->Body = new_body;
|
||||
}
|
||||
|
||||
void gen_netslime_interfaces()
|
||||
{
|
||||
Array<StringCached> header_paths = Array<StringCached>::init_reserve(GlobalAllocator, 32);
|
||||
// header_paths.append(get_cached_string(txt( path_module_gasa "GasaObject.h")));
|
||||
// header_paths.append(get_cached_string(txt( path_gasa_actors "GasaActor.h")));
|
||||
// header_paths.append(get_cached_string(txt( path_gasa_characters "GasaCharacter.h")));
|
||||
// header_paths.append(get_cached_string(txt( path_gasa_game "GasaGameMode.h")));
|
||||
// header_paths.append(get_cached_string(txt( path_gasa_game "GasaGameState.h")));
|
||||
|
||||
for (StringCached path : header_paths)
|
||||
{
|
||||
CodeBody original_header = parse_file(path);
|
||||
CodeBody header_body = def_body(ECode::Global_Body);
|
||||
for (Code code : original_header)
|
||||
{
|
||||
switch (code->Type) {
|
||||
case ECode::Class:
|
||||
{
|
||||
CodeClass aclass = code.cast<CodeClass>();
|
||||
gen_netslime_interface(aclass);
|
||||
header_body.append(aclass);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
header_body.append(code);
|
||||
}
|
||||
}
|
||||
Builder header = Builder::open(path);
|
||||
header.print(header_body);
|
||||
header.write();
|
||||
format_file(path);
|
||||
}
|
||||
}
|
@ -272,6 +272,7 @@ void def_attribute_field_value_setters( CodeBody body, Array<StringCached> prope
|
||||
|
||||
void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name, Array<StringCached> properties )
|
||||
{
|
||||
body.append(def_pragma( txt("region Attribute Setters")));
|
||||
for ( String property : properties )
|
||||
{
|
||||
CodeFn generated_get_attribute = parse_function(
|
||||
@ -288,6 +289,7 @@ void def_attribute_field_property_setter_inlines( CodeBody body, StrC class_name
|
||||
)));
|
||||
body.append( generated_get_attribute );
|
||||
}
|
||||
body.append(def_pragma( txt("endregion Attribute Setters")));
|
||||
}
|
||||
|
||||
void def_attribute_field_initers ( CodeBody body, Array<StringCached> properties )
|
||||
@ -307,11 +309,10 @@ void def_attribute_field_initers ( CodeBody body, Array<StringCached> properties
|
||||
|
||||
void impl_attribute_fields( CodeBody body, StrC class_name, Array<StringCached> properties )
|
||||
{
|
||||
body.append(fmt_newline);
|
||||
body.append(def_pragma( txt("region Rep Notifies")));
|
||||
for ( String property : properties )
|
||||
{
|
||||
body.append(fmt_newline);
|
||||
|
||||
CodeFn field_impl = parse_function( token_fmt(
|
||||
"class_name", class_name, "property", (StrC)property, "from_notice", txt("\n// From GAMEPLAYATTRIBUTE_REPNOTIFY\n"),
|
||||
stringize(
|
||||
@ -326,6 +327,7 @@ void impl_attribute_fields( CodeBody body, StrC class_name, Array<StringCached>
|
||||
body.append( field_impl );
|
||||
}
|
||||
body.append( def_pragma( txt("endregion Rep Notifies")));
|
||||
body.append(fmt_newline);
|
||||
}
|
||||
|
||||
inline
|
||||
|
@ -1610,7 +1610,7 @@ void CodeConstructor::to_string_fwd( String& result )
|
||||
if ( ast->InlineCmt )
|
||||
result.append_fmt( "; // %S\n", ast->InlineCmt->Content );
|
||||
else
|
||||
result.append( ";" );
|
||||
result.append( ";\n" );
|
||||
}
|
||||
|
||||
String CodeClass::to_string()
|
||||
@ -6278,6 +6278,16 @@ namespace parser
|
||||
move_forward();
|
||||
preprocess_content.Length++;
|
||||
|
||||
if ( current == '\r' && scanner[1] == '\n' )
|
||||
{
|
||||
move_forward();
|
||||
move_forward();
|
||||
}
|
||||
else if ( current == '\n' )
|
||||
{
|
||||
move_forward();
|
||||
}
|
||||
|
||||
Tokens.append( preprocess_content );
|
||||
return Lex_Continue; // Skip found token, its all handled here.
|
||||
}
|
||||
@ -7262,7 +7272,7 @@ namespace parser
|
||||
Tokens = Array<Token>::init_reserve( LexArena, ( LexAllocator_Size - sizeof( Array<Token>::Header ) ) / sizeof( Token ) );
|
||||
|
||||
defines_map_arena = Arena_256KB::init();
|
||||
defines = HashTable<StrC>::init( defines_map_arena );
|
||||
defines = HashTable<StrC>::init_reserve( defines_map_arena, 256 );
|
||||
}
|
||||
|
||||
internal void deinit()
|
||||
|
@ -1663,7 +1663,7 @@ struct Array
|
||||
{
|
||||
Header& header = *get_header();
|
||||
|
||||
if ( begin < 0 || end >= header.Num )
|
||||
if ( begin < 0 || end > header.Num )
|
||||
return false;
|
||||
|
||||
for ( sw idx = begin; idx < end; idx++ )
|
||||
@ -1820,13 +1820,11 @@ struct HashTable
|
||||
Type Value;
|
||||
};
|
||||
|
||||
static constexpr f32 CriticalLoadScale = 0.7f;
|
||||
|
||||
static HashTable init( AllocatorInfo allocator )
|
||||
{
|
||||
HashTable<Type> result = { { nullptr }, { nullptr } };
|
||||
|
||||
result.Hashes = Array<sw>::init( allocator );
|
||||
result.Entries = Array<Entry>::init( allocator );
|
||||
|
||||
HashTable<Type> result = init_reserve(allocator, 8);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1834,21 +1832,19 @@ struct HashTable
|
||||
{
|
||||
HashTable<Type> result = { { nullptr }, { nullptr } };
|
||||
|
||||
result.Hashes = Array<sw>::init_reserve( allocator, num );
|
||||
result.Hashes = Array<sw>::init_reserve( allocator, num );
|
||||
result.Hashes.get_header()->Num = num;
|
||||
result.Hashes.resize( num );
|
||||
result.Hashes.fill( 0, num, -1);
|
||||
|
||||
result.Entries = Array<Entry>::init_reserve( allocator, num );
|
||||
|
||||
result.Entries = Array<Entry>::init_reserve( allocator, num );
|
||||
return result;
|
||||
}
|
||||
|
||||
void clear( void )
|
||||
{
|
||||
for ( sw idx = 0; idx < Hashes.num(); idx++ )
|
||||
Hashes[idx] = -1;
|
||||
|
||||
Hashes.clear();
|
||||
Entries.clear();
|
||||
Hashes.fill( 0, Hashes.num(), -1);
|
||||
}
|
||||
|
||||
void destroy( void )
|
||||
@ -1901,32 +1897,19 @@ struct HashTable
|
||||
|
||||
void rehash( sw new_num )
|
||||
{
|
||||
sw idx;
|
||||
sw last_added_index;
|
||||
|
||||
HashTable<Type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
|
||||
|
||||
Array<sw>::Header* hash_header = new_ht.Hashes.get_header();
|
||||
|
||||
for ( idx = 0; idx < new_ht.Hashes.num(); ++idx )
|
||||
new_ht.Hashes[idx] = -1;
|
||||
|
||||
for ( idx = 0; idx < Entries.num(); ++idx )
|
||||
HashTable<Type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
|
||||
for ( sw idx = 0; idx < Entries.num(); ++idx )
|
||||
{
|
||||
Entry& entry = Entries[idx];
|
||||
|
||||
FindResult find_result;
|
||||
|
||||
if ( new_ht.Hashes.num() == 0 )
|
||||
new_ht.grow();
|
||||
|
||||
entry = Entries[idx];
|
||||
Entry& entry = Entries[idx];
|
||||
find_result = new_ht.find( entry.Key );
|
||||
last_added_index = new_ht.add_entry( entry.Key );
|
||||
|
||||
if ( find_result.PrevIndex < 0 )
|
||||
new_ht.Hashes[find_result.HashIndex] = last_added_index;
|
||||
|
||||
else
|
||||
new_ht.Entries[find_result.PrevIndex].Next = last_added_index;
|
||||
|
||||
@ -1984,11 +1967,10 @@ struct HashTable
|
||||
sw idx;
|
||||
FindResult find_result;
|
||||
|
||||
if ( Hashes.num() == 0 )
|
||||
if ( full() )
|
||||
grow();
|
||||
|
||||
find_result = find( key );
|
||||
|
||||
if ( find_result.EntryIndex >= 0 )
|
||||
{
|
||||
idx = find_result.EntryIndex;
|
||||
@ -2060,7 +2042,9 @@ protected:
|
||||
|
||||
b32 full()
|
||||
{
|
||||
return 0.75f * Hashes.num() < Entries.num();
|
||||
uw critical_load = uw( CriticalLoadScale * f32(Hashes.num()) );
|
||||
b32 result = Entries.num() > critical_load;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
@ -2096,7 +2080,7 @@ struct StrC
|
||||
#define txt( text ) \
|
||||
StrC \
|
||||
{ \
|
||||
sizeof( text ) - 1, text \
|
||||
sizeof( (text) ) - 1, (text) \
|
||||
}
|
||||
|
||||
StrC to_str( char const* str )
|
||||
|
Reference in New Issue
Block a user