forked from Orchid/orchid
Progress mostly on atom repr
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -286,6 +286,7 @@ name = "orchid-extension"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
|
"derive_destructure",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"itertools",
|
"itertools",
|
||||||
"orchid-api",
|
"orchid-api",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use orchid_api_traits::Request;
|
|||||||
use crate::atom::Atom;
|
use crate::atom::Atom;
|
||||||
use crate::intern::{TStr, TStrv};
|
use crate::intern::{TStr, TStrv};
|
||||||
use crate::location::Location;
|
use crate::location::Location;
|
||||||
use crate::proto::ExtHostReq;
|
use crate::proto::{ExtHostNotif, ExtHostReq};
|
||||||
use crate::system::SysId;
|
use crate::system::SysId;
|
||||||
|
|
||||||
/// An arbitrary ID associated with an expression on the host side. Incoming
|
/// An arbitrary ID associated with an expression on the host side. Incoming
|
||||||
@@ -25,7 +25,8 @@ pub type ExprTicket = u64;
|
|||||||
///
|
///
|
||||||
/// This can be called with a foreign system to signal that an owned reference
|
/// This can be called with a foreign system to signal that an owned reference
|
||||||
/// is being passed, though [Relocate] may be a better fit.
|
/// is being passed, though [Relocate] may be a better fit.
|
||||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding)]
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
|
||||||
|
#[extends(ExprNotif, ExtHostNotif)]
|
||||||
pub struct Acquire(pub SysId, pub ExprTicket);
|
pub struct Acquire(pub SysId, pub ExprTicket);
|
||||||
|
|
||||||
/// Release a reference either previously acquired through either [Acquire]
|
/// Release a reference either previously acquired through either [Acquire]
|
||||||
@@ -33,13 +34,15 @@ pub struct Acquire(pub SysId, pub ExprTicket);
|
|||||||
/// acquired an expression is counted, and it is the system's responsibility to
|
/// acquired an expression is counted, and it is the system's responsibility to
|
||||||
/// ensure that acquires and releases pair up. Behaviour in case of excessive
|
/// ensure that acquires and releases pair up. Behaviour in case of excessive
|
||||||
/// freeing is not defined.
|
/// freeing is not defined.
|
||||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding)]
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
|
||||||
|
#[extends(ExprNotif, ExtHostNotif)]
|
||||||
pub struct Release(pub SysId, pub ExprTicket);
|
pub struct Release(pub SysId, pub ExprTicket);
|
||||||
|
|
||||||
/// Decrement the reference count for one system and increment it for another,
|
/// Decrement the reference count for one system and increment it for another,
|
||||||
/// to indicate passing an owned reference. Equivalent to [Acquire] followed by
|
/// to indicate passing an owned reference. Equivalent to [Acquire] followed by
|
||||||
/// [Release].
|
/// [Release].
|
||||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding)]
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
|
||||||
|
#[extends(ExprNotif, ExtHostNotif)]
|
||||||
pub struct Relocate {
|
pub struct Relocate {
|
||||||
pub dec: SysId,
|
pub dec: SysId,
|
||||||
pub inc: SysId,
|
pub inc: SysId,
|
||||||
@@ -91,7 +94,9 @@ pub enum ExprReq {
|
|||||||
Inspect(Inspect),
|
Inspect(Inspect),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding)]
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Coding, Hierarchy)]
|
||||||
|
#[extends(ExtHostNotif)]
|
||||||
|
#[extendable]
|
||||||
pub enum ExprNotif {
|
pub enum ExprNotif {
|
||||||
Acquire(Acquire),
|
Acquire(Acquire),
|
||||||
Release(Release),
|
Release(Release),
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
use derive_more::{From, TryInto};
|
|
||||||
use orchid_api_derive::{Coding, Hierarchy};
|
use orchid_api_derive::{Coding, Hierarchy};
|
||||||
use orchid_api_traits::{read_exact, write_exact, Channel, Decode, Encode, MsgSet, Request};
|
use orchid_api_traits::{read_exact, write_exact, Channel, Decode, Encode, MsgSet, Request};
|
||||||
|
|
||||||
@@ -77,10 +76,11 @@ pub enum ExtHostReq {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Notifications sent from the extension to the host
|
/// Notifications sent from the extension to the host
|
||||||
#[derive(Debug, Clone, Coding, From, TryInto)]
|
#[derive(Debug, Clone, Coding, Hierarchy)]
|
||||||
#[allow(clippy::enum_variant_names)]
|
#[allow(clippy::enum_variant_names)]
|
||||||
|
#[extendable]
|
||||||
pub enum ExtHostNotif {
|
pub enum ExtHostNotif {
|
||||||
Expr(expr::ExprNotif),
|
ExprNotif(expr::ExprNotif),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExtHostChannel;
|
pub struct ExtHostChannel;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ahash = "0.8.11"
|
ahash = "0.8.11"
|
||||||
|
derive_destructure = "1.0.0"
|
||||||
hashbrown = "0.14.5"
|
hashbrown = "0.14.5"
|
||||||
itertools = "0.12.1"
|
itertools = "0.12.1"
|
||||||
orchid-api = { version = "0.1.0", path = "../orchid-api" }
|
orchid-api = { version = "0.1.0", path = "../orchid-api" }
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
use std::any::TypeId;
|
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
use itertools::Itertools;
|
use derive_destructure::destructure;
|
||||||
use orchid_api::expr::Expr;
|
use orchid_api::atom::{Atom, Fwd};
|
||||||
|
use orchid_api::expr::{ExprTicket, Release};
|
||||||
use orchid_api::proto::ExtMsgSet;
|
use orchid_api::proto::ExtMsgSet;
|
||||||
use orchid_api::system::{NewSystem, SysId, SystemDecl};
|
use orchid_api::system::SysId;
|
||||||
use orchid_api_traits::Coding;
|
use orchid_api_traits::{Coding, Decode, Request};
|
||||||
use orchid_base::reqnot::ReqNot;
|
use orchid_base::reqnot::{ReqNot, Requester};
|
||||||
use ordered_float::NotNan;
|
|
||||||
|
|
||||||
pub struct SystemHandle<T: SystemDepCard> {
|
pub struct SystemHandle<T: SystemDepCard> {
|
||||||
_t: PhantomData<T>,
|
_t: PhantomData<T>,
|
||||||
@@ -16,122 +15,69 @@ pub struct SystemHandle<T: SystemDepCard> {
|
|||||||
reqnot: ReqNot<ExtMsgSet>,
|
reqnot: ReqNot<ExtMsgSet>,
|
||||||
}
|
}
|
||||||
impl<T: SystemDepCard> SystemHandle<T> {
|
impl<T: SystemDepCard> SystemHandle<T> {
|
||||||
fn new(id: SysId, reqnot: ReqNot<ExtMsgSet>) -> Self { Self { _t: PhantomData, id, reqnot } }
|
pub(crate) fn new(id: SysId, reqnot: ReqNot<ExtMsgSet>) -> Self {
|
||||||
|
Self { _t: PhantomData, id, reqnot }
|
||||||
|
}
|
||||||
|
pub fn id(&self) -> SysId { self.id }
|
||||||
|
pub fn wrap_atom<A: Atomic<Owner = T>>(
|
||||||
|
&self,
|
||||||
|
api: Atom,
|
||||||
|
ticket: ExprTicket,
|
||||||
|
) -> Result<OwnedAtom<A>, Atom> {
|
||||||
|
if api.owner == self.id {
|
||||||
|
Ok(OwnedAtom { ticket, sys: self.clone(), value: T::decode_atom(&api), api })
|
||||||
|
} else {
|
||||||
|
Err(api)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T: SystemDepCard> Clone for SystemHandle<T> {
|
||||||
|
fn clone(&self) -> Self { Self { reqnot: self.reqnot.clone(), _t: PhantomData, id: self.id } }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait System: Send {
|
pub trait Atomic: 'static {
|
||||||
fn consts(&self) -> Expr;
|
type Owner: SystemDepCard;
|
||||||
|
type Req: Coding;
|
||||||
|
const HAS_DROP: bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SystemParams<Ctor: SystemCtor + ?Sized> {
|
pub trait SystemDepCard: 'static {
|
||||||
pub deps: <Ctor::Deps as DepSet>::Sat,
|
|
||||||
pub id: SysId,
|
|
||||||
pub reqnot: ReqNot<ExtMsgSet>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait SystemDepCard {
|
|
||||||
type IngressReq: Coding;
|
|
||||||
type IngressNotif: Coding;
|
|
||||||
const NAME: &'static str;
|
const NAME: &'static str;
|
||||||
|
/// Decode an atom from binary representation.
|
||||||
|
///
|
||||||
|
/// This is held in the dep card because there is no global type tag on the
|
||||||
|
/// atom, so by the logic of the binary coding algorithm the value has to be a
|
||||||
|
/// concrete type, probably an enum of the viable types.
|
||||||
|
fn decode_atom<A: Atomic<Owner = Self>>(api: &Atom) -> A;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DepSet {
|
#[derive(destructure)]
|
||||||
type Sat;
|
pub struct OwnedAtom<A: Atomic> {
|
||||||
fn report(names: &mut impl FnMut(&'static str));
|
sys: SystemHandle<A::Owner>,
|
||||||
fn create(take: &mut impl FnMut() -> SysId, reqnot: ReqNot<ExtMsgSet>) -> Self::Sat;
|
ticket: ExprTicket,
|
||||||
|
api: Atom,
|
||||||
|
value: A,
|
||||||
}
|
}
|
||||||
|
impl<A: Atomic> OwnedAtom<A> {
|
||||||
impl<T: SystemDepCard> DepSet for T {
|
/// Unpack the object, returning the held atom and expr ticket. This is in
|
||||||
type Sat = SystemHandle<Self>;
|
/// contrast to dropping the atom which releases the expr ticket.
|
||||||
fn report(names: &mut impl FnMut(&'static str)) { names(T::NAME) }
|
pub fn unpack(self) -> (A, ExprTicket, Atom) {
|
||||||
fn create(take: &mut impl FnMut() -> SysId, reqnot: ReqNot<ExtMsgSet>) -> Self::Sat {
|
let (_, ticket, api, value) = self.destructure();
|
||||||
SystemHandle::new(take(), reqnot)
|
(value, ticket, api)
|
||||||
|
}
|
||||||
|
pub fn ticket(&self) -> ExprTicket { self.ticket }
|
||||||
|
pub fn request<R: Coding + Into<A::Req> + Request>(&self, req: R) -> R::Response {
|
||||||
|
R::Response::decode(&mut &self.sys.reqnot.request(Fwd(self.api.clone(), req.enc_vec()))[..])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<A: Atomic> Deref for OwnedAtom<A> {
|
||||||
pub trait SystemCtor: Send {
|
type Target = A;
|
||||||
type Deps: DepSet;
|
fn deref(&self) -> &Self::Target { &self.value }
|
||||||
const NAME: &'static str;
|
|
||||||
const VERSION: f64;
|
|
||||||
#[allow(clippy::new_ret_no_self)]
|
|
||||||
fn new(params: SystemParams<Self>) -> Box<dyn System>;
|
|
||||||
}
|
}
|
||||||
|
impl<A: Atomic> Drop for OwnedAtom<A> {
|
||||||
pub trait DynSystemCtor: Send {
|
fn drop(&mut self) {
|
||||||
fn decl(&self) -> SystemDecl;
|
if A::HAS_DROP {
|
||||||
fn new_system(&self, new: &NewSystem, reqnot: ReqNot<ExtMsgSet>) -> Box<dyn System>;
|
self.sys.reqnot.notify(Release(self.sys.id(), self.ticket))
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: SystemCtor + 'static> DynSystemCtor for T {
|
|
||||||
fn decl(&self) -> SystemDecl {
|
|
||||||
// Version is equivalent to priority for all practical purposes
|
|
||||||
let priority = NotNan::new(T::VERSION).unwrap();
|
|
||||||
// aggregate depends names
|
|
||||||
let mut depends = Vec::new();
|
|
||||||
T::Deps::report(&mut |n| depends.push(n.to_string()));
|
|
||||||
// generate definitely unique id
|
|
||||||
let mut ahash = ahash::AHasher::default();
|
|
||||||
TypeId::of::<T>().hash(&mut ahash);
|
|
||||||
let id = (ahash.finish().to_be_bytes().into_iter().tuples())
|
|
||||||
.map(|(l, b)| u16::from_be_bytes([l, b]))
|
|
||||||
.fold(0, |a, b| a ^ b);
|
|
||||||
SystemDecl { name: T::NAME.to_string(), depends, id, priority }
|
|
||||||
}
|
}
|
||||||
fn new_system(&self, new: &NewSystem, reqnot: ReqNot<ExtMsgSet>) -> Box<dyn System> {
|
|
||||||
let mut ids = new.depends.iter().copied();
|
|
||||||
T::new(SystemParams {
|
|
||||||
deps: T::Deps::create(&mut || ids.next().unwrap(), reqnot.clone()),
|
|
||||||
id: new.id,
|
|
||||||
reqnot,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExtensionData {
|
|
||||||
pub systems: Vec<Box<dyn DynSystemCtor>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
mod dep_set_tuple_impls {
|
|
||||||
use orchid_api::proto::ExtMsgSet;
|
|
||||||
use orchid_api::system::SysId;
|
|
||||||
use orchid_base::reqnot::ReqNot;
|
|
||||||
|
|
||||||
use super::DepSet;
|
|
||||||
|
|
||||||
macro_rules! dep_set_tuple_impl {
|
|
||||||
($($name:ident),*) => {
|
|
||||||
impl<$( $name :DepSet ),*> DepSet for ( $( $name , )* ) {
|
|
||||||
type Sat = ( $( $name ::Sat , )* );
|
|
||||||
fn report(names: &mut impl FnMut(&'static str)) {
|
|
||||||
$(
|
|
||||||
$name ::report(names);
|
|
||||||
)*
|
|
||||||
}
|
|
||||||
fn create(take: &mut impl FnMut() -> SysId, reqnot: ReqNot<ExtMsgSet>) -> Self::Sat {
|
|
||||||
(
|
|
||||||
$(
|
|
||||||
$name ::create(take, reqnot.clone()),
|
|
||||||
)*
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
dep_set_tuple_impl!(A);
|
|
||||||
dep_set_tuple_impl!(A, B); // 2
|
|
||||||
dep_set_tuple_impl!(A, B, C);
|
|
||||||
dep_set_tuple_impl!(A, B, C, D); // 4
|
|
||||||
dep_set_tuple_impl!(A, B, C, D, E);
|
|
||||||
dep_set_tuple_impl!(A, B, C, D, E, F);
|
|
||||||
dep_set_tuple_impl!(A, B, C, D, E, F, G);
|
|
||||||
dep_set_tuple_impl!(A, B, C, D, E, F, G, H); // 8
|
|
||||||
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I);
|
|
||||||
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J);
|
|
||||||
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J, K);
|
|
||||||
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L); // 12
|
|
||||||
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M);
|
|
||||||
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
|
|
||||||
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
|
|
||||||
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P); // 16
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,8 +9,12 @@ use orchid_base::clone;
|
|||||||
use orchid_base::intern::{init_replica, sweep_replica};
|
use orchid_base::intern::{init_replica, sweep_replica};
|
||||||
use orchid_base::reqnot::{ReqNot, Requester};
|
use orchid_base::reqnot::{ReqNot, Requester};
|
||||||
|
|
||||||
use crate::data::ExtensionData;
|
|
||||||
use crate::msg::{recv_parent_msg, send_parent_msg};
|
use crate::msg::{recv_parent_msg, send_parent_msg};
|
||||||
|
use crate::system_ctor::DynSystemCtor;
|
||||||
|
|
||||||
|
pub struct ExtensionData {
|
||||||
|
pub systems: Vec<Box<dyn DynSystemCtor>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn main(data: ExtensionData) {
|
pub fn main(data: ExtensionData) {
|
||||||
HostHeader::decode(&mut &recv_parent_msg().unwrap()[..]);
|
HostHeader::decode(&mut &recv_parent_msg().unwrap()[..]);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
pub mod entrypoint;
|
pub mod entrypoint;
|
||||||
pub mod data;
|
pub mod data;
|
||||||
pub mod msg;
|
pub mod msg;
|
||||||
|
pub mod system_ctor;
|
||||||
|
pub mod system;
|
||||||
|
|||||||
6
orchid-extension/src/system.rs
Normal file
6
orchid-extension/src/system.rs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
use orchid_api::expr::Expr;
|
||||||
|
|
||||||
|
pub trait System: Send {
|
||||||
|
fn consts(&self) -> Expr;
|
||||||
|
}
|
||||||
|
|
||||||
114
orchid-extension/src/system_ctor.rs
Normal file
114
orchid-extension/src/system_ctor.rs
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
use std::any::TypeId;
|
||||||
|
use std::hash::{Hash as _, Hasher as _};
|
||||||
|
|
||||||
|
use itertools::Itertools as _;
|
||||||
|
use orchid_api::proto::ExtMsgSet;
|
||||||
|
use orchid_api::system::{NewSystem, SysId, SystemDecl};
|
||||||
|
use orchid_base::reqnot::ReqNot;
|
||||||
|
use ordered_float::NotNan;
|
||||||
|
|
||||||
|
use crate::data::{SystemDepCard, SystemHandle};
|
||||||
|
use crate::system::System;
|
||||||
|
|
||||||
|
pub struct SystemParams<Ctor: SystemCtor + ?Sized> {
|
||||||
|
pub deps: <Ctor::Deps as DepSet>::Sat,
|
||||||
|
pub id: SysId,
|
||||||
|
pub reqnot: ReqNot<ExtMsgSet>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait DepSet {
|
||||||
|
type Sat;
|
||||||
|
fn report(names: &mut impl FnMut(&'static str));
|
||||||
|
fn create(take: &mut impl FnMut() -> SysId, reqnot: ReqNot<ExtMsgSet>) -> Self::Sat;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: SystemDepCard> DepSet for T {
|
||||||
|
type Sat = SystemHandle<Self>;
|
||||||
|
fn report(names: &mut impl FnMut(&'static str)) { names(T::NAME) }
|
||||||
|
fn create(take: &mut impl FnMut() -> SysId, reqnot: ReqNot<ExtMsgSet>) -> Self::Sat {
|
||||||
|
SystemHandle::new(take(), reqnot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SystemCtor: Send + 'static {
|
||||||
|
type Deps: DepSet;
|
||||||
|
const NAME: &'static str;
|
||||||
|
const VERSION: f64;
|
||||||
|
#[allow(clippy::new_ret_no_self)]
|
||||||
|
fn new(params: SystemParams<Self>) -> Box<dyn System>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait DynSystemCtor: Send + 'static {
|
||||||
|
fn decl(&self) -> SystemDecl;
|
||||||
|
fn new_system(&self, new: &NewSystem, reqnot: ReqNot<ExtMsgSet>) -> Box<dyn System>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: SystemCtor> DynSystemCtor for T {
|
||||||
|
fn decl(&self) -> SystemDecl {
|
||||||
|
// Version is equivalent to priority for all practical purposes
|
||||||
|
let priority = NotNan::new(T::VERSION).unwrap();
|
||||||
|
// aggregate depends names
|
||||||
|
let mut depends = Vec::new();
|
||||||
|
T::Deps::report(&mut |n| depends.push(n.to_string()));
|
||||||
|
// generate definitely unique id
|
||||||
|
let mut ahash = ahash::AHasher::default();
|
||||||
|
TypeId::of::<T>().hash(&mut ahash);
|
||||||
|
let id = (ahash.finish().to_be_bytes().into_iter().tuples())
|
||||||
|
.map(|(l, b)| u16::from_be_bytes([l, b]))
|
||||||
|
.fold(0, |a, b| a ^ b);
|
||||||
|
SystemDecl { name: T::NAME.to_string(), depends, id, priority }
|
||||||
|
}
|
||||||
|
fn new_system(&self, new: &NewSystem, reqnot: ReqNot<ExtMsgSet>) -> Box<dyn System> {
|
||||||
|
let mut ids = new.depends.iter().copied();
|
||||||
|
T::new(SystemParams {
|
||||||
|
deps: T::Deps::create(&mut || ids.next().unwrap(), reqnot.clone()),
|
||||||
|
id: new.id,
|
||||||
|
reqnot,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod dep_set_tuple_impls {
|
||||||
|
use orchid_api::proto::ExtMsgSet;
|
||||||
|
use orchid_api::system::SysId;
|
||||||
|
use orchid_base::reqnot::ReqNot;
|
||||||
|
|
||||||
|
use super::DepSet;
|
||||||
|
|
||||||
|
macro_rules! dep_set_tuple_impl {
|
||||||
|
($($name:ident),*) => {
|
||||||
|
impl<$( $name :DepSet ),*> DepSet for ( $( $name , )* ) {
|
||||||
|
type Sat = ( $( $name ::Sat , )* );
|
||||||
|
fn report(names: &mut impl FnMut(&'static str)) {
|
||||||
|
$(
|
||||||
|
$name ::report(names);
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
fn create(take: &mut impl FnMut() -> SysId, reqnot: ReqNot<ExtMsgSet>) -> Self::Sat {
|
||||||
|
(
|
||||||
|
$(
|
||||||
|
$name ::create(take, reqnot.clone()),
|
||||||
|
)*
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
dep_set_tuple_impl!(A);
|
||||||
|
dep_set_tuple_impl!(A, B); // 2
|
||||||
|
dep_set_tuple_impl!(A, B, C);
|
||||||
|
dep_set_tuple_impl!(A, B, C, D); // 4
|
||||||
|
dep_set_tuple_impl!(A, B, C, D, E);
|
||||||
|
dep_set_tuple_impl!(A, B, C, D, E, F);
|
||||||
|
dep_set_tuple_impl!(A, B, C, D, E, F, G);
|
||||||
|
dep_set_tuple_impl!(A, B, C, D, E, F, G, H); // 8
|
||||||
|
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I);
|
||||||
|
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J);
|
||||||
|
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J, K);
|
||||||
|
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L); // 12
|
||||||
|
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M);
|
||||||
|
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
|
||||||
|
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
|
||||||
|
dep_set_tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P); // 16
|
||||||
|
}
|
||||||
@@ -120,24 +120,20 @@ impl Extension {
|
|||||||
g.stdin.as_mut().unwrap().write_all(sfn).unwrap();
|
g.stdin.as_mut().unwrap().write_all(sfn).unwrap();
|
||||||
}),
|
}),
|
||||||
|notif, _| match notif {
|
|notif, _| match notif {
|
||||||
ExtHostNotif::Expr(expr) => match expr {
|
ExtHostNotif::ExprNotif(ExprNotif::Acquire(Acquire(sys, extk))) => acq_expr(sys, extk),
|
||||||
ExprNotif::Acquire(Acquire(sys, extk)) => acq_expr(sys, extk),
|
ExtHostNotif::ExprNotif(ExprNotif::Release(Release(sys, extk))) => rel_expr(sys, extk),
|
||||||
ExprNotif::Release(Release(sys, extk)) => rel_expr(sys, extk),
|
ExtHostNotif::ExprNotif(ExprNotif::Relocate(Relocate { dec, inc, expr })) => {
|
||||||
ExprNotif::Relocate(Relocate { inc, dec, expr }) => {
|
|
||||||
acq_expr(inc, expr);
|
acq_expr(inc, expr);
|
||||||
rel_expr(dec, expr);
|
rel_expr(dec, expr);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
|req| match req.req() {
|
|req| match req.req() {
|
||||||
ExtHostReq::Ping(ping) => req.handle(ping, &()),
|
ExtHostReq::Ping(ping) => req.handle(ping, &()),
|
||||||
ExtHostReq::IntReq(intreq) => match intreq {
|
ExtHostReq::IntReq(IntReq::InternStr(s)) => req.handle(s, &intern(&**s.0).marker()),
|
||||||
IntReq::InternStr(s) => req.handle(s, &intern(&**s.0).marker()),
|
ExtHostReq::IntReq(IntReq::InternStrv(v)) => req.handle(v, &intern(&*v.0).marker()),
|
||||||
IntReq::InternStrv(v) => req.handle(v, &intern(&*v.0).marker()),
|
ExtHostReq::IntReq(IntReq::ExternStr(si)) => req.handle(si, &deintern(si.0).arc()),
|
||||||
IntReq::ExternStr(si) => req.handle(si, &deintern(si.0).arc()),
|
ExtHostReq::IntReq(IntReq::ExternStrv(vi)) =>
|
||||||
IntReq::ExternStrv(vi) =>
|
|
||||||
req.handle(vi, &Arc::new(deintern(vi.0).iter().map(|t| t.marker()).collect_vec())),
|
req.handle(vi, &Arc::new(deintern(vi.0).iter().map(|t| t.marker()).collect_vec())),
|
||||||
},
|
|
||||||
ExtHostReq::Fwd(fw @ Fwd(atom, _body)) => {
|
ExtHostReq::Fwd(fw @ Fwd(atom, _body)) => {
|
||||||
let sys = System::resolve(atom.owner).unwrap();
|
let sys = System::resolve(atom.owner).unwrap();
|
||||||
thread::spawn(clone!(fw; move || {
|
thread::spawn(clone!(fw; move || {
|
||||||
|
|||||||
Reference in New Issue
Block a user