Skip to content

Instantly share code, notes, and snippets.

@ubnt-intrepid
Created January 1, 2017 03:18
Show Gist options
  • Select an option

  • Save ubnt-intrepid/df7396ee779af1d1fa850845ff312468 to your computer and use it in GitHub Desktop.

Select an option

Save ubnt-intrepid/df7396ee779af1d1fa850845ff312468 to your computer and use it in GitHub Desktop.
Rust と Electron で GUI アプリケーションを作る ref: http://qiita.com/ubnt_intrepid/items/cf4e1cc6d6e5b3b23ca8
#[macro_use]
extern crate itertools;
use std::cmp;
use itertools::Itertools;
pub fn mandelbrot(buffer: &mut [u8], width: i64, height: i64, pixel_size: f64, x0: f64, y0: f64) {
iproduct!((0..width), (0..height)).foreach(|(i, j)| {
let cr = x0 + pixel_size * (i as f64);
let ci = y0 + pixel_size * (j as f64);
let (mut zr, mut zi) = (0.0, 0.0);
let k = (0..256)
.take_while(|_| {
let (zrzi, zr2, zi2) = (zr * zi, zr * zr, zi * zi);
zr = zr2 - zi2 + cr;
zi = zrzi + zrzi + ci;
zi2 + zr2 < 2.0
})
.count();
let k = cmp::min(255, k) as u8;
let idx = (j * width + i) as usize;
buffer[4 * idx] = 255 - k;
buffer[4 * idx + 1] = 255 - k;
buffer[4 * idx + 2] = 255 - k;
buffer[4 * idx + 3] = 255;
});
}
#[macro_use]
extern crate neon;
extern crate mandelbrot;
use neon::vm::{Call, Lock, JsResult, This, FunctionCall};
use neon::js::{JsInteger, JsNumber, JsUndefined, Value};
use neon::js::binary::JsBuffer;
trait CheckArgument<'a> {
fn check_argument<V: Value>(&mut self, i: i32) -> JsResult<'a, V>;
}
impl<'a, T: This> CheckArgument<'a> for FunctionCall<'a, T> {
fn check_argument<V: Value>(&mut self, i: i32) -> JsResult<'a, V> {
self.arguments.require(self.scope, i)?.check::<V>()
}
}
fn mandelbrot(mut call: Call) -> JsResult<JsUndefined> {
let mut buffer = call.check_argument::<JsBuffer>(0)?;
let width = call.check_argument::<JsInteger>(1)?.value();
let height = call.check_argument::<JsInteger>(2)?.value();
let pixel_size = call.check_argument::<JsNumber>(3)?.value();
let x0 = call.check_argument::<JsNumber>(4)?.value();
let y0 = call.check_argument::<JsNumber>(5)?.value();
buffer.grab(|mut buf| {
mandelbrot::mandelbrot(buf.as_mut_slice(), width, height, pixel_size, x0, y0)
});
Ok(JsUndefined::new())
}
register_module!(m, {
m.export("mandelbrot", mandelbrot)
});
#![feature(link_args)]
#[link_args = "-s EXPORTED_FUNCTIONS=['_mandelbrot']"]
extern "C" {}
extern crate mandelbrot;
use std::slice;
#[no_mangle]
pub fn mandelbrot(buffer: *mut u8,
len: usize,
width: f64,
height: f64,
pixel_size: f64,
x0: f64,
y0: f64) {
let mut buffer = unsafe { slice::from_raw_parts_mut(buffer, len) };
mandelbrot::mandelbrot(buffer, width as i64, height as i64, pixel_size, x0, y0);
}
fn main() {
// Intentionally left blank.
}
module.exports = Module;
let buffer = Buffer.from(image.data.buffer); // new BUffer(image.data.buffer) でも可
Native.mandelbrot(buffer, width, height, ...);
// ptr には Module.HEAPU8 におけるオフセット値が入る
let ptr = Module._malloc(canvas.width * canvas.height * 4);
// JavaScript 側から確保された領域にアクセスする
let buffer = new Uint8ClampedArray(Module.HEAPU8.buffer, ptr, n_bytes);
// ...
// asm.js 側の関数呼び出しの時はオフセットの方を渡す
Module.ccall("mandelbrot", undefined, ["number", "number", ...], [ptr, ...]);
// 使用後は free
Module._free(ptr);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment