assets.rs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. use dioxus_core::prelude::{Runtime, RuntimeGuard, ScopeId};
  2. use rustc_hash::FxHashMap;
  3. use std::{cell::RefCell, rc::Rc};
  4. use wry::{http::Request, RequestAsyncResponder};
  5. ///
  6. pub type AssetRequest = Request<Vec<u8>>;
  7. pub struct AssetHandler {
  8. f: Box<dyn Fn(AssetRequest, RequestAsyncResponder) + 'static>,
  9. scope: ScopeId,
  10. }
  11. #[derive(Clone)]
  12. pub struct AssetHandlerRegistry {
  13. dom_rt: Rc<Runtime>,
  14. handlers: Rc<RefCell<FxHashMap<String, AssetHandler>>>,
  15. }
  16. impl AssetHandlerRegistry {
  17. pub fn new(dom_rt: Rc<Runtime>) -> Self {
  18. AssetHandlerRegistry {
  19. dom_rt,
  20. handlers: Default::default(),
  21. }
  22. }
  23. pub fn has_handler(&self, name: &str) -> bool {
  24. self.handlers.borrow().contains_key(name)
  25. }
  26. pub fn handle_request(
  27. &self,
  28. name: &str,
  29. request: AssetRequest,
  30. responder: RequestAsyncResponder,
  31. ) {
  32. if let Some(handler) = self.handlers.borrow().get(name) {
  33. // make sure the runtime is alive for the duration of the handler
  34. // We should do this for all the things - not just asset handlers
  35. RuntimeGuard::with(self.dom_rt.clone(), Some(handler.scope), || {
  36. (handler.f)(request, responder)
  37. });
  38. }
  39. }
  40. pub fn register_handler(
  41. &self,
  42. name: String,
  43. f: Box<dyn Fn(AssetRequest, RequestAsyncResponder) + 'static>,
  44. scope: ScopeId,
  45. ) {
  46. self.handlers
  47. .borrow_mut()
  48. .insert(name, AssetHandler { f, scope });
  49. }
  50. pub fn remove_handler(&self, name: &str) -> Option<AssetHandler> {
  51. self.handlers.borrow_mut().remove(name)
  52. }
  53. }