- syncathetic
- Oct 21, 2010
-
|
Why not this?
code:
fn subdivide_voxel<D>(&mut self, deregister_voxel: &D) where D : Fn(u32) {
*self = match self {
&mut SVO::Voxel{ ref external_id, voxel_type } => {
for voxel_id in external_id.get() {
deregister_voxel(voxel_id)
};
SVO::new_octants([voxel_type, voxel_type, voxel_type, voxel_type,
voxel_type, voxel_type, voxel_type, voxel_type])
},
_ => panic!("subdivide_voxel called on a non-voxel!")
}
|
#
¿
Mar 19, 2016 05:41
|
|
- Adbot
-
ADBOT LOVES YOU
|
|
#
¿
May 3, 2024 07:28
|
|
- syncathetic
- Oct 21, 2010
-
|
I think your problem comes from Iterator::map being lazy. If the the code in your post could be executed, the code inside the closure would never run. If you want to append something to vec after the closure is evaluated and still use its result, you need to do something like:
code:fn with_vec(vec: &mut Vec<u8>) {
let octant_indices = Vec::from_iter(octants.iter().map(|octant| {
vec.add(???);
vec.len() as u64 - 1
}));
vec.add(???);
for octant_index in octant_indices {
//....
}
}
|
#
¿
Mar 23, 2016 00:15
|
|
- syncathetic
- Oct 21, 2010
-
|
I was able to get it to compile making the following changes:
code:diff --git a/carved_rust/src/svo/generator/height_map.rs b/carved_rust/src/svo/generator/height_map.rs
index 000291a..f3d2bd9 100644
--- a/carved_rust/src/svo/generator/height_map.rs
+++ b/carved_rust/src/svo/generator/height_map.rs
@@ -34,7 +34,7 @@ impl<'a> SubImage<'a> {
self.y_n - self.y_0
}
- fn rect(&self, x_0: u32, x_n: u32, y_0: u32, y_n: u32) -> SubImage {
+ fn rect(&self, x_0: u32, x_n: u32, y_0: u32, y_n: u32) -> SubImage<'a> {
SubImage { x_0: x_0, x_n: x_n, y_0: y_0, y_n: y_n, .. *self }
}
@@ -51,7 +51,7 @@ impl<'a> SubImage<'a> {
Some([ll, lr, rl, rr])
}
- fn split_threshold(&'a self) -> Option<[SubImage<'a>; 2]> {
+ fn split_threshold(&self) -> Option<[SubImage<'a>; 2]> {
let half_range = (self.b_n - self.b_0) / 2;
if half_range == 0 { return None; }
@@ -113,4 +113,4 @@ impl SVO {
//SVO::Octants([])
}
}
-}
\ No newline at end of file
+}
I can't really explain why that works, though. I'm pretty sure doing &'a self is generally counter-productive. Most of the time, 'a needs to outlive self to make sense.
|
#
¿
Apr 8, 2016 10:24
|
|
- syncathetic
- Oct 21, 2010
-
|
I have an awful suggestion: use mem::transmute to avoid copying altogether. There are a lot of potential problems (it could cause bugs to appear if the structure of SVO changes later), but I don't think there is a faster option.
code:use std::mem;
use std::marker::PhantomData;
#[derive(Debug, PartialEq, Copy, Clone)]
pub struct Registered;
#[derive(Debug, PartialEq, Copy, Clone)]
pub struct Unregistered;
pub trait RegistrationTrait {}
impl RegistrationTrait for Registered {}
impl RegistrationTrait for Unregistered {}
enum SVO<R: RegistrationTrait> {
Voxel {
external_id: u32, // Moved external_id from registration
data: u32, // Placeholder data type
phantom: PhantomData<R>,
},
Octants([Box<SVO<R>>; 8]),
}
pub trait Deregister: Fn(u32) {}
impl SVO<Registered> {
fn deregister_inner<D: Deregister>(&self, deregister_voxel: &D) {
match self {
&SVO::Voxel { external_id, .. } => deregister_voxel(external_id),
&SVO::Octants (ref octants) => {
for c in octants.iter() {
c.deregister_inner(deregister_voxel)
}
},
}
}
pub fn deregister<D: Deregister>(self, deregister_voxel: &D) -> SVO<Unregistered> {
self.deregister_inner(deregister_voxel);
unsafe {
mem::transmute(self)
}
}
}
|
#
¿
Apr 21, 2016 18:16
|
|
- syncathetic
- Oct 21, 2010
-
|
Could you explain what BindFunc and Registery::binders are?
Edit:
I don't totally understand what you're going for, but this is how I would go about implementing a global registry:
code:#[macro_use]
extern crate lazy_static;
extern crate toml;
//use message::Message;
struct Message;
use std::error::Error;
use std::collections::HashMap;
use std::sync::RwLock;
trait Decoder: Send + Sync {
fn decode(&self, data: Vec<u8>) -> Result<Message, Box<Error>>;
}
//type BindFunc = fn(toml::Value) -> Result<Box<Decoder>, Box<Error>>;
struct Registry {
decoders: HashMap<String, usize>,
defaults: HashMap<String, usize>,
//binders: Mutex<HashMap<String, BindFunc>>,
decoders_cache: Vec<Box<Decoder>>,
}
impl Registry {
fn new() -> Registry {
Registry {
decoders: HashMap::new(),
defaults: HashMap::new(),
decoders_cache: Vec::new(),
//binders: Mutex::new(HashMap::new()),
}
}
pub fn lookup_decoder(&self, name: &str) -> Option<&Decoder> {
self.decoders.get(name).map(|i| &*self.decoders_cache[*i])
}
pub fn lookup_default(&self, name: &str) -> Option<&Decoder> {
self.defaults.get(name).map(|i| &*self.decoders_cache[*i])
}
/*pub fn register(&self, name: String, b: BindFunc) {
let mut bs = self.binders.lock().unwrap();
let _ = bs.insert(name, b);
}*/
}
lazy_static! {
static ref REGISTRY: RwLock<Registry> = RwLock::new(Registry::new());
}
fn do_nothing(decoder: &Decoder) {
}
fn main() {
{
let r = REGISTRY.write().unwrap();
// Insert decoders here
}
{
let r = REGISTRY.read().unwrap();
let decoder = r.lookup_decoder("json").unwrap();
do_nothing(decoder);
}
}
syncathetic fucked around with this message at 09:05 on Apr 24, 2016
|
#
¿
Apr 24, 2016 08:40
|
|
- syncathetic
- Oct 21, 2010
-
|
I don't think its possible for the first case to be null-pointer optimized. Consider https://is.gd/HtdE2R . What value/address does list_end return if the final Empty value isn't on the heap?
As I understand it, Option<bool> having a size of 1 byte might be a breaking change for unsafe code. It would mean that you can no longer blindly memcpy a value onto a &mut bool for fear of clobbering the Option data in the higher bits. I could be wrong though. The exact rules for what is valid unsafe code aren't exactly clear.
|
#
¿
Sep 23, 2016 08:36
|
|
- Adbot
-
ADBOT LOVES YOU
|
|
#
¿
May 3, 2024 07:28
|
|
- syncathetic
- Oct 21, 2010
-
|
I was going to make the same suggestion, except with a macro https://gist.github.com/anonymous/81b4b2dde02467feb13bc8c2de671ded
|
#
¿
Mar 9, 2017 19:35
|
|