Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

## 0.4.3


* New features
* `sequence.attachAudio()` now [accepts](https://github.com/AriaMinaei/theatre/commit/3f0556b9eb66a0893b43e38a3ee889e13d3a6667) any `AudioNode` as destination.
* Implemented `studio.createContentOfSaveFile()` for programmatically exporting the project's state.
Expand Down
78 changes: 78 additions & 0 deletions packages/core/src/projects/Project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type {Deferred} from '@theatre/utils/defer'
import {defer} from '@theatre/utils/defer'
import {globals} from '@theatre/core/globals'
import type {
ObjectAddressKey,
ProjectId,
SheetId,
SheetInstanceId,
Expand Down Expand Up @@ -81,6 +82,7 @@ export default class Project {
private _sheetTemplates = new Atom<{
[sheetId: string]: SheetTemplate | undefined
}>({})
private _localProjectStateAtom: Atom<ProjectState> | undefined
sheetTemplatesP = this._sheetTemplates.pointer
private _studio: Studio | undefined
assetStorage: IStudioAssetStorage
Expand Down Expand Up @@ -108,6 +110,7 @@ export default class Project {
revisionHistory: [],
},
})
this._localProjectStateAtom = onDiskStateAtom

this._assetStorageReadyDeferred = defer()
this.assetStorage = {
Expand Down Expand Up @@ -202,6 +205,7 @@ export default class Project {
this._pointerProxies.ephemeral.setPointer(
studio.ephemeralAtom.pointer.coreByProject[this.address.projectId],
)
this._localProjectStateAtom = undefined

// asset storage has to be initialized after the pointers are set
await studio
Expand Down Expand Up @@ -247,6 +251,80 @@ export default class Project {

return template.getInstance(instanceId)
}

/**
* @internal
* Removes all persisted state related to an object. Used when the object
* is detached before studio is attached or when studio isn't present.
*/
_forgetObject(sheetId: SheetId, objectKey: ObjectAddressKey) {
const projectId = this.address.projectId

if (this._studio) {
this._studio.transaction(({stateEditors}: $____FixmeStudio) => {
stateEditors.coreByProject.historic.sheetsById.forgetObject({
projectId,
sheetId,
objectKey,
})
})
return
}

const localAtom = this._localProjectStateAtom
if (!localAtom) return

localAtom.reduce((state) => {
const sheetState = state.historic.sheetsById[sheetId]
if (!sheetState) return state

let hasChanges = false
let newSheetState = sheetState

const staticOverridesForObject =
sheetState.staticOverrides.byObject[objectKey]
if (staticOverridesForObject) {
const newByObject = {...sheetState.staticOverrides.byObject}
delete newByObject[objectKey]
newSheetState = {
...newSheetState,
staticOverrides: {
...sheetState.staticOverrides,
byObject: newByObject,
},
}
hasChanges = true
}

const tracksByObject = sheetState.sequence?.tracksByObject
if (tracksByObject && tracksByObject[objectKey]) {
const newTracksByObject = {...sheetState.sequence.tracksByObject}
delete newTracksByObject[objectKey]
const newSequence = {
...sheetState.sequence,
tracksByObject: newTracksByObject,
}
newSheetState =
newSheetState === sheetState
? {...sheetState, sequence: newSequence}
: {...newSheetState, sequence: newSequence}
hasChanges = true
}

if (!hasChanges) return state

return {
...state,
historic: {
...state.historic,
sheetsById: {
...state.historic.sheetsById,
[sheetId]: newSheetState,
},
},
}
})
}
}

/**
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/projects/initialiseProjectState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ export default async function initialiseProjectState(
if (!onDiskState) {
useBrowserState()
} else {
const diskHeadRevision = onDiskState.revisionHistory[0]
if (
browserState.revisionHistory.indexOf(onDiskState.revisionHistory[0]) ==
-1
diskHeadRevision &&
browserState.revisionHistory.indexOf(diskHeadRevision) === -1
) {
browserStateIsNotBasedOnDiskState(onDiskState)
} else {
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/sheets/Sheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,17 @@ export default class Sheet {
}

deleteObject(objectKey: ObjectAddressKey) {
const objectExists = !!this._objects.get()[objectKey]

this._objects.reduce((state) => {
const newState = {...state}
delete newState[objectKey]
return newState
})

if (objectExists) {
this.project._forgetObject(this.address.sheetId, objectKey)
}
}

getSequence(): Sequence {
Expand Down