rafx_plugins/assets/font/
importer.rs

1use crate::assets::font::FontAssetData;
2use crate::schema::{FontAssetAccessor, FontAssetRecord, FontImportedDataRecord};
3use fnv::FnvHasher;
4use hydrate_base::AssetId;
5use hydrate_data::{Record, RecordAccessor};
6use hydrate_pipeline::{
7    AssetPlugin, AssetPluginSetupContext, Builder, BuilderContext, ImportContext, Importer,
8    JobInput, JobOutput, JobProcessor, PipelineResult, RunContext, ScanContext,
9};
10use serde::{Deserialize, Serialize};
11use std::hash::{Hash, Hasher};
12use std::sync::Arc;
13use type_uuid::*;
14
15#[derive(TypeUuid, Default)]
16#[uuid = "b99453db-4d59-4801-8b89-c86ba6fb4620"]
17pub struct FontImporter;
18
19impl Importer for FontImporter {
20    fn supported_file_extensions(&self) -> &[&'static str] {
21        &["ttf"]
22    }
23
24    fn scan_file(
25        &self,
26        context: ScanContext,
27    ) -> PipelineResult<()> {
28        context.add_default_importable::<FontAssetRecord>()?;
29        Ok(())
30    }
31
32    fn import_file(
33        &self,
34        context: ImportContext,
35    ) -> PipelineResult<()> {
36        //
37        // Read the file
38        //
39        let font_bytes = std::fs::read(context.path)?;
40
41        //
42        // Create the default asset
43        //
44        let default_asset = FontAssetRecord::new_builder(context.schema_set);
45
46        //
47        // Create import data
48        //
49        let import_data = FontImportedDataRecord::new_builder(context.schema_set);
50        import_data.bytes().set(Arc::new(font_bytes))?;
51
52        //
53        // Return the created objects
54        //
55        context
56            .add_default_importable(default_asset.into_inner()?, Some(import_data.into_inner()?));
57        Ok(())
58    }
59}
60
61#[derive(Hash, Serialize, Deserialize)]
62pub struct FontJobInput {
63    pub asset_id: AssetId,
64}
65impl JobInput for FontJobInput {}
66
67#[derive(Serialize, Deserialize)]
68pub struct FontJobOutput {}
69impl JobOutput for FontJobOutput {}
70
71#[derive(Default, TypeUuid)]
72#[uuid = "b49738d7-e5f6-4144-8fc6-83018802ef94"]
73pub struct FontJobProcessor;
74
75impl JobProcessor for FontJobProcessor {
76    type InputT = FontJobInput;
77    type OutputT = FontJobOutput;
78
79    fn version(&self) -> u32 {
80        1
81    }
82
83    fn run<'a>(
84        &self,
85        context: &'a RunContext<'a, Self::InputT>,
86    ) -> PipelineResult<FontJobOutput> {
87        //
88        // Read asset properties
89        //
90
91        //
92        // Read imported data
93        //
94        let imported_data =
95            context.imported_data::<FontImportedDataRecord>(context.input.asset_id)?;
96
97        let font_bytes = imported_data.bytes().get()?.clone();
98
99        let scale = 40i32;
100
101        let mut hasher = FnvHasher::default();
102        font_bytes.hash(&mut hasher);
103        scale.hash(&mut hasher);
104        let data_hash = hasher.finish();
105
106        //
107        // Create the processed data
108        //
109        let processed_data = FontAssetData {
110            data_hash,
111            data: (*font_bytes).clone(),
112            scale: scale as f32,
113        };
114
115        //
116        // Serialize and return
117        //
118        context.produce_default_artifact(context.input.asset_id, processed_data)?;
119
120        Ok(FontJobOutput {})
121    }
122}
123
124#[derive(TypeUuid, Default)]
125#[uuid = "834e2100-00b6-4d7b-8fbd-196ee8b998f1"]
126pub struct FontBuilder {}
127
128impl Builder for FontBuilder {
129    fn asset_type(&self) -> &'static str {
130        FontAssetAccessor::schema_name()
131    }
132
133    fn start_jobs(
134        &self,
135        context: BuilderContext,
136    ) -> PipelineResult<()> {
137        //Future: Might produce jobs per-platform
138        context.enqueue_job::<FontJobProcessor>(
139            context.data_set,
140            context.schema_set,
141            context.job_api,
142            FontJobInput {
143                asset_id: context.asset_id,
144            },
145        )?;
146        Ok(())
147    }
148}
149
150pub struct FontAssetPlugin;
151
152impl AssetPlugin for FontAssetPlugin {
153    fn setup(context: AssetPluginSetupContext) {
154        context.importer_registry.register_handler::<FontImporter>();
155        context.builder_registry.register_handler::<FontBuilder>();
156        context
157            .job_processor_registry
158            .register_job_processor::<FontJobProcessor>();
159    }
160}