move Optional out of spirv_backend and into coremem_types

This commit is contained in:
2022-07-25 00:35:04 -07:00
parent 9c7ef7ec88
commit 5490634fe7
8 changed files with 98 additions and 90 deletions

View File

@@ -1,12 +1,12 @@
use serde::{Deserialize, Serialize};
use crate::geom::Index;
use coremem_types::compound::Optional;
use coremem_types::vec::{Vec3, Vec3u};
/// hide the actual spirv backend structures inside a submodule to make their use/boundary clear.
mod ffi {
pub use spirv_backend::{entry_points, SerializedSimMeta};
pub use spirv_backend::support::Optional;
}
// conversion traits for types defined cross-lib
@@ -43,16 +43,16 @@ impl<T: Identity> Identity for Vec3<T> {}
impl<L: IntoFfi> IntoFfi for Option<L>
where L::Ffi: Default
{
type Ffi = ffi::Optional<L::Ffi>;
type Ffi = Optional<L::Ffi>;
fn into_ffi(self) -> Self::Ffi {
match self {
Some(s) => ffi::Optional::some(s.into_ffi()),
None => ffi::Optional::none(),
Some(s) => Optional::some(s.into_ffi()),
None => Optional::none(),
}
}
}
impl<F: Copy + IntoLib> IntoLib for ffi::Optional<F> {
impl<F: Copy + IntoLib> IntoLib for Optional<F> {
type Lib = Option<F::Lib>;
fn into_lib(self) -> Self::Lib {
if self.is_some() {

View File

@@ -1,5 +1,6 @@
use crate::sim::{StepEContext, StepHContext, VolumeSampleNeg, VolumeSamplePos};
use crate::support::{Array3, Array3Mut, Optional, UnsizedArray};
use crate::support::{Array3, Array3Mut, UnsizedArray};
use coremem_types::compound::Optional;
use coremem_types::mat::Material;
use coremem_types::real::Real;
use coremem_types::vec::{Vec3, Vec3u};

View File

@@ -17,8 +17,9 @@ pub mod sim;
pub mod support;
pub use adapt::SerializedSimMeta;
pub use support::{Optional, UnsizedArray};
pub use support::UnsizedArray;
use coremem_types::compound::Optional;
use coremem_types::mat::{Ferroxcube3R1MH, FullyGenericMaterial, IsoConductorOr};
use coremem_types::vec::{Vec3, Vec3u};

View File

@@ -1,5 +1,5 @@
// use spirv_std::RuntimeArray;
use crate::support::Optional;
use coremem_types::compound::Optional;
use coremem_types::mat::Material;
use coremem_types::real::Real;
use coremem_types::vec::Vec3;

View File

@@ -1,86 +1,6 @@
use coremem_types::compound::Optional;
use coremem_types::vec::Vec3u;
/// This is a spirv-compatible option type.
/// The native rust Option type produces invalid spirv due to its enum nature; this custom option
/// type creates code which will actually compile.
#[derive(Copy, Clone, PartialEq)]
pub struct Optional<T> {
// XXX: not a bool, because: "entrypoint parameter cannot contain a boolean"
present: u8,
data: T,
}
impl<T> Optional<T> {
pub fn some(data: T) -> Self {
Self {
present: 1,
data,
}
}
pub fn explicit_none(data: T) -> Self {
Self {
present: 0,
data,
}
}
pub fn is_some(self) -> bool {
self.present != 0
}
pub fn unwrap(self) -> T {
assert!(self.present != 0);
self.data
}
pub fn map<U: Default, F: FnOnce(T) -> U>(self, f: F) -> Optional<U> {
self.and_then(|inner| Optional::some(f(inner)))
}
pub fn and_then<U: Default, F: FnOnce(T) -> Optional<U>>(self, f: F) -> Optional<U> {
if self.present != 0 {
f(self.unwrap())
} else {
Optional::none()
}
}
pub fn unwrap_or(self, default: T) -> T {
if self.present != 0 {
self.unwrap()
} else {
default
}
}
}
impl<T: Default> Optional<T> {
pub fn none() -> Self {
Self::explicit_none(Default::default())
}
pub fn unwrap_or_default(self) -> T {
self.unwrap_or(Default::default())
}
}
impl<T: Default> Default for Optional<T> {
fn default() -> Self {
Self::none()
}
}
impl<T0: Default, T1: Default> Optional<(T0, T1)> {
pub fn flatten((f0, f1): (Optional<T0>, Optional<T1>)) -> Self {
if f0.present != 0 && f1.present != 0 {
Optional::some((f0.unwrap(), f1.unwrap()))
} else {
Optional::none()
}
}
}
/// This struct allows doing things like *(ptr + offset) = value.
/// Such code wouldn't ordinarily compile with the spirv target because of
/// unsupported pointer math. RuntimeArray exists to overcome this, however

View File

@@ -1,3 +1,6 @@
pub mod enumerated;
pub mod list;
mod optional;
pub mod peano;
pub use optional::Optional;

View File

@@ -0,0 +1,82 @@
/// This is a spirv-compatible option type.
/// The native rust Option type produces invalid spirv due to its enum nature; this custom option
/// type creates code which will actually compile.
#[derive(Copy, Clone, PartialEq)]
pub struct Optional<T> {
// XXX: not a bool, because: "entrypoint parameter cannot contain a boolean"
present: u8,
data: T,
}
impl<T> Optional<T> {
pub fn some(data: T) -> Self {
Self {
present: 1,
data,
}
}
pub fn explicit_none(data: T) -> Self {
Self {
present: 0,
data,
}
}
pub fn is_some(self) -> bool {
self.present != 0
}
pub fn unwrap(self) -> T {
assert!(self.present != 0);
self.data
}
pub fn map<U: Default, F: FnOnce(T) -> U>(self, f: F) -> Optional<U> {
self.and_then(|inner| Optional::some(f(inner)))
}
pub fn and_then<U: Default, F: FnOnce(T) -> Optional<U>>(self, f: F) -> Optional<U> {
if self.present != 0 {
f(self.unwrap())
} else {
Optional::none()
}
}
pub fn unwrap_or(self, default: T) -> T {
if self.present != 0 {
self.unwrap()
} else {
default
}
}
}
impl<T: Default> Optional<T> {
pub fn none() -> Self {
Self::explicit_none(Default::default())
}
pub fn unwrap_or_default(self) -> T {
self.unwrap_or(Default::default())
}
}
impl<T: Default> Default for Optional<T> {
fn default() -> Self {
Self::none()
}
}
impl<T0: Default, T1: Default> Optional<(T0, T1)> {
pub fn flatten((f0, f1): (Optional<T0>, Optional<T1>)) -> Self {
if f0.present != 0 && f1.present != 0 {
Optional::some((f0.unwrap(), f1.unwrap()))
} else {
Optional::none()
}
}
}

View File

@@ -1,8 +1,9 @@
#![no_std]
#![feature(core_intrinsics)]
mod compound;
pub mod compound;
pub mod mat;
pub mod real;
pub mod vec;
// private because `vec` re-exports to important vecu constructs
mod vecu;