From 01a6ce7d785dbde3b04a16f2ae9fc0baa2eef720 Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Sat, 11 Jul 2026 18:05:10 -0400 Subject: [PATCH] Create migration handler --- .../migration-handlers/2_5_2.mjs | 14 +++- .../migration-handlers/base.mjs | 64 +++++++++++++++++++ module/systemRegistration/migrations.mjs | 50 ++++----------- 3 files changed, 88 insertions(+), 40 deletions(-) create mode 100644 module/systemRegistration/migration-handlers/base.mjs diff --git a/module/systemRegistration/migration-handlers/2_5_2.mjs b/module/systemRegistration/migration-handlers/2_5_2.mjs index c2f9261a..ec892d83 100644 --- a/module/systemRegistration/migration-handlers/2_5_2.mjs +++ b/module/systemRegistration/migration-handlers/2_5_2.mjs @@ -1,7 +1,15 @@ -export class Migration_2_5_2 { - version = '2.5.2'; +import { MigrationHandlerBase } from './base.mjs'; - async updateEffect(effectSource, item) { +export class Migration_2_5_2 extends MigrationHandlerBase { + version = '2.5.2'; + documentNames = ['Actor', 'Item']; + + /** @protected */ + _preMigrate() { + + } + + async updateEffectSource(effectSource, item) { let shouldUpdate = false; const newChanges = []; const srdItem = item?._stats.compendiumSource ? diff --git a/module/systemRegistration/migration-handlers/base.mjs b/module/systemRegistration/migration-handlers/base.mjs new file mode 100644 index 00000000..737ff562 --- /dev/null +++ b/module/systemRegistration/migration-handlers/base.mjs @@ -0,0 +1,64 @@ +/** + * The base class of an async migration. + * These are generally run between versions for things that require compendiums or must be done in post. + * The migrate() functions calls the various updateXSource() functions. + * Generally a subclass will override the version and the updateXSource() functions. + */ +export class MigrationHandlerBase { + version = null; + + async migrate() { + // todo: handle migrations, but have a way for a migration handler to specify if migrations are handled + // todo: handle more than just migrating effects. Right now this can only migrate effects + // NOTE: the preload is hardcoded, we should not hardcode it + + // note: last update costs as 5 on the progress + const numActors = game.actors.length; + const numItems = game.items.length; + const finalUpdateProgress = 5; + const DhProgress = game.system.api.applications.ui.DhProgress; + const preRunProgress = game.packs.size; + + const progress = DhProgress.createMigrationProgress( + preRunProgress + numActors + numItems + finalUpdateProgress + ); + + // Preload. Avoid hardcoding in the future + for (const pack of game.packs) { + await pack.getDocuments(); + progress.advance(); + } + + const batch = []; + + const updateItem = async item => { + const itemUpdates = []; + for (const effect of item.effects) { + const changes = await this.updateEffectSource(effect.toObject(), effect.parent); + if (changes) itemUpdates.push(changes); + } + if (itemUpdates.length) { + batch.push({ + action: 'update', + documentName: 'ActiveEffect', + updates: itemUpdates, + parent: item + }); + } + }; + + for (const actor of game.actors) { + for (const item of actor.items) { + await updateItem(item); + } + progress.advance(); + } + for (const item of game.items) { + await updateItem(item); + progress.advance(); + } + + await foundry.documents.modifyBatch(batch); + progress.advance({ by: finalUpdateProgress }); + } +} \ No newline at end of file diff --git a/module/systemRegistration/migrations.mjs b/module/systemRegistration/migrations.mjs index 11ebc160..fef97b8f 100644 --- a/module/systemRegistration/migrations.mjs +++ b/module/systemRegistration/migrations.mjs @@ -322,42 +322,18 @@ export async function runMigrations() { lastMigrationVersion = '2.1.0'; } - if (foundry.utils.isNewerVersion('2.5.2', lastMigrationVersion)) { - const progress = game.system.api.applications.ui.DhProgress.createMigrationProgress(game.packs.size + 5); - for (const pack of game.packs) { - await pack.getDocuments(); - progress.advance(); - } - - // todo: introduce a runner class that can handle passing on to the different update functions - const handler = new Migration_2_5_2(); - - const batch = []; - for (const actor of game.actors) { - for (const item of actor.items) { - const updates = []; - for (const effect of item.effects) { - const update = await handler.updateEffect(effect.toObject(), effect.parent); - if (update) { - updates.push(update); - } - } - - if (updates.length) { - batch.push({ item, updates }); - } - } - } - - for (const updateData of batch) { - await updateData.item.updateEmbeddedDocuments('ActiveEffect', updateData.updates); - } - - progress.advance({ by: 5 }); - - lastMigrationVersion = '2.5.2'; - } - //#endregion - await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion, lastMigrationVersion); + + /* -------------------------------------------- */ + /* New Style migrations below this point */ + /* -------------------------------------------- */ + + const migrations = [ + new Migration_2_5_2() + ].filter(m => m.version && foundry.utils.isNewerVersion(m.version, lastMigrationVersion)); + + for (const handler of migrations) { + await handler.migrate(); + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion, handler.version); + } }