@@ -19,7 +19,6 @@ use crate::messages::portfolio::document::overlays::grid_overlays::{grid_overlay
1919use crate :: messages:: portfolio:: document:: overlays:: utility_types:: { OverlaysType , OverlaysVisibilitySettings , Pivot } ;
2020use crate :: messages:: portfolio:: document:: properties_panel:: properties_panel_message_handler:: PropertiesPanelMessageContext ;
2121use crate :: messages:: portfolio:: document:: utility_types:: document_metadata:: { DocumentMetadata , LayerNodeIdentifier } ;
22- use crate :: messages:: portfolio:: document:: utility_types:: embedded_resources:: EmbeddedResources ;
2322use crate :: messages:: portfolio:: document:: utility_types:: misc:: { AlignAggregate , AlignAxis , FlipAxis , PTZ } ;
2423use crate :: messages:: portfolio:: document:: utility_types:: network_interface:: { FlowType , InputConnector , NodeTemplate , OutputConnector } ;
2524use crate :: messages:: portfolio:: utility_types:: { CachedData , PanelType } ;
@@ -30,7 +29,7 @@ use crate::messages::tool::tool_messages::tool_prelude::Key;
3029use crate :: messages:: tool:: utility_types:: ToolType ;
3130use crate :: node_graph_executor:: NodeGraphExecutor ;
3231use glam:: { DAffine2 , DVec2 } ;
33- use graph_craft:: application_io:: resource:: ResourceHash ;
32+ use graph_craft:: application_io:: resource:: ResourceId ;
3433use graph_craft:: application_io:: wgpu_available;
3534use graph_craft:: descriptor;
3635use graph_craft:: document:: value:: TaggedValue ;
@@ -61,7 +60,7 @@ pub struct DocumentMessageContext<'a> {
6160 pub layers_panel_open : bool ,
6261 pub properties_panel_open : bool ,
6362 pub viewport : & ' a ViewportMessageHandler ,
64- pub resources : & ' a ResourceMessageHandler ,
63+ pub resource_storage : & ' a ResourceStorageMessageHandler ,
6564}
6665
6766#[ derive( Clone , Debug , serde:: Serialize , serde:: Deserialize , ExtractField ) ]
@@ -88,6 +87,9 @@ pub struct DocumentMessageHandler {
8887 //
8988 // Contains the NodeNetwork and acts an an interface to manipulate the NodeNetwork with custom setters in order to keep NetworkMetadata in sync
9089 pub network_interface : NodeNetworkInterface ,
90+ /// Resources embedded in the document.
91+ #[ serde( default , skip_serializing_if = "ResourceMessageHandler::is_empty" ) ]
92+ pub resources : ResourceMessageHandler ,
9193 /// Tracks which layer occurrences are collapsed in the Layers panel, keyed by tree path.
9294 #[ serde( deserialize_with = "deserialize_collapsed_layers" , default ) ]
9395 pub collapsed : CollapsedLayers ,
@@ -110,9 +112,6 @@ pub struct DocumentMessageHandler {
110112 pub graph_view_overlay_open : bool ,
111113 /// The current opacity of the faded node graph background that covers up the artwork.
112114 pub graph_fade_artwork_percentage : f64 ,
113- /// Resources embedded in the document. Only propagated if saving to an external file and never for autosaved documents.
114- #[ serde( rename = "resources" , default , skip_serializing_if = "EmbeddedResources::is_empty" ) ]
115- pub embedded_resources : EmbeddedResources ,
116115
117116 // =============================================
118117 // Fields omitted from the saved document format
@@ -166,6 +165,7 @@ impl Default for DocumentMessageHandler {
166165 // Fields that are saved in the document format
167166 // ============================================
168167 network_interface : default_document_network_interface ( ) ,
168+ resources : ResourceMessageHandler :: default ( ) ,
169169 collapsed : CollapsedLayers :: default ( ) ,
170170 commit_hash : GRAPHITE_GIT_COMMIT_HASH . to_string ( ) ,
171171 document_ptz : PTZ :: default ( ) ,
@@ -175,7 +175,6 @@ impl Default for DocumentMessageHandler {
175175 graph_view_overlay_open : false ,
176176 snapping_state : SnappingState :: default ( ) ,
177177 graph_fade_artwork_percentage : 80. ,
178- embedded_resources : EmbeddedResources :: default ( ) ,
179178 // =============================================
180179 // Fields omitted from the saved document format
181180 // =============================================
@@ -207,7 +206,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
207206 data_panel_open,
208207 layers_panel_open,
209208 properties_panel_open,
210- resources ,
209+ resource_storage ,
211210 } = context;
212211
213212 match message {
@@ -282,6 +281,10 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
282281 let mut graph_operation_message_handler = GraphOperationMessageHandler { } ;
283282 graph_operation_message_handler. process_message ( message, responses, context) ;
284283 }
284+ DocumentMessage :: Resource ( message) => {
285+ let context = ResourceMessageContext { } ;
286+ self . resources . process_message ( message, responses, context) ;
287+ }
285288 DocumentMessage :: AlignSelectedLayers { axis, aggregate } => {
286289 let axis = match axis {
287290 AlignAxis :: X => DVec2 :: X ,
@@ -920,36 +923,29 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
920923 DocumentMessage :: SaveDocument | DocumentMessage :: SaveDocumentAs => {
921924 responses. add ( PortfolioMessage :: AutoSaveActiveDocument ) ;
922925
926+ let name = format ! ( "{}.{}" , self . name. clone( ) , FILE_EXTENSION ) ;
923927 let path = if let DocumentMessage :: SaveDocumentAs = message { None } else { self . path . clone ( ) } ;
924928 if path. is_some ( ) {
925929 responses. add ( DocumentMessage :: MarkAsSaved ) ;
926930 }
927931 let folder = self . path . as_ref ( ) . and_then ( |path| path. parent ( ) ) . map ( |parent| parent. to_path_buf ( ) ) ;
928932
929- let resource_hashes = Vec :: from_iter ( self . used_resources ( false ) ) . into_boxed_slice ( ) ;
930- let resources = resources. resources ( ) ;
931933 let mut document = self . clone ( ) ;
932- let name = format ! ( "{}.{}" , self . name . clone ( ) , FILE_EXTENSION ) ;
934+ let resources_load_handle = resource_storage . resources ( ) ;
933935
934936 responses. add ( FrontendMessage :: Await {
935937 future : FrontendMessageFuture :: new ( async move {
936- let loads = resource_hashes
937- . into_iter ( )
938- . map ( |hash| {
939- let resource = resources. load ( hash) ;
940- async move { resource. await . map ( |resource| ( hash, resource) ) }
941- } )
942- . collect :: < Vec < _ > > ( ) ;
938+ document. resources . garbage_collect ( document. used_resources ( false ) . as_ref ( ) ) ;
939+ document. resources . embed_resources ( resources_load_handle) . await ;
943940
944- document. embedded_resources = EmbeddedResources :: from_iter ( futures:: future:: join_all ( loads) . await . into_iter ( ) . flatten ( ) ) ;
945- let content = document. serialize_document ( ) ;
941+ let content = document. serialize_document ( ) . into_bytes ( ) . into ( ) ;
946942
947943 FrontendMessage :: TriggerSaveDocument {
948944 document_id,
949945 name,
950946 path,
951947 folder,
952- content : content . into_bytes ( ) . into ( ) ,
948+ content,
953949 }
954950 } ) ,
955951 } ) ;
@@ -3472,14 +3468,19 @@ impl DocumentMessageHandler {
34723468 self . graph_view_overlay_open
34733469 }
34743470
3475- pub fn used_resources ( & self , include_history : bool ) -> HashSet < ResourceHash > {
3471+ pub fn garbage_collect_resources ( & mut self ) {
3472+ let used_resources = self . used_resources ( true ) ;
3473+ self . resources . garbage_collect ( & used_resources) ;
3474+ }
3475+
3476+ pub fn used_resources ( & self , include_history : bool ) -> Box < [ ResourceId ] > {
34763477 let mut resources = HashSet :: new ( ) ;
34773478 self . network_interface . collect_used_resources ( & mut resources) ;
34783479 if include_history {
34793480 self . document_undo_history . iter ( ) . for_each ( |interface| interface. collect_used_resources ( & mut resources) ) ;
34803481 self . document_redo_history . iter ( ) . for_each ( |interface| interface. collect_used_resources ( & mut resources) ) ;
34813482 }
3482- resources
3483+ resources. into_iter ( ) . collect :: < Vec < _ > > ( ) . into_boxed_slice ( )
34833484 }
34843485}
34853486
0 commit comments