mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-12-10 13:17:48 +00:00
chore: track loaded zones in ui
This commit is contained in:
@@ -1,12 +1,42 @@
|
|||||||
#include "FastFileContext.h"
|
#include "FastFileContext.h"
|
||||||
|
|
||||||
|
#include "Web/Binds/FastFileBinds.h"
|
||||||
|
#include "Web/UiCommunication.h"
|
||||||
#include "ZoneLoading.h"
|
#include "ZoneLoading.h"
|
||||||
|
|
||||||
|
void FastFileContext::Destroy()
|
||||||
|
{
|
||||||
|
// Unload all zones
|
||||||
|
m_loaded_zones.clear();
|
||||||
|
}
|
||||||
|
|
||||||
result::Expected<Zone*, std::string> FastFileContext::LoadFastFile(const std::string& path)
|
result::Expected<Zone*, std::string> FastFileContext::LoadFastFile(const std::string& path)
|
||||||
{
|
{
|
||||||
auto zone = ZoneLoading::LoadZone(path);
|
auto zone = ZoneLoading::LoadZone(path);
|
||||||
if (!zone)
|
if (!zone)
|
||||||
return result::Unexpected(std::move(zone.error()));
|
return result::Unexpected(std::move(zone.error()));
|
||||||
|
|
||||||
return m_loaded_zones.emplace_back(std::move(*zone)).get();
|
auto* result = m_loaded_zones.emplace_back(std::move(*zone)).get();
|
||||||
|
|
||||||
|
ui::NotifyZoneLoaded(result->m_name, path);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result::Expected<NoResult, std::string> FastFileContext::UnloadZone(const std::string& zoneName)
|
||||||
|
{
|
||||||
|
const auto existingZone = std::ranges::find_if(m_loaded_zones,
|
||||||
|
[&zoneName](const std::unique_ptr<Zone>& zone)
|
||||||
|
{
|
||||||
|
return zone->m_name == zoneName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingZone != m_loaded_zones.end())
|
||||||
|
{
|
||||||
|
m_loaded_zones.erase(existingZone);
|
||||||
|
ui::NotifyZoneUnloaded(zoneName);
|
||||||
|
return NoResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result::Unexpected(std::format("No zone with name {} loaded", zoneName));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,10 @@
|
|||||||
class FastFileContext
|
class FastFileContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
result::Expected<Zone*, std::string> LoadFastFile(const std::string& path);
|
result::Expected<Zone*, std::string> LoadFastFile(const std::string& path);
|
||||||
|
result::Expected<NoResult, std::string> UnloadZone(const std::string& zoneName);
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Zone>> m_loaded_zones;
|
std::vector<std::unique_ptr<Zone>> m_loaded_zones;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,5 +13,6 @@ void ModManContext::Startup()
|
|||||||
|
|
||||||
void ModManContext::Destroy()
|
void ModManContext::Destroy()
|
||||||
{
|
{
|
||||||
|
m_fast_file.Destroy();
|
||||||
m_db_thread.Terminate();
|
m_db_thread.Terminate();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ namespace ui
|
|||||||
void RegisterAllBinds(webview::webview& wv)
|
void RegisterAllBinds(webview::webview& wv)
|
||||||
{
|
{
|
||||||
RegisterDialogHandlerBinds(wv);
|
RegisterDialogHandlerBinds(wv);
|
||||||
RegisterFastFileBinds(wv);
|
RegisterZoneBinds(wv);
|
||||||
}
|
}
|
||||||
} // namespace ui
|
} // namespace ui
|
||||||
|
|||||||
@@ -3,8 +3,27 @@
|
|||||||
#include "Context/ModManContext.h"
|
#include "Context/ModManContext.h"
|
||||||
#include "Web/UiCommunication.h"
|
#include "Web/UiCommunication.h"
|
||||||
|
|
||||||
|
#include "Json/JsonExtension.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
class ZoneLoadedDto
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string zoneName;
|
||||||
|
std::string filePath;
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneLoadedDto, zoneName, filePath);
|
||||||
|
|
||||||
|
class ZoneUnloadedDto
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string zoneName;
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneUnloadedDto, zoneName);
|
||||||
|
|
||||||
void LoadFastFile(webview::webview& wv, std::string id, std::string path) // NOLINT(performance-unnecessary-value-param) Copy is made for thread safety
|
void LoadFastFile(webview::webview& wv, std::string id, std::string path) // NOLINT(performance-unnecessary-value-param) Copy is made for thread safety
|
||||||
{
|
{
|
||||||
ModManContext::Get().m_db_thread.Dispatch(
|
ModManContext::Get().m_db_thread.Dispatch(
|
||||||
@@ -24,11 +43,47 @@ namespace
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UnloadZone(webview::webview& wv, std::string id, std::string zoneName) // NOLINT(performance-unnecessary-value-param) Copy is made for thread safety
|
||||||
|
{
|
||||||
|
ModManContext::Get().m_db_thread.Dispatch(
|
||||||
|
[&wv, id, zoneName]
|
||||||
|
{
|
||||||
|
auto result = ModManContext::Get().m_fast_file.UnloadZone(zoneName);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
con::debug("Unloaded zone \"{}\"", zoneName);
|
||||||
|
ui::PromiseResolve(wv, id, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
con::warn("Failed unloading zone {}: {}", zoneName, result.error());
|
||||||
|
ui::PromiseReject(wv, id, std::move(result).error());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace ui
|
namespace ui
|
||||||
{
|
{
|
||||||
void RegisterFastFileBinds(webview::webview& wv)
|
void NotifyZoneLoaded(std::string zoneName, std::string fastFilePath)
|
||||||
|
{
|
||||||
|
const ZoneLoadedDto dto{
|
||||||
|
.zoneName = std::move(zoneName),
|
||||||
|
.filePath = std::move(fastFilePath),
|
||||||
|
};
|
||||||
|
Notify(*ModManContext::Get().m_main_webview, "zoneLoaded", dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifyZoneUnloaded(std::string zoneName)
|
||||||
|
{
|
||||||
|
const ZoneUnloadedDto dto{
|
||||||
|
.zoneName = std::move(zoneName),
|
||||||
|
};
|
||||||
|
Notify(*ModManContext::Get().m_main_webview, "zoneUnloaded", dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterZoneBinds(webview::webview& wv)
|
||||||
{
|
{
|
||||||
BindAsync<std::string>(wv,
|
BindAsync<std::string>(wv,
|
||||||
"loadFastFile",
|
"loadFastFile",
|
||||||
@@ -36,5 +91,12 @@ namespace ui
|
|||||||
{
|
{
|
||||||
LoadFastFile(wv, id, std::move(path));
|
LoadFastFile(wv, id, std::move(path));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
BindAsync<std::string>(wv,
|
||||||
|
"unloadZone",
|
||||||
|
[&wv](const std::string& id, std::string zoneName)
|
||||||
|
{
|
||||||
|
UnloadZone(wv, id, std::move(zoneName));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} // namespace ui
|
} // namespace ui
|
||||||
|
|||||||
@@ -4,5 +4,8 @@
|
|||||||
|
|
||||||
namespace ui
|
namespace ui
|
||||||
{
|
{
|
||||||
void RegisterFastFileBinds(webview::webview& wv);
|
void NotifyZoneLoaded(std::string zoneName, std::string fastFilePath);
|
||||||
}
|
void NotifyZoneUnloaded(std::string zoneName);
|
||||||
|
|
||||||
|
void RegisterZoneBinds(webview::webview& wv);
|
||||||
|
} // namespace ui
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { webviewBinds } from "./native";
|
import { webviewBinds } from "@/native";
|
||||||
|
import { useZoneStore } from "@/stores/ZoneStore";
|
||||||
|
|
||||||
|
const zoneStore = useZoneStore();
|
||||||
const lastPath = ref("");
|
const lastPath = ref("");
|
||||||
const loadingFastFile = ref(false);
|
const loadingFastFile = ref(false);
|
||||||
|
|
||||||
@@ -11,12 +13,19 @@ async function onOpenFastfileClick() {
|
|||||||
|
|
||||||
loadingFastFile.value = true;
|
loadingFastFile.value = true;
|
||||||
|
|
||||||
webviewBinds.loadFastFile(lastPath.value)
|
webviewBinds
|
||||||
.catch((e: string) => {
|
.loadFastFile(lastPath.value)
|
||||||
console.error("Failed to load fastfile:", e);
|
.catch((e: string) => {
|
||||||
})
|
console.error("Failed to load fastfile:", e);
|
||||||
.finally(() => {
|
})
|
||||||
loadingFastFile.value = false;
|
.finally(() => {
|
||||||
|
loadingFastFile.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onUnloadClicked(zoneName: string) {
|
||||||
|
webviewBinds.unloadZone(zoneName).catch((e: string) => {
|
||||||
|
console.error("Failed to unload zone:", e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -28,9 +37,15 @@ async function onOpenFastfileClick() {
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
<button @click="onOpenFastfileClick">Open fastfile</button>
|
<button @click="onOpenFastfileClick">Open fastfile</button>
|
||||||
<span>The last path: {{ lastPath }}</span>
|
|
||||||
<span>Loading: {{ loadingFastFile }}</span>
|
<span>Loading: {{ loadingFastFile }}</span>
|
||||||
</p>
|
</p>
|
||||||
|
<div>
|
||||||
|
<h3>Loaded zones:</h3>
|
||||||
|
<div v-for="zone in zoneStore.loadedZones" :key="zone">
|
||||||
|
<span>{{ zone }}</span>
|
||||||
|
<button @click="onUnloadClicked(zone)">Unload</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,18 @@
|
|||||||
|
export interface ZoneLoadedDto {
|
||||||
|
zoneName: string;
|
||||||
|
filePath: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ZoneUnloadedDto {
|
||||||
|
zoneName: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface FastFileBinds {
|
export interface FastFileBinds {
|
||||||
loadFastFile(path: string): Promise<void>;
|
loadFastFile(path: string): Promise<void>;
|
||||||
|
unloadZone(zoneName: string): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FastFileEventMap {
|
||||||
|
zoneLoaded: ZoneLoadedDto;
|
||||||
|
zoneUnloaded: ZoneUnloadedDto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import type { DialogBinds } from "./DialogBinds";
|
import type { DialogBinds } from "./DialogBinds";
|
||||||
import type { FastFileBinds } from "./FastFileBinds";
|
import type { FastFileBinds, FastFileEventMap } from "./FastFileBinds";
|
||||||
|
|
||||||
|
|
||||||
export type NativeMethods = DialogBinds & FastFileBinds;
|
export type NativeMethods = DialogBinds & FastFileBinds;
|
||||||
|
|
||||||
interface NativeEventMap {
|
type NativeEventMap = FastFileEventMap;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type WebViewExtensions = {
|
type WebViewExtensions = {
|
||||||
webviewBinds: NativeMethods;
|
webviewBinds: NativeMethods;
|
||||||
|
|||||||
20
src/ModManUi/src/stores/ZoneStore.ts
Normal file
20
src/ModManUi/src/stores/ZoneStore.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { readonly, ref } from "vue";
|
||||||
|
import { defineStore } from "pinia";
|
||||||
|
import { webviewAddEventListener } from "@/native";
|
||||||
|
|
||||||
|
export const useZoneStore = defineStore("zone", () => {
|
||||||
|
const loadedZones = ref<string[]>([]);
|
||||||
|
|
||||||
|
webviewAddEventListener("zoneLoaded", (dto) => {
|
||||||
|
loadedZones.value.push(dto.zoneName);
|
||||||
|
});
|
||||||
|
|
||||||
|
webviewAddEventListener("zoneUnloaded", (dto) => {
|
||||||
|
const index = loadedZones.value.indexOf(dto.zoneName);
|
||||||
|
if (index >= 0) {
|
||||||
|
loadedZones.value.splice(index, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { loadedZones: readonly(loadedZones) };
|
||||||
|
});
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import { ref, computed } from "vue";
|
|
||||||
import { defineStore } from "pinia";
|
|
||||||
|
|
||||||
export const useCounterStore = defineStore("counter", () => {
|
|
||||||
const count = ref(0);
|
|
||||||
const doubleCount = computed(() => count.value * 2);
|
|
||||||
function increment() {
|
|
||||||
count.value++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { count, doubleCount, increment };
|
|
||||||
});
|
|
||||||
@@ -8,7 +8,8 @@ Zone::Zone(std::string name, const zone_priority_t priority, GameId gameId)
|
|||||||
m_language(GameLanguage::LANGUAGE_NONE),
|
m_language(GameLanguage::LANGUAGE_NONE),
|
||||||
m_game_id(gameId),
|
m_game_id(gameId),
|
||||||
m_pools(ZoneAssetPools::CreateForGame(gameId, this, priority)),
|
m_pools(ZoneAssetPools::CreateForGame(gameId, this, priority)),
|
||||||
m_memory(std::make_unique<ZoneMemory>())
|
m_memory(std::make_unique<ZoneMemory>()),
|
||||||
|
m_registered(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user