-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
component: Use
generational-arena
for component storage
The `generational-arena` crate implements a generational index allocator which provides a "weak ref" for addressing a particular component, implemented in this PR in the form of `component::Handle`: <https://github.com/fitzgen/generational-arena> This also allows multiple simultaneous mutable references to components, so this PR additionally introduces `Component::register_dependency` which provides mutable refs to a component and its dependency for each enumerated dependency. In principle this is equivalent to "dependency injection". This PR removes the previous downcasting functionality, which was never tested and didn't seem to work out in practice. It should get added back, but in a form that actually works, with tests.
- Loading branch information
1 parent
776398f
commit d15c147
Showing
14 changed files
with
289 additions
and
138 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ description = """ | |
configuration, error handling, logging, and terminal interactions. | ||
This crate contains a CLI utility for generating new applications. | ||
""" | ||
version = "0.2.1" # Also update html_root_url in lib.rs when bumping this | ||
version = "0.3.0-rc.0" # Also update html_root_url in lib.rs when bumping this | ||
license = "Apache-2.0" | ||
authors = ["Tony Arcieri <[email protected]>"] | ||
edition = "2018" | ||
|
@@ -27,7 +27,7 @@ lazy_static = "1" | |
serde = { version = "1", features = ["serde_derive"] } | ||
|
||
[dependencies.abscissa_core] | ||
version = "0.2" | ||
version = "0.3.0-rc.0" | ||
path = "../core" | ||
|
||
[dev-dependencies.abscissa_core] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ description = """ | |
configuration, error handling, logging, and terminal interactions. | ||
This crate contains the framework's core functionality. | ||
""" | ||
version = "0.2.1" # Also update html_root_url in lib.rs when bumping this | ||
version = "0.3.0-rc.0" # Also update html_root_url in lib.rs when bumping this | ||
license = "Apache-2.0" | ||
authors = ["Tony Arcieri <[email protected]>"] | ||
edition = "2018" | ||
|
@@ -16,10 +16,11 @@ categories = ["command-line-interface", "rust-patterns"] | |
keywords = ["abscissa", "cli", "application", "framework", "service"] | ||
|
||
[dependencies] | ||
abscissa_derive = { version = "0.2", path = "../derive" } | ||
abscissa_derive = { version = "0.3.0-rc.0", path = "../derive" } | ||
canonical-path = "2" | ||
chrono = { version = "0.4", optional = true, features = ["serde"] } | ||
failure = "0.1" | ||
generational-arena = { version = "0.2", optional = true } | ||
gumdrop = { version = "0.6", optional = true } | ||
lazy_static = "1" | ||
log = { version = "0.4", optional = true, features = ["std"] } | ||
|
@@ -36,7 +37,7 @@ libc = { version = "0.2", optional = true } | |
signal-hook = { version = "0.1", optional = true } | ||
|
||
[features] | ||
default = ["application", "signals", "secrets", "testing", "time"] | ||
default = ["application", "generational-arena", "signals", "secrets", "testing", "time"] | ||
application = ["config", "logging", "options", "semver/serde", "terminal"] | ||
config = ["secrets", "serde", "terminal", "toml"] | ||
logging = ["log"] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
//! Component handles: opaque references to registered components | ||
|
||
use super::id::Id; | ||
use generational_arena::Index; | ||
use std::fmt; | ||
|
||
/// Component handles are references to components which have been registered | ||
/// with a `component::Registry`. | ||
/// | ||
/// However, unlike normal Rust references, component handles are a "weak" | ||
/// reference which is not checked by the borrow checker. This allows for | ||
/// complex reference graphs which are otherwise inexpressible in Rust. | ||
#[derive(Copy, Clone, Eq, Hash, PartialEq, Ord, PartialOrd)] | ||
pub struct Handle { | ||
/// Component name | ||
name: Id, | ||
|
||
/// Index in the registry's generational index allocator | ||
pub(super) index: Index, | ||
} | ||
|
||
impl Handle { | ||
/// Create a new handle from a component's name and index | ||
pub(crate) fn new(name: Id, index: Index) -> Self { | ||
Self { name, index } | ||
} | ||
|
||
/// Get the identifier of the component this handle points to | ||
pub fn id(self) -> Id { | ||
self.name | ||
} | ||
} | ||
|
||
impl fmt::Debug for Handle { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
write!(f, "Handle({})", self.id().as_ref()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
//! Component identifiers | ||
//! | ||
//! By convention these are Rust paths to the component types | ||
// TODO(tarcieri): enforce this convention via e.g. custom derive? | ||
|
||
use std::fmt; | ||
|
||
/// Identifier for an individual component | ||
/// | ||
/// This should ideally match the Rust path name to the corresponding type. | ||
// TODO(tarcieri): obtain this automatically via `std::module_path`? | ||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)] | ||
pub struct Id(&'static str); | ||
|
||
impl Id { | ||
/// Create a new component identifier | ||
// TODO(tarcieri): make this method private in the future | ||
pub fn new(id: &'static str) -> Id { | ||
Id(id) | ||
} | ||
} | ||
|
||
impl AsRef<str> for Id { | ||
fn as_ref(&self) -> &str { | ||
self.0 | ||
} | ||
} | ||
|
||
impl fmt::Display for Id { | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
write!(f, "{}", self.0) | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.