1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Carnelian
//!
//! Carnelian is a prototype framework for writing
//! [Fuchsia](https://fuchsia.dev/fuchsia-src/concepts)
//! applications in
//! [Rust](https://www.rust-lang.org/).
//!
//! Below is a tiny example of a Carnelian app.
//!
//! The [`ViewAssistant`] trait is a good place to start when learning
//! about Carnelian.
//!
//! ```no_run
//! use anyhow::Error;
//! use carnelian::{
//!     make_app_assistant,
//!     render::{self},
//!     App, AppAssistant, ViewAssistant, ViewAssistantContext, ViewAssistantPtr, ViewKey,
//! };
//! use fuchsia_zircon::Event;
//!
//! #[derive(Default)]
//! struct SampleAppAssistant;
//!
//! impl AppAssistant for SampleAppAssistant {
//!     fn setup(&mut self) -> Result<(), Error> {
//!         Ok(())
//!     }
//!
//!     fn create_view_assistant(&mut self, _: ViewKey) -> Result<ViewAssistantPtr, Error> {
//!         SampleViewAssistant::new()
//!     }
//! }
//!
//! struct SampleViewAssistant;
//!
//! impl SampleViewAssistant {
//!     fn new() -> Result<ViewAssistantPtr, Error> {
//!         Ok(Box::new(Self {}))
//!     }
//! }
//!
//! impl ViewAssistant for SampleViewAssistant {
//!     fn render(
//!         &mut self,
//!         _render_context: &mut render::Context,
//!         _buffer_ready_event: Event,
//!         _view_context: &ViewAssistantContext,
//!     ) -> Result<(), Error> {
//!         Ok(())
//!     }
//! }
//!
//! fn main() -> Result<(), Error> {
//!     App::run(make_app_assistant::<SampleAppAssistant>())
//! }
//! ```

#![deny(missing_docs)]

use std::{
    marker::PhantomData,
    sync::atomic::{AtomicU64, Ordering},
};

/// Application related items
pub mod app;
/// Color-related items
pub mod color;
/// Drawing-related items
pub mod drawing;
/// Geometry-related items.
pub mod geometry;
/// Input-related items.
pub mod input;
/// Extension items related to input.
pub mod input_ext;
mod message;
/// Render-related items.
pub mod render;
/// UI item abstraction
pub mod scene;
mod view;

pub(crate) trait IdFromRaw {
    fn from_raw(id: u64) -> Self;
}

#[derive(Default)]
pub(crate) struct IdGenerator2<T> {
    id_type: PhantomData<T>,
}

impl<T> IdGenerator2<T>
where
    T: IdFromRaw + std::fmt::Debug,
{
    fn next() -> Option<T> {
        static NEXT_ID: AtomicU64 = AtomicU64::new(100);
        let id = NEXT_ID.fetch_add(1, Ordering::SeqCst);
        // fetch_add wraps on overflow, which we'll use as a signal
        // that this generator is out of ids.
        if id == 0 {
            None
        } else {
            Some(T::from_raw(id))
        }
    }
}

pub use crate::{
    app::{
        make_app_assistant, App, AppAssistant, AppAssistantPtr, AppSender, AssistantCreator,
        AssistantCreatorFunc, LocalBoxFuture, MessageTarget,
    },
    geometry::{Coord, IntCoord, IntPoint, IntRect, IntSize, Point, Rect, Size},
    message::{make_message, Message},
    view::{ViewAssistant, ViewAssistantContext, ViewAssistantPtr, ViewKey},
};