11use dyn_any:: StaticType ;
2+ use std:: any:: Any ;
23use std:: future:: Future ;
34use std:: pin:: Pin ;
45use std:: sync:: { Arc , OnceLock } ;
@@ -7,7 +8,7 @@ use crate::WgpuExecutor;
78
89pub type PipelineFuture < ' a , T > = Pin < Box < dyn Future < Output = T > + Send + ' a > > ;
910
10- pub trait Pipeline : std :: any :: Any + Send + Sync + Sized {
11+ pub trait Pipeline : Any + Send + Sync + Sized {
1112 type Args < ' a > ;
1213 type Out : Send ;
1314
@@ -16,7 +17,7 @@ pub trait Pipeline: std::any::Any + Send + Sync + Sized {
1617 fn run < ' a > ( & ' a self , executor : & ' a WgpuExecutor , args : & ' a Self :: Args < ' _ > ) -> PipelineFuture < ' a , Self :: Out > ;
1718}
1819
19- pub trait AsyncPipeline : std :: any :: Any + Send + Sync + Sized {
20+ pub trait AsyncPipeline : Any + Send + Sync + Sized {
2021 type Args < ' a > ;
2122 type Out : Send ;
2223
@@ -38,47 +39,34 @@ impl<P: AsyncPipeline> Pipeline for P {
3839 }
3940}
4041
41- pub struct PipelineCache < P : Pipeline > {
42- pipeline : Arc < OnceLock < P > > ,
42+ #[ derive( Default , Clone ) ]
43+ pub struct PipelineCache {
44+ pipeline : Arc < OnceLock < Box < dyn Any + Send + Sync > > > ,
4345 executor : Arc < OnceLock < WgpuExecutor > > ,
4446}
4547
46- impl < P : Pipeline > PipelineCache < P > {
47- pub ( super ) fn init ( & self , executor : & WgpuExecutor ) {
48+ impl PipelineCache {
49+ pub ( super ) fn init < P : Pipeline > ( & self , executor : & WgpuExecutor ) {
4850 self . executor . get_or_init ( || executor. clone ( ) ) ;
51+ self . pipeline . get_or_init ( || Box :: new ( P :: create ( executor) ) ) ;
4952 }
5053
51- pub async fn run ( & self , args : & P :: Args < ' _ > ) -> P :: Out {
52- let executor = self . executor . get ( ) . expect ( "PipelineCache not initialized with an executor" ) ;
53- let pipeline = self . pipeline . get_or_init ( || P :: create ( executor) ) ;
54+ pub async fn run < P : Pipeline > ( & self , args : & P :: Args < ' _ > ) -> P :: Out {
55+ let executor = self . executor . get ( ) . expect ( "PipelineCache not initialized" ) ;
56+ let entry = self . pipeline . get ( ) . expect ( "PipelineCache not initialized" ) ;
57+ let pipeline = ( & * * entry)
58+ . downcast_ref :: < P > ( )
59+ . unwrap_or_else ( || panic ! ( "PipelineCache type mismatch: run::<{}>() but init used a different pipeline type" , std:: any:: type_name:: <P >( ) , ) ) ;
5460 pipeline. run ( executor, args) . await
5561 }
5662}
5763
58- impl < P : Pipeline > Default for PipelineCache < P > {
59- fn default ( ) -> Self {
60- Self {
61- pipeline : Arc :: new ( OnceLock :: new ( ) ) ,
62- executor : Arc :: new ( OnceLock :: new ( ) ) ,
63- }
64- }
65- }
66-
67- impl < P : Pipeline > Clone for PipelineCache < P > {
68- fn clone ( & self ) -> Self {
69- Self {
70- pipeline : self . pipeline . clone ( ) ,
71- executor : self . executor . clone ( ) ,
72- }
73- }
74- }
75-
76- impl < P : Pipeline > std:: fmt:: Debug for PipelineCache < P > {
64+ impl std:: fmt:: Debug for PipelineCache {
7765 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
78- f. debug_struct ( "PipelineCache" ) . field ( "type " , & std :: any :: type_name :: < P > ( ) ) . finish ( )
66+ f. debug_struct ( "PipelineCache" ) . field ( "initialized " , & self . pipeline . get ( ) . is_some ( ) ) . finish ( )
7967 }
8068}
8169
82- unsafe impl < P : Pipeline > StaticType for PipelineCache < P > {
83- type Static = PipelineCache < P > ;
70+ unsafe impl StaticType for PipelineCache {
71+ type Static = PipelineCache ;
8472}
0 commit comments