Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/rm-hull/cljs-dataview

A ClojureScript library for asynchronously fetching & dicing remote binary objects
https://github.com/rm-hull/cljs-dataview

Last synced: about 1 month ago
JSON representation

A ClojureScript library for asynchronously fetching & dicing remote binary objects

Awesome Lists containing this project

README

        

# cljs-dataview [![Build Status](https://secure.travis-ci.org/rm-hull/cljs-dataview.png)](http://travis-ci.org/rm-hull/cljs-dataview)

A ClojureScript library for asynchronously fetching & dicing remote binary objects

_PREAMBLE_: TODO

### Pre-requisites

You will need [Leiningen](https://github.com/technomancy/leiningen) 2.3.4 or above installed.

### Building

To build and install the library locally, run:

$ lein clean
$ lein cljsbuild once
$ lein install

### Testing

To run the tests in a browser, ensure the generated javascript files are up-to-date,
and open ```resources/run-tests.html``` in a browser - this executes the tests and
the test results are displayed on the page.

Alternatively, to run using PhantomJS, execute:

$ lein cljsbuild test

This will only show a tally of failed tests.

### Including in your project

There is an 'alpha-quality' version hosted at [Clojars](https://clojars.org/rm-hull/cljs-dataview).
For leiningen include a dependency:

```clojure
[rm-hull/cljs-dataview "0.0.1-SNAPSHOT"]
```

For maven-based projects, add the following to your `pom.xml`:

```xml

rm-hull
cljs-dataview
0.0.1-SNAPSHOT

```

## Basic Usage

### Example: Reading binary STL files

[Binary STL](https://en.wikipedia.org/wiki/STL_\(file_format\)#Binary_STL) files
can be read in and processed with the following code sample (see
[example/binary_stl.cljs](https://github.com/rm-hull/cljs-dataview/blob/master/example/binary_stl.cljs)
for fully working example). Starting with some necessary pre-amble:

```clojure
(ns binary-stl
(:require [cljs.dataview.loader :refer [fetch-blob]]
[cljs.dataview.ops :refer [create-reader read-fixed-string read-float32-le
read-uint16-le read-uint32-le]])
(:require-macros [cljs.core.async.macros :refer [go]]))

(def local-url "http://localhost/~rhu/test/torus.stl")
```

The ```torus.stl``` contains polygons for the classic/ubiquitous 3D torus as per:

![Torus](https://raw.github.com/rm-hull/wireframes/master/doc/gallery/shaded/torus.png)

In order to read the binary STL data, we must first define some decoders; so
to create a 3D point, a ```point-spec``` generates an ordered map of _x_, _y_
and _z_ floating-point components from a reader:

```clojure
(defn point-spec [reader]
(array-map
:x (read-float32-le reader)
:y (read-float32-le reader)
:z (read-float32-le reader)))
```
A _reader_ is a stateful implementation of an
[IReader](https://github.com/rm-hull/cljs-dataview/blob/master/src/cljs/dataview/ops.cljs#L57)
protocol -- this has methods that traverse a javascript
[DataView](https://developer.mozilla.org/en-US/docs/Web/API/DataView?redirectlocale=en-US&redirectslug=Web%2FJavaScript%2FTyped_arrays%2FDataView)
sequentially as bytes, 16-bit & 32-bit integers, floating-point numbers and
fixed-width/delimited strings. The reified reader object may also implement
[IRandomAccess](https://github.com/rm-hull/cljs-dataview/blob/master/src/cljs/dataview/ops.cljs#L67)
so that _seek_/_rewind_/_tell_ operations (similar to that used with Unix file
descriptors) are also available.

Secondly, a triangle is composed of a [surface normal](https://en.wikipedia.org/wiki/Surface_normal),
followed by 3 vertex co-ordinates and some attributes in the form of a 16-bit
word -- the normal and the vertexes are constructed out of repeated application
of the ```point-spec``` above. Note that since the ```point-spec``` has side-effects
it is important to call _doall_ to force evaluation, otherwise _repeatedly_ will
act lazily.

```clojure
(defn triangle-spec [reader]
(array-map
:normal (point-spec reader)
:points (doall (repeatedly 3 #(point-spec reader)))
:attributes (read-uint16-le reader)))
```
Finally, the overall STL spec header consists of 80 padded characters,
followed by a triangle count: notice how this determines how many times the
```triangle-spec``` is subsequently invoked in the body:

```clojure
(defn stl-spec [reader]
(array-map
:header (read-fixed-string reader 80)
:triangles (doall (repeatedly
(read-uint32-le reader) ; <== triangle-count
#(triangle-spec reader)))))
```
So in order to fetch the binary data, ```fetch-blob``` below returns a
_core.async_ channel, from which a javascript DataView is produced. In order
to then _sort-of_ treat the DataView object as an input stream, it is wrapped in a
reader (by virtue of the ```create-reader``` function), which is then passed on
to the ```stl-spec```: hence the binary data is progressively diced
into a persistent map structure.

```clojure
(go
(->
(