Documentation

Advanced Resources

Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ΅ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ рСсурсами критичСски Π²Π°ΠΆΠ½ΠΎ для ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈΠ³Ρ€Ρ‹. Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Π΅ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с рСсурсами Π² Wudgine.

Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅

Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ рСсурсами β€” ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Ρ… аспСктов Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΈΠ³Ρ€, особСнно для ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ² с большим количСством ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°. Wudgine прСдоставляСт Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π½Ρ‹Π΅ возмоТности для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ, хранСния ΠΈ использования ΠΈΠ³Ρ€ΠΎΠ²Ρ‹Ρ… рСсурсов.

Асинхронная Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° рСсурсов

Асинхронная Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° позволяСт Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ рСсурсы Π² Ρ„ΠΎΠ½ΠΎΠ²ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅, Π½Π΅ блокируя основной ΠΏΠΎΡ‚ΠΎΠΊ ΠΈΠ³Ρ€Ρ‹.

БистСма асинхронной Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ

// ИспользованиС асинхронной Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ тСкстур
Wudgine::Resources::TextureHandle textureHandle = 
    resourceManager.LoadTextureAsync("textures/large_terrain.png", 
                                    [](Wudgine::Resources::TextureHandle handle) {
    // Π­Ρ‚ΠΎΡ‚ ΠΊΠΎΠ΄ выполнится послС Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ тСкстуры
    std::cout << "ВСкстура Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Π°!" << std::endl;
});

// ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° статуса Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
if (resourceManager.IsLoading(textureHandle)) {
    // РСсурс всС Π΅Ρ‰Π΅ загруТаСтся
    float progress = resourceManager.GetLoadingProgress(textureHandle);
    std::cout << "ΠŸΡ€ΠΎΠ³Ρ€Π΅ΡΡ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ: " << progress * 100.0f << "%" << std::endl;
} else {
    // РСсурс Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½ ΠΈ Π³ΠΎΡ‚ΠΎΠ² ΠΊ использованию
    auto texture = resourceManager.Get<Wudgine::Resources::Texture>(textureHandle);
}

Π“Ρ€ΡƒΠΏΠΏΡ‹ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ

// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π³Ρ€ΡƒΠΏΠΏΡ‹ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
Wudgine::Resources::LoadGroup levelResources;

// Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ рСсурсов Π² Π³Ρ€ΡƒΠΏΠΏΡƒ
levelResources.AddTexture("textures/terrain.png");
levelResources.AddTexture("textures/buildings.png");
levelResources.AddModel("models/player.obj");
levelResources.AddSound("sounds/ambient.wav");

// Запуск асинхронной Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π³Ρ€ΡƒΠΏΠΏΡ‹
resourceManager.LoadGroupAsync(levelResources, [](Wudgine::Resources::LoadGroup& group) {
    // Π­Ρ‚ΠΎΡ‚ ΠΊΠΎΠ΄ выполнится послС Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ всСх рСсурсов Π³Ρ€ΡƒΠΏΠΏΡ‹
    std::cout << "ВсС рСсурсы уровня Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Ρ‹!" << std::endl;
});

// ΠžΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΠ΅ прогрСсса Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π³Ρ€ΡƒΠΏΠΏΡ‹
float groupProgress = resourceManager.GetGroupLoadingProgress(levelResources);

ΠŸΠΎΡ‚ΠΎΠΊΠΎΠ²Π°Ρ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ°

ΠŸΠΎΡ‚ΠΎΠΊΠΎΠ²Π°Ρ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° позволяСт Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ΠΈ Π²Ρ‹Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ рСсурсы Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π² зависимости ΠΎΡ‚ потрСбностСй ΠΈΠ³Ρ€Ρ‹.

БистСма ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΉ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ

// Настройка систСмы ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΉ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
Wudgine::Resources::StreamingSystem streamingSystem;
streamingSystem.SetMaxMemoryUsage(1024 * 1024 * 1024); // 1 Π“Π‘
streamingSystem.SetLoadingBudgetPerFrame(5 * 1024 * 1024); // 5 ΠœΠ‘ Π·Π° ΠΊΠ°Π΄Ρ€

// РСгистрация ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° для опрСдСлСния ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π° рСсурсов
streamingSystem.SetPriorityHandler([](const Wudgine::Resources::ResourceInfo& resource) {
    // ВычислСниС ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π° Π½Π° основС расстояния Π΄ΠΎ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
    float distance = CalculateDistanceToCamera(resource.position);
    return 1.0f / (distance + 1.0f); // Π§Π΅ΠΌ Π±Π»ΠΈΠΆΠ΅, Ρ‚Π΅ΠΌ Π²Ρ‹ΡˆΠ΅ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚
});

// ОбновлСниС систСмы ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΉ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΊΠ°Π΄Ρ€
void Update(float deltaTime) {
    // ОбновлСниС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΊΠ°ΠΌΠ΅Ρ€Ρ‹
    streamingSystem.SetCameraPosition(camera.GetPosition());
    
    // ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ/Π²Ρ‹Π³Ρ€ΡƒΠ·ΠΊΠΈ рСсурсов
    streamingSystem.Update(deltaTime);
}

Π£Ρ€ΠΎΠ²Π½ΠΈ Π΄Π΅Ρ‚Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ (LOD)

// Настройка LOD для ΠΌΠΎΠ΄Π΅Π»ΠΈ
Wudgine::Resources::ModelHandle modelHandle = resourceManager.LoadModel("models/character.obj");
auto model = resourceManager.Get<Wudgine::Resources::Model>(modelHandle);

// Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ Π΄Π΅Ρ‚Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ
model->AddLOD(1, resourceManager.LoadModel("models/character_lod1.obj"));
model->AddLOD(2, resourceManager.LoadModel("models/character_lod2.obj"));
model->AddLOD(3, resourceManager.LoadModel("models/character_lod3.obj"));

// Настройка расстояний для ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ LOD
model->SetLODDistance(1, 10.0f);  // ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π½Π° LOD1 Π½Π° расстоянии 10 Π΅Π΄ΠΈΠ½ΠΈΡ†
model->SetLODDistance(2, 30.0f);  // ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π½Π° LOD2 Π½Π° расстоянии 30 Π΅Π΄ΠΈΠ½ΠΈΡ†
model->SetLODDistance(3, 100.0f); // ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π½Π° LOD3 Π½Π° расстоянии 100 Π΅Π΄ΠΈΠ½ΠΈΡ†

Π’ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ тСкстурная ΠΏΠ°ΠΌΡΡ‚ΡŒ

Π’ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Π°Ρ тСкстурная ΠΏΠ°ΠΌΡΡ‚ΡŒ позволяСт эффСктивно Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с тСкстурами, Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°Π΅Ρ‚ Π΄ΠΎΡΡ‚ΡƒΠΏΠ½ΡƒΡŽ Π²ΠΈΠ΄Π΅ΠΎΠΏΠ°ΠΌΡΡ‚ΡŒ.

Настройка Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ тСкстурной памяти

// Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ систСмы Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… тСкстур
Wudgine::Resources::VirtualTextureSystem vtSystem;
vtSystem.Initialize(4096, 4096); // Π Π°Π·ΠΌΠ΅Ρ€ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ тСкстуры 4096x4096
vtSystem.SetPageSize(128); // Π Π°Π·ΠΌΠ΅Ρ€ страницы 128x128 пиксСлСй
vtSystem.SetCacheSize(512 * 1024 * 1024); // Кэш 512 ΠœΠ‘

// Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° мСгатСкстуры
Wudgine::Resources::VirtualTextureHandle vtHandle = 
    vtSystem.LoadVirtualTexture("textures/terrain_mega.vtex");

// ИспользованиС Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ тСкстуры Π² ΡˆΠ΅ΠΉΠ΄Π΅Ρ€Π΅
shader->SetVirtualTexture("terrainTexture", vtHandle);

// ОбновлСниС систСмы Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… тСкстур ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΊΠ°Π΄Ρ€
void Update(float deltaTime) {
    // ОбновлСниС Π²ΠΈΠ΄ΠΈΠΌΡ‹Ρ… областСй
    vtSystem.UpdateVisibleRegions(camera);
    
    // Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… страниц
    vtSystem.UpdatePageCache();
}

Π‘ΠΆΠ°Ρ‚ΠΈΠ΅ рСсурсов

Wudgine ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ сТатия для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ использования памяти.

Π‘ΠΆΠ°Ρ‚ΠΈΠ΅ тСкстур

// Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° тСкстуры с ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° сТатия
Wudgine::Resources::TextureLoadOptions options;
options.compressionFormat = Wudgine::Resources::TextureCompressionFormat::BC7;
options.generateMipmaps = true;
options.mipmapFilter = Wudgine::Resources::MipmapFilter::Kaiser;

Wudgine::Resources::TextureHandle textureHandle = 
    resourceManager.LoadTexture("textures/albedo.png", options);

Π‘ΠΆΠ°Ρ‚ΠΈΠ΅ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ

// Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ с ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ
Wudgine::Resources::ModelLoadOptions options;
options.optimizeMesh = true;
options.compressVertexData = true;
options.vertexCacheOptimization = true;

Wudgine::Resources::ModelHandle modelHandle = 
    resourceManager.LoadModel("models/complex_scene.obj", options);

Горячая ΠΏΠ΅Ρ€Π΅Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° рСсурсов

Горячая ΠΏΠ΅Ρ€Π΅Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° позволяСт ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒ рСсурсы Π±Π΅Π· пСрСзапуска ΠΈΠ³Ρ€Ρ‹, Ρ‡Ρ‚ΠΎ ускоряСт процСсс Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ.

Настройка горячСй ΠΏΠ΅Ρ€Π΅Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ

// Π’ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ систСмы горячСй ΠΏΠ΅Ρ€Π΅Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
Wudgine::Resources::HotReloadSystem hotReloadSystem;
hotReloadSystem.Initialize(resourceManager);
hotReloadSystem.WatchDirectory("assets/textures");
hotReloadSystem.WatchDirectory("assets/models");
hotReloadSystem.WatchDirectory("assets/shaders");

// РСгистрация ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° событий
hotReloadSystem.OnResourceReloaded([](const std::string& path) {
    std::cout << "РСсурс ΠΏΠ΅Ρ€Π΅Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½: " << path << std::endl;
});

// ОбновлСниС систСмы горячСй ΠΏΠ΅Ρ€Π΅Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
void Update(float deltaTime) {
    hotReloadSystem.Update();
}

ΠŸΡƒΠ»Ρ‹ рСсурсов

ΠŸΡƒΠ»Ρ‹ рСсурсов ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ эффСктивно ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈ использованиС ΠΏΡƒΠ»Π°

// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡƒΠ»Π° частиц
Wudgine::Resources::ResourcePool<Particle> particlePool(1000);

// ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈΠ· ΠΏΡƒΠ»Π°
Particle* particle = particlePool.Acquire();
if (particle) {
    // Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ частицы
    particle->position = position;
    particle->velocity = velocity;
    particle->lifetime = 2.0f;
    particle->color = color;
}

// Π’ΠΎΠ·Π²Ρ€Π°Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π² ΠΏΡƒΠ»
particlePool.Release(particle);

// ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° Π½Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²
particlePool.GarbageCollect();

ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ рСсурсов

ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ позволяСт ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ доступ ΠΊ часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΌ рСсурсам.

Настройка кэша рСсурсов

// Настройка кэша рСсурсов
Wudgine::Resources::ResourceCache cache;
cache.SetMaxSize(1024 * 1024 * 512); // 512 ΠœΠ‘
cache.SetEvictionPolicy(Wudgine::Resources::EvictionPolicy::LRU);

// Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ рСсурса Π² кэш
cache.Add("textures/ui.png", textureHandle);

// ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ рСсурса ΠΈΠ· кэша
if (cache.Contains("textures/ui.png")) {
    auto handle = cache.Get("textures/ui.png");
    auto texture = resourceManager.Get<Wudgine::Resources::Texture>(handle);
}

// ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° кэша
cache.Clear();

ΠŸΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° рСсурсов

Wudgine ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ рСсурсов для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈΡ… использования Π² ΠΈΠ³Ρ€Π΅.

ΠšΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ рСсурсов

// Настройка ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ тСкстур
Wudgine::Resources::TextureProcessor textureProcessor;
textureProcessor.AddStep<Wudgine::Resources::ResizeStep>(2048, 2048);
textureProcessor.AddStep<Wudgine::Resources::NormalMapGeneratorStep>();
textureProcessor.AddStep<Wudgine::Resources::CompressionStep>(Wudgine::Resources::TextureCompressionFormat::BC5);

// ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° тСкстуры
textureProcessor.Process("textures/input.png", "textures/output.dds");

Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ

Π­Ρ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ΅ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ критичСски Π²Π°ΠΆΠ½ΠΎ для ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈΠ³Ρ€Ρ‹.

ΠžΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΠ΅ использования памяти

// ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎΠ± использовании памяти
Wudgine::Resources::MemoryStats memoryStats = resourceManager.GetMemoryStats();

std::cout << "ИспользованиС памяти:" << std::endl;
std::cout << "- ВСкстуры: " << memoryStats.textureMemory / (1024 * 1024) << " ΠœΠ‘" << std::endl;
std::cout << "- МодСли: " << memoryStats.modelMemory / (1024 * 1024) << " ΠœΠ‘" << std::endl;
std::cout << "- Π—Π²ΡƒΠΊΠΈ: " << memoryStats.audioMemory / (1024 * 1024) << " ΠœΠ‘" << std::endl;
std::cout << "- ВсСго: " << memoryStats.totalMemory / (1024 * 1024) << " ΠœΠ‘" << std::endl;

// Установка ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ памяти
resourceManager.SetMemoryLimit(Wudgine::Resources::ResourceType::Texture, 1024 * 1024 * 512); // 512 ΠœΠ‘ для тСкстур

ДСфрагмСнтация памяти

// Запуск Π΄Π΅Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ памяти
resourceManager.DefragmentMemory();

// Настройка автоматичСской Π΄Π΅Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ
resourceManager.SetAutoDefragment(true);
resourceManager.SetDefragmentThreshold(0.3f); // Запуск ΠΏΡ€ΠΈ 30% Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования

Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° уровня с экраном Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ

// Класс для управлСния Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΎΠΉ уровня
class LevelLoader {
public:
    void LoadLevel(const std::string& levelName) {
        // ΠŸΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ экран Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
        m_LoadingScreen.Show();
        
        // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π³Ρ€ΡƒΠΏΠΏΡ‹ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ для уровня
        Wudgine::Resources::LoadGroup levelGroup;
        
        // Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° манифСста уровня
        auto manifestHandle = m_ResourceManager.LoadJson("levels/" + levelName + "/manifest.json");
        auto manifest = m_ResourceManager.Get<Wudgine::Resources::JsonResource>(manifestHandle);
        
        // Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ рСсурсов ΠΈΠ· манифСста
        for (const auto& textureInfo : manifest->GetArray("textures")) {
            levelGroup.AddTexture(textureInfo["path"].GetString());
        }
        
        for (const auto& modelInfo : manifest->GetArray("models")) {
            levelGroup.AddModel(modelInfo["path"].GetString());
        }
        
        // Запуск асинхронной Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
        m_ResourceManager.LoadGroupAsync(levelGroup, [this, levelName](Wudgine::Resources::LoadGroup& group) {
            // Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π°, созданиС уровня
            CreateLevel(levelName);
            
            // Π‘ΠΊΡ€Ρ‹Ρ‚ΡŒ экран Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
            m_LoadingScreen.Hide();
        });
    }
    
    void Update(float deltaTime) {
        // ОбновлСниС прогрСсса Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
        if (m_LoadingScreen.IsVisible()) {
            float progress = m_ResourceManager.GetGroupLoadingProgress(m_CurrentLoadGroup);
            m_LoadingScreen.SetProgress(progress);
        }
    }
    
private:
    Wudgine::Resources::ResourceManager& m_ResourceManager;
    Wudgine::UI::LoadingScreen m_LoadingScreen;
    Wudgine::Resources::LoadGroup m_CurrentLoadGroup;
    
    void CreateLevel(const std::string& levelName) {
        // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ уровня Π½Π° основС Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹Ρ… рСсурсов
        // ...
    }
};

БистСма ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΉ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ ΠΌΠΈΡ€Π°

// БистСма управлСния Ρ‡Π°Π½ΠΊΠ°ΠΌΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ ΠΌΠΈΡ€Π°
class OpenWorldChunkManager {
public:
    void Initialize(int worldSize, int chunkSize) {
        m_WorldSize = worldSize;
        m_ChunkSize = chunkSize;
        
        // ВычислСниС количСства Ρ‡Π°Π½ΠΊΠΎΠ²
        m_ChunksCount = worldSize / chunkSize;
        
        // Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ массива Ρ‡Π°Π½ΠΊΠΎΠ²
        m_Chunks.resize(m_ChunksCount * m_ChunksCount);
    }
    
    void Update(const Wudgine::Math::Vector3& playerPosition) {
        // ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Ρ‡Π°Π½ΠΊΠ° ΠΈΠ³Ρ€ΠΎΠΊΠ°
        int chunkX = static_cast<int>(playerPosition.x) / m_ChunkSize;
        int chunkZ = static_cast<int>(playerPosition.z) / m_ChunkSize;
        
        // ОбновлСниС видимости Ρ‡Π°Π½ΠΊΠΎΠ²
        for (int z = 0; z < m_ChunksCount; z++) {
            for (int x = 0; x < m_ChunksCount; x++) {
                int distance = std::max(std::abs(x - chunkX), std::abs(z - chunkZ));
                
                Chunk& chunk = GetChunk(x, z);
                
                if (distance <= m_ViewDistance) {
                    // Π§Π°Π½ΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½
                    if (!chunk.isLoaded) {
                        LoadChunk(x, z);
                    }
                } else {
                    // Π§Π°Π½ΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹Π³Ρ€ΡƒΠΆΠ΅Π½
                    if (chunk.isLoaded) {
                        UnloadChunk(x, z);
                    }
                }
            }
        }
    }
    
private:
    struct Chunk {
        bool isLoaded = false;
        Wudgine::Resources::LoadGroup resources;
        Wudgine::ECS::Entity chunkEntity;
    };
    
    std::vector<Chunk> m_Chunks;
    int m_WorldSize;
    int m_ChunkSize;
    int m_ChunksCount;
    int m_ViewDistance = 3;
    
    Chunk& GetChunk(int x, int z) {
        return m_Chunks[z * m_ChunksCount + x];
    }
    
    void LoadChunk(int x, int z) {
        Chunk& chunk = GetChunk(x, z);
        
        // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π³Ρ€ΡƒΠΏΠΏΡ‹ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ для Ρ‡Π°Π½ΠΊΠ°
        Wudgine::Resources::LoadGroup chunkGroup;
        
        // Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ рСсурсов Ρ‡Π°Π½ΠΊΠ°
        std::string chunkPath = "world/chunks/" + std::to_string(x) + "_" + std::to_string(z);
        chunkGroup.AddTexture(chunkPath + "/terrain.png");
        chunkGroup.AddModel(chunkPath + "/terrain.obj");
        
        // Запуск асинхронной Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
        m_ResourceManager.LoadGroupAsync(chunkGroup, [this, x, z](Wudgine::Resources::LoadGroup& group) {
            // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ сущности Ρ‡Π°Π½ΠΊΠ°
            CreateChunkEntity(x, z);
            
            // ΠžΡ‚ΠΌΠ΅Ρ‚ΠΊΠ° Ρ‡Π°Π½ΠΊΠ° ΠΊΠ°ΠΊ Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ
            GetChunk(x, z).isLoaded = true;
        });
        
        // Π‘ΠΎΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Π³Ρ€ΡƒΠΏΠΏΡ‹ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ
        chunk.resources = chunkGroup;
    }
    
    void UnloadChunk(int x, int z) {
        Chunk& chunk = GetChunk(x, z);
        
        // Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ сущности Ρ‡Π°Π½ΠΊΠ°
        m_World.DestroyEntity(chunk.chunkEntity);
        
        // Π’Ρ‹Π³Ρ€ΡƒΠ·ΠΊΠ° рСсурсов Ρ‡Π°Π½ΠΊΠ°
        m_ResourceManager.UnloadGroup(chunk.resources);
        
        // ΠžΡ‚ΠΌΠ΅Ρ‚ΠΊΠ° Ρ‡Π°Π½ΠΊΠ° ΠΊΠ°ΠΊ Π²Ρ‹Π³Ρ€ΡƒΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ
        chunk.isLoaded = false;
    }
    
    void CreateChunkEntity(int x, int z) {
        Chunk& chunk = GetChunk(x, z);
        
        // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ сущности для Ρ‡Π°Π½ΠΊΠ°
        chunk.chunkEntity = m_World.CreateEntity();
        
        // Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²
        auto& transform = m_World.AddComponent<Wudgine::ECS::TransformComponent>(chunk.chunkEntity);
        transform.position = Wudgine::Math::Vector3(x * m_ChunkSize, 0, z * m_ChunkSize);
        
        // Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ
        auto& model = m_World.AddComponent<Wudgine::ECS::ModelComponent>(chunk.chunkEntity);
        std::string modelPath = "world/chunks/" + std::to_string(x) + "_" + std::to_string(z) + "/terrain.obj";
        model.handle = m_ResourceManager.GetHandle(modelPath);
    }
    
    Wudgine::Resources::ResourceManager& m_ResourceManager;
    Wudgine::ECS::World& m_World;
};

Π§Ρ‚ΠΎ дальшС?

НСэффСктивноС ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ рСсурсами ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ ΡƒΡ‚Π΅Ρ‡ΠΊΠ°ΠΌ памяти ΠΈ сниТСнию ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. РСгулярно ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ систСмы рСсурсов.

Wudgine β€’ Β© 2025