Ostatnio zmodyfikowano wczoraj o godz. 21:45
tBane Temat założony przez niniejszego użytkownika |
» 2025-05-03 20:33:33 tak jest lepiej ? :-) void binary_save( std::wstring pathfile = L"world\\test_world.wrd" ) { class Writer { std::ostream & os; public: Writer( std::ostream & os ) : os( os ) { } void write_string( const std::string & str ) { uint16_t str_len = static_cast < uint16_t >( str.size() ); os.write( reinterpret_cast < const char * >( & str_len ), sizeof( str_len ) ); os.write( str.data(), str_len ); } void write_uint32( uint32_t val ) { os.write( reinterpret_cast < const char * >( & val ), sizeof( uint32_t ) ); } void write_uint8( uint8_t val ) { os.write( reinterpret_cast < const char * >( & val ), sizeof( uint8_t ) ); } void write_float( float val ) { os.write( reinterpret_cast < const char * >( & val ), sizeof( float ) ); } void write_int( int val ) { os.write( reinterpret_cast < const char * >( & val ), sizeof( int ) ); } void write_short( short val ) { os.write( reinterpret_cast < const char * >( & val ), sizeof( short ) ); } }; std::ofstream file( pathfile, std::ios::binary ); Writer writer( file ); writer.write_string( "#ResourcesBegin" ); writer.write_uint32( prefabs.size() ); for( auto & prefab: prefabs ) writer.write_string( prefab->name ); writer.write_string( "#ResourcesEnd" ); writer.write_string( "#MapBegin" ); for( auto & chunk: chunks ) { writer.write_int( chunk->coords.x ); writer.write_int( chunk->coords.y ); Terrain * ter = chunk->terrain; for( short y = 0; y < 16; y++ ) { for( short x = 0; x < 16; x++ ) { writer.write_short( ter->tiles[ y * 16 + x ] ); } } writer.write_uint32( chunk->getAllGameObjects().size() ); for( auto & object: chunk->getAllGameObjects() ) { writer.write_uint8( static_cast < uint8_t >( object->type ) ); writer.write_uint32( getPrefabID( object->name ) ); if( object->type == GameObjectType::Building ) { writer.write_short( dynamic_cast < Building * >( object )->id ); writer.write_float( object->position.x ); writer.write_float( object->position.y ); } else if( object->type == GameObjectType::Monster ) { sf::Vector2f position = dynamic_cast < Monster * >( object )->base; writer.write_float( position.x ); writer.write_float( position.y ); } else if( object->type == GameObjectType::Character ) { writer.write_float( object->position.x ); writer.write_float( object->position.y ); } else if( object->type == GameObjectType::InventoryOnMap ) { writer.write_short( dynamic_cast < InventoryOnMap * >( object )->inventory->id ); writer.write_float( object->position.x ); writer.write_float( object->position.y ); } else { writer.write_float( object->position.x ); writer.write_float( object->position.y ); } } } writer.write_string( "#MapEnd" ); file.close(); }
|
|
pekfos |
» 2025-05-03 20:41:17 Dużo lepiej. writer.write_float( object->position.x ); writer.write_float( object->position.y ); Jak masz powtarzalne struktury danych jak choćby ta pozycja, to możesz dorobić na to też metody zapisu by nie powtarzać się. Np writer.write_point( object->position );
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-05-03 20:46:46 Ok. Słuszna uwaga. Dzięki :-) edit// Rozmiar pliku z ponad 1MB spadł do 900kb i do tego szybciej wczutuje taką mapę o około 2s :-) Oto kompletny kod: void binary_save( std::wstring pathfile = L"world\\test_world.wrd" ) { class Writer { std::ostream & os; public: Writer( std::ostream & os ) : os( os ) { } void write_string( const std::string & str ) { uint16_t str_len = static_cast < uint16_t >( str.size() ); os.write( reinterpret_cast < const char * >( & str_len ), sizeof( str_len ) ); os.write( str.data(), str_len ); } void write_uint32( uint32_t val ) { os.write( reinterpret_cast < const char * >( & val ), sizeof( uint32_t ) ); } void write_uint16( uint16_t val ) { os.write( reinterpret_cast < const char * >( & val ), sizeof( uint16_t ) ); } void write_uint8( uint8_t val ) { os.write( reinterpret_cast < const char * >( & val ), sizeof( uint8_t ) ); } void write_float( float val ) { os.write( reinterpret_cast < const char * >( & val ), sizeof( float ) ); } void write_int( int val ) { os.write( reinterpret_cast < const char * >( & val ), sizeof( int ) ); } void write_short( short val ) { os.write( reinterpret_cast < const char * >( & val ), sizeof( short ) ); } void write_Vector2f( sf::Vector2f val ) { os.write( reinterpret_cast < const char * >( & val.x ), sizeof( float ) ); os.write( reinterpret_cast < const char * >( & val.y ), sizeof( float ) ); } void write_Vector2i( sf::Vector2i val ) { os.write( reinterpret_cast < const char * >( & val.x ), sizeof( int ) ); os.write( reinterpret_cast < const char * >( & val.y ), sizeof( int ) ); } }; std::ofstream file( pathfile, std::ios::binary ); Writer writer( file ); writer.write_string( "#ResourcesBegin" ); writer.write_uint32( prefabs.size() ); for( auto & prefab: prefabs ) writer.write_string( prefab->name ); writer.write_string( "#ResourcesEnd" ); writer.write_string( "#MapBegin" ); for( auto & chunk: chunks ) { writer.write_int( chunk->coords.x ); writer.write_int( chunk->coords.y ); Terrain * ter = chunk->terrain; for( short y = 0; y < 16; y++ ) { for( short x = 0; x < 16; x++ ) { writer.write_short( ter->tiles[ y * 16 + x ] ); } } writer.write_uint32( chunk->getAllGameObjects().size() ); for( auto & object: chunk->getAllGameObjects() ) { writer.write_uint16( static_cast < uint16_t >( object->type ) ); if( object->type == GameObjectType::Building ) { writer.write_short( dynamic_cast < Building * >( object )->id ); writer.write_Vector2f( object->position ); } else if( object->type == GameObjectType::Monster ) { writer.write_uint32( getPrefabID( object->name ) ); sf::Vector2f position = dynamic_cast < Monster * >( object )->base; writer.write_Vector2f( object->position ); } else if( object->type == GameObjectType::Character ) { writer.write_uint32( getPrefabID( object->name ) ); writer.write_Vector2f( object->position ); } else if( object->type == GameObjectType::InventoryOnMap ) { writer.write_uint32( getPrefabID( object->name ) ); writer.write_short( dynamic_cast < InventoryOnMap * >( object )->inventory->id ); writer.write_Vector2f( object->position ); } else { writer.write_uint32( getPrefabID( object->name ) ); writer.write_Vector2f( object->position ); } } } writer.write_string( "#MapEnd" ); for( auto & chunk: chunks ) { for( auto & building: chunk->_buildings ) { writer.write_string( "#BuildingBegin" ); writer.write_short( building->id ); writer.write_string( building->name ); writer.write_Vector2i( building->size ); writer.write_string( building->_door->name ); writer.write_string( building->texture_top_walls->name ); writer.write_string( building->texture_center_walls->name ); writer.write_string( building->texture_bottom_walls->name ); writer.write_string( building->texture_windows->name ); writer.write_short( building->floors->width ); writer.write_short( building->floors->height ); for( short y = 0; y < building->floors->height; y++ ) { for( short x = 0; x < building->floors->width; x++ ) { writer.write_short( building->floors->floors[ y * building->floors->width + x ] ); } } std::vector < GameObject * > building_objects = building->getAllGameObjects(); writer.write_uint32( building_objects.size() ); for( auto & object: building_objects ) { writer.write_uint16( static_cast < uint16_t >( object->type ) ); writer.write_uint32( getPrefabID( object->name ) ); sf::Vector2f position; position.x = int( object->position.x ) - int( building->position.x ) + building->size.x / 2 * 16; position.y = int( object->position.y ) - int( building->position.y ) + building->size.y * 16; writer.write_Vector2f( position ); } writer.write_string( "#BuildingEnd" ); } } file.close(); }
|
|
pekfos |
» 2025-05-04 21:28:22 Rozmiar pliku z ponad 1MB spadł do 900kb i do tego szybciej wczutuje taką mapę o około 2s :-) Na jakim kalkulatorze to odpalasz że ta zmiana dała 2s przyspieszenia? Na pewno te wczytywanie się wykonuje 1 raz? |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-05-04 21:35:32 Normalnie wczytywanie trwa 7s, przyspieszenie 2s to chyba duża różnica. Procesor Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz 2.90 GHz Zainstalowana pamięć RAM 32,0 GB Karta graficzna NVIDIA GeForce RTX 2070 (8 GB) void binary_load( std::wstring pathfile = L"world\\world.wrd" ) { class Reader { std::istream & is; public: Reader( std::istream & is ) : is( is ) { } std::string read_string() { uint16_t len; is.read( reinterpret_cast < char * >( & len ), sizeof( uint16_t ) ); std::string str( len, '\0' ); is.read( & str[ 0 ], len ); return str; } uint32_t read_uint32() { uint32_t value; is.read( reinterpret_cast < char * >( & value ), sizeof( uint32_t ) ); return value; } uint16_t read_uint16() { uint16_t value; is.read( reinterpret_cast < char * >( & value ), sizeof( uint16_t ) ); return value; } uint8_t read_uint8() { uint8_t value; is.read( reinterpret_cast < char * >( & value ), sizeof( uint8_t ) ); return value; } float read_float() { float value; is.read( reinterpret_cast < char * >( & value ), sizeof( float ) ); return value; } int read_int() { int value; is.read( reinterpret_cast < char * >( & value ), sizeof( int ) ); return value; } short read_short() { short value; is.read( reinterpret_cast < char * >( & value ), sizeof( short ) ); return value; } sf::Vector2f read_Vector2f() { sf::Vector2f value; is.read( reinterpret_cast < char * >( & value.x ), sizeof( float ) ); is.read( reinterpret_cast < char * >( & value.y ), sizeof( float ) ); return value; } sf::Vector2i read_Vector2i() { sf::Vector2i value; is.read( reinterpret_cast < char * >( & value.x ), sizeof( int ) ); is.read( reinterpret_cast < char * >( & value.y ), sizeof( int ) ); return value; } }; std::ifstream file( pathfile, std::ios::binary ); Reader reader( file ); std::vector < std::string > pathfiles; while( file && !file.eof() ) { std::string phrase; try { phrase = reader.read_string(); } catch( ... ) { break; } if( phrase == "#Resources" ) { uint32_t resources_count = reader.read_uint32(); for( uint32_t i = 0; i < resources_count; i++ ) { pathfiles.push_back( reader.read_string() ); } } else if( phrase == "#Map" ) { for( auto & chunk: chunks ) delete chunk; chunks.clear(); clearAllMainListsOfGameObjects(); this->width = reader.read_uint8(); this->height = reader.read_uint8(); for( short i = 0; i < width * height; i++ ) { sf::Vector2i coords = reader.read_Vector2i(); Chunk * ch = new Chunk( coords.x, coords.y ); for( short y = 0; y < 16; y++ ) { for( short x = 0; x < 16; x++ ) { short t_val = reader.read_short(); ch->terrain->edit( x, y, t_val ); ( t_val == 0 ||( t_val >= countOfBasicTerrain && t_val < countOfBasicTerrain + 16 ) ) ? ch->water->edit( x, y, t_val ) : ch->water->edit( x, y, - 1 ); } } uint32_t objects_count = reader.read_uint32(); for( uint32_t i = 0; i < objects_count; i++ ) { uint16_t objectType = reader.read_uint16(); GameObject * object = nullptr; if( objectType == static_cast < uint16_t >( GameObjectType::Building ) ) { object = new Building( reader.read_short() ); } else if( objectType == static_cast < uint16_t >( GameObjectType::Character ) ) { GameObject * prefab = getPrefab( pathfiles[ reader.read_uint32() ] ); object = getNewGameObject( prefab ); } else if( objectType == static_cast < uint16_t >( GameObjectType::InventoryOnMap ) ) { Inventory * in = new Inventory( reader.read_short() ); object = new InventoryOnMap( in ); } else { GameObject * prefab = getPrefab( pathfiles[ reader.read_uint32() ] ); object = getNewGameObject( prefab ); } if( object != nullptr ) { object->setPosition( reader.read_Vector2f() ); ch->addGameObject( object ); } } chunks.push_back( ch ); } } else if( phrase == "#Building" ) { Building * building = getBuilding( reader.read_short() ); building->name = reader.read_string(); building->size = reader.read_Vector2i(); building->_door = dynamic_cast < Door * >( getNewGameObject( getPrefab( reader.read_string() ) ) ); building->_door->setPosition( building->position ); building->texture_top_walls = getSingleTexture( reader.read_string() ); building->texture_center_walls = getSingleTexture( reader.read_string() ); building->texture_bottom_walls = getSingleTexture( reader.read_string() ); building->texture_windows = getSingleTexture( reader.read_string() ); short floor_w = reader.read_short(); short floor_h = reader.read_short(); if( building->floors != nullptr ) delete building->floors; building->floors = new Floors( building->position.x / 16 - building->size.x / 2, building->position.y / 16 - building->size.y, building->size.x, building->size.y ); for( short y = 0; y < floor_h; y++ ) { for( short x = 0; x < floor_w; x++ ) { building->floors->edit( x, y, reader.read_short() ); } } uint32_t objects_count = reader.read_uint32(); for( uint32_t i = 0; i < objects_count; i++ ) { uint16_t objectType = reader.read_uint16(); GameObject * prefab = getPrefab( pathfiles[ reader.read_uint32() ] ); if( prefab != nullptr ) { GameObject * object = getNewGameObject( prefab ); sf::Vector2f position = reader.read_Vector2f(); position.x = position.x -( building->size.x * 16 / 2 ) + building->position.x; position.y = position.y -( building->size.y * 16 ) + building->position.y; object->setPosition( position ); building->addGameObject( object ); } } building->loadTexture(); } else if( phrase == "#Inventory" ) { clearInventories(); Inventory * inventory = new Inventory( reader.read_short() ); uint32_t items_count = reader.read_uint32(); for( uint32_t i = 0; i < items_count; i++ ) { uint32_t id = reader.read_uint32(); Item * item = getItem( pathfiles[ id ] ); uint16_t count = reader.read_uint16(); inventory->addItem( item, count ); } std::cout << "#Inventory: " << inventory->id << "\n"; for( short i = 0; i < inventory->items.size(); i++ ) { std::cout << inventory->items[ i ]->name << " " << inventory->counts[ i ] << "\n"; } } } file.close(); }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-05-04 21:45:05 mój błąd - odpalałem w trybie debug... w release jest poniżej sekundy ... |
|
1 « 2 » |