Created
August 5, 2019 23:45
-
-
Save piscisaureus/5f1fc257e57cb976ec446eed03fb76f5 to your computer and use it in GitHub Desktop.
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
use std::collections::HashMap; | |
use std::sync::Mutex; | |
#[macro_use] | |
extern crate lazy_static; | |
struct CoreOp {} // Placeholder. | |
struct FlatBuffer {} // Placeholder. | |
struct PinnedBuf {} // Placeholder. | |
impl FlatBuffer { | |
fn parse(_blob: &[u8]) -> Self { | |
unimplemented!() | |
} | |
} | |
// Use a separate trait to give the op a name, because a trait object | |
// object (dyn Opdispatcher) can't have associated constants. | |
trait NamedOpDispatcher: OpDispatcher { | |
const NAME: &'static str; | |
} | |
trait OpDispatcher: Send + Sync { | |
fn dispatch(&self, args: &[u8], buf: Option<PinnedBuf>) -> CoreOp; | |
} | |
trait FlatBufferOpDispatcher: Send + Sync { | |
fn dispatch_flatbuffer(&self, fb: &FlatBuffer, buf: Option<PinnedBuf>) -> CoreOp; | |
} | |
impl<T> OpDispatcher for T | |
where | |
T: FlatBufferOpDispatcher, | |
{ | |
fn dispatch(&self, args: &[u8], buf: Option<PinnedBuf>) -> CoreOp { | |
let fb = FlatBuffer::parse(args); // Or something like that. | |
return self.dispatch_flatbuffer(&fb, buf); | |
} | |
} | |
fn register_op<D: NamedOpDispatcher + 'static>(d: D) { | |
// Rather than having a global registry, I think it should be per-isolate. | |
lazy_static! { | |
static ref OP_REGISTRY: Mutex<HashMap<&'static str, Box<dyn OpDispatcher>>> = | |
Mutex::new(HashMap::new()); | |
} | |
OP_REGISTRY | |
.lock() | |
.unwrap() | |
.entry(D::NAME) | |
.and_modify(|_| panic!("Op already registered")) | |
.or_insert(Box::new(d)); | |
} | |
// Example implements OpDispatcher. | |
struct BasicOpDispatcherExample; | |
impl NamedOpDispatcher for BasicOpDispatcherExample { | |
const NAME: &'static str = "Basic"; | |
} | |
impl OpDispatcher for BasicOpDispatcherExample { | |
fn dispatch(&self, _args: &[u8], _buf: Option<PinnedBuf>) -> CoreOp { | |
unimplemented!() | |
} | |
} | |
// Example implements FlatBufferOpDispatcher. | |
struct SomeFlatBufferOpDispatcher; | |
impl NamedOpDispatcher for SomeFlatBufferOpDispatcher { | |
const NAME: &'static str = "FB"; | |
} | |
impl FlatBufferOpDispatcher for SomeFlatBufferOpDispatcher { | |
fn dispatch_flatbuffer(&self, _fb: &FlatBuffer, _buf: Option<PinnedBuf>) -> CoreOp { | |
unimplemented!() | |
} | |
} | |
fn main() { | |
register_op(BasicOpDispatcherExample); | |
register_op(SomeFlatBufferOpDispatcher); | |
register_op(SomeFlatBufferOpDispatcher); // Crash. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Namespacing maybe?
New dlopen/plugins code would be something like this: