larry babby and threejs for glsl

This commit is contained in:
Sam
2024-06-24 21:24:00 +12:00
parent 87d5dc634d
commit 907ebae4c0
6474 changed files with 1279596 additions and 8 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017-present Devon Govett
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _assert() {
const data = _interopRequireDefault(require("assert"));
_assert = function () {
return data;
};
return data;
}
var _errors = require("./errors");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*
* A general-purpose disposable class. It can normalize disposable-like values
* (such as single functions or IDisposables), as well as hold multiple
* disposable-like values to be disposed of at once.
*/
class Disposable {
disposed = false;
#disposables /*: ?Set<DisposableLike> */;
constructor(...disposables) {
this.#disposables = new Set(disposables);
}
add(...disposables) {
if (this.disposed) {
throw new _errors.AlreadyDisposedError('Cannot add new disposables after disposable has been disposed');
}
(0, _assert().default)(this.#disposables != null);
for (let disposable of disposables) {
this.#disposables.add(disposable);
}
}
async dispose() {
if (this.disposed) {
return;
}
this.disposed = true;
(0, _assert().default)(this.#disposables != null);
await Promise.all([...this.#disposables].map(disposable => typeof disposable === 'function' ? disposable() : disposable.dispose()));
this.#disposables = null;
}
}
exports.default = Disposable;

View File

@@ -0,0 +1,71 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _errors = require("./errors");
// Like an EventEmitter, but for only a single "event". This provides type-safety
// for the values emitted. Rather than passing predetermined strings (which can
// be misspelled), create an instance of ValueEmitter for every logical "event"
// to be dispatched, and type it according to the type of value emitted.
class ValueEmitter {
// An array of listeners. One might think a Set would be better for O(1) removal,
// but splicing a JS array gets pretty close, and copying the array (as is done
// in emit) is far faster than a Set copy: https://github.com/atom/event-kit/pull/39
_listeners = [];
_disposed = false;
addListener(listener) {
if (this._disposed) {
throw new _errors.AlreadyDisposedError('Cannot add a listener since this ValueEmitter has been disposed');
}
this._listeners.push(listener);
// Close over a reference to this emitter in the disposable below, rather
// than referencing `this` directly. This allows us to set it to null after
// slicing out the listener.
// This prevents anyone holding onto the disposable after disposal from
// unintentionally retaining a reference to this emitter.
let emitter = this;
return {
dispose() {
if (emitter == null) {
return;
}
if (emitter._disposed) {
emitter = null;
return;
}
let listeners = emitter._listeners;
let listenerIndex = listeners.indexOf(listener);
if (listenerIndex > -1) {
listeners.splice(listenerIndex, 1);
}
emitter = null;
}
};
}
emit(value) {
if (this._disposed) {
throw new _errors.AlreadyDisposedError('Cannot emit since this ValueEmitter has been disposed');
}
// Iterate over a copy of listeners. This prevents the following cases:
// * When a listener callback can itself register a new listener and be
// emitted as part of this iteration.
// * When a listener callback disposes of this emitter mid-emit, preventing
// other listeners from receiving the event.
let listeners = this._listeners.slice();
for (let i = 0; i < listeners.length; i++) {
listeners[i](value);
}
}
dispose() {
if (this._disposed) {
return;
}
this._listeners = [];
this._disposed = true;
}
}
exports.default = ValueEmitter;

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.AlreadyDisposedError = void 0;
class AlreadyDisposedError extends Error {}
exports.AlreadyDisposedError = AlreadyDisposedError;
Object.defineProperty(AlreadyDisposedError.prototype, 'name', {
value: 'AlreadyDisposedError'
});

View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "AlreadyDisposedError", {
enumerable: true,
get: function () {
return _errors.AlreadyDisposedError;
}
});
Object.defineProperty(exports, "Disposable", {
enumerable: true,
get: function () {
return _Disposable.default;
}
});
Object.defineProperty(exports, "ValueEmitter", {
enumerable: true,
get: function () {
return _ValueEmitter.default;
}
});
var _Disposable = _interopRequireDefault(require("./Disposable"));
var _ValueEmitter = _interopRequireDefault(require("./ValueEmitter"));
var _errors = require("./errors");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

View File

@@ -0,0 +1 @@
"use strict";

View File

@@ -0,0 +1,22 @@
{
"name": "@parcel/events",
"version": "2.12.0",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"repository": {
"type": "git",
"url": "https://github.com/parcel-bundler/parcel.git"
},
"main": "lib/index.js",
"source": "src/index.js",
"engines": {
"node": ">= 12.0.0"
},
"gitHead": "2059029ee91e5f03a273b0954d3e629d7375f986"
}

View File

@@ -0,0 +1,52 @@
// @flow strict-local
import type {IDisposable} from './types';
import invariant from 'assert';
import {AlreadyDisposedError} from './errors';
type DisposableLike = IDisposable | (() => mixed);
/*
* A general-purpose disposable class. It can normalize disposable-like values
* (such as single functions or IDisposables), as well as hold multiple
* disposable-like values to be disposed of at once.
*/
export default class Disposable implements IDisposable {
disposed: boolean = false;
#disposables /*: ?Set<DisposableLike> */;
constructor(...disposables: Array<DisposableLike>) {
this.#disposables = new Set(disposables);
}
add(...disposables: Array<DisposableLike>): void {
if (this.disposed) {
throw new AlreadyDisposedError(
'Cannot add new disposables after disposable has been disposed',
);
}
invariant(this.#disposables != null);
for (let disposable of disposables) {
this.#disposables.add(disposable);
}
}
async dispose(): Promise<void> {
if (this.disposed) {
return;
}
this.disposed = true;
invariant(this.#disposables != null);
await Promise.all(
[...this.#disposables].map(disposable =>
typeof disposable === 'function' ? disposable() : disposable.dispose(),
),
);
this.#disposables = null;
}
}

View File

@@ -0,0 +1,81 @@
// @flow strict-local
import type {IDisposable} from './types';
import {AlreadyDisposedError} from './errors';
// Like an EventEmitter, but for only a single "event". This provides type-safety
// for the values emitted. Rather than passing predetermined strings (which can
// be misspelled), create an instance of ValueEmitter for every logical "event"
// to be dispatched, and type it according to the type of value emitted.
export default class ValueEmitter<TValue> implements IDisposable {
// An array of listeners. One might think a Set would be better for O(1) removal,
// but splicing a JS array gets pretty close, and copying the array (as is done
// in emit) is far faster than a Set copy: https://github.com/atom/event-kit/pull/39
_listeners: Array<(value: TValue) => mixed> = [];
_disposed: boolean = false;
addListener(listener: (value: TValue) => mixed): IDisposable {
if (this._disposed) {
throw new AlreadyDisposedError(
'Cannot add a listener since this ValueEmitter has been disposed',
);
}
this._listeners.push(listener);
// Close over a reference to this emitter in the disposable below, rather
// than referencing `this` directly. This allows us to set it to null after
// slicing out the listener.
// This prevents anyone holding onto the disposable after disposal from
// unintentionally retaining a reference to this emitter.
let emitter = this;
return {
dispose() {
if (emitter == null) {
return;
}
if (emitter._disposed) {
emitter = null;
return;
}
let listeners = emitter._listeners;
let listenerIndex = listeners.indexOf(listener);
if (listenerIndex > -1) {
listeners.splice(listenerIndex, 1);
}
emitter = null;
},
};
}
emit(value: TValue): void {
if (this._disposed) {
throw new AlreadyDisposedError(
'Cannot emit since this ValueEmitter has been disposed',
);
}
// Iterate over a copy of listeners. This prevents the following cases:
// * When a listener callback can itself register a new listener and be
// emitted as part of this iteration.
// * When a listener callback disposes of this emitter mid-emit, preventing
// other listeners from receiving the event.
let listeners = this._listeners.slice();
for (let i = 0; i < listeners.length; i++) {
listeners[i](value);
}
}
dispose() {
if (this._disposed) {
return;
}
this._listeners = [];
this._disposed = true;
}
}

View File

@@ -0,0 +1,6 @@
// @flow strict-local
export class AlreadyDisposedError extends Error {}
Object.defineProperty(AlreadyDisposedError.prototype, 'name', {
value: 'AlreadyDisposedError',
});

View File

@@ -0,0 +1,5 @@
// @flow strict-local
export {default as Disposable} from './Disposable';
export {default as ValueEmitter} from './ValueEmitter';
export {AlreadyDisposedError} from './errors';

View File

@@ -0,0 +1,8 @@
// @flow strict-local
export interface IDisposable {
/** This can return a Promise, as dispose() of all inner disposables are
* awaited in Disposable#dispose()
*/
dispose(): mixed;
}

View File

@@ -0,0 +1,118 @@
// @flow strict-local
import assert from 'assert';
import Disposable from '../src/Disposable';
import {AlreadyDisposedError} from '../src/errors';
describe('Disposable', () => {
it('can wrap an IDisposable', () => {
let disposed;
new Disposable({
dispose() {
disposed = true;
},
}).dispose();
assert.equal(disposed, true);
});
it('can wrap a function to dispose', () => {
let disposed;
new Disposable(() => {
disposed = true;
}).dispose();
assert.equal(disposed, true);
});
it('can wrap many disposable-likes', () => {
let disposed1;
let disposed2;
new Disposable(
{
dispose() {
disposed1 = true;
},
},
() => {
disposed2 = true;
},
).dispose();
assert.equal(disposed1, true);
assert.equal(disposed2, true);
});
it('can add disposables after construction', () => {
let disposed1;
let disposed2;
let disposed3;
let disposed4;
let disposable = new Disposable(
{
dispose() {
disposed1 = true;
},
},
() => {
disposed2 = true;
},
);
disposable.add(
() => {
disposed3 = true;
},
{
dispose() {
disposed4 = true;
},
},
);
assert.notEqual(disposed1, true);
assert.notEqual(disposed2, true);
assert.notEqual(disposed3, true);
assert.notEqual(disposed4, true);
disposable.dispose();
assert.equal(disposed1, true);
assert.equal(disposed2, true);
assert.equal(disposed3, true);
assert.equal(disposed4, true);
});
it(
'does not dispose inner disposables more than once,' +
' and does not throw on subsequent disposals',
() => {
let disposed;
let disposable = new Disposable(() => {
if (disposed) {
// $FlowFixMe
assert.fail();
}
disposed = true;
});
disposable.dispose();
disposable.dispose();
},
);
it('throws if `add` is called after it has been disposed', () => {
let disposable = new Disposable();
disposable.dispose();
assert.throws(() => {
disposable.add(() => {});
}, AlreadyDisposedError);
});
it('can be checked for disposal state', () => {
let disposable = new Disposable();
assert.equal(disposable.disposed, false);
disposable.dispose();
assert.equal(disposable.disposed, true);
});
});

View File

@@ -0,0 +1,100 @@
// @flow strict-local
import assert from 'assert';
import ValueEmitter from '../src/ValueEmitter';
import {AlreadyDisposedError} from '../src/errors';
describe('ValueEmitter', () => {
let emitter: ValueEmitter<number>;
let values: Array<number>;
beforeEach(() => {
emitter = new ValueEmitter();
values = [];
});
afterEach(() => {
emitter.dispose();
});
function numberListener(x: number): void {
values.push(x);
}
it('registers new listeners and can dispose of them', () => {
let disposable = emitter.addListener(numberListener);
assert.deepEqual(emitter._listeners, [numberListener]);
disposable.dispose();
assert.deepEqual(emitter._listeners, []);
});
it('emits values to registered listeners', () => {
let disposable = emitter.addListener(numberListener);
emitter.emit(42);
assert.deepEqual(values, [42]);
disposable.dispose();
});
it('does not emit to listeners that were just registered', () => {
let innerDisposable;
let disposable = emitter.addListener(() => {
innerDisposable = emitter.addListener(numberListener);
});
emitter.emit(42);
assert.deepEqual(values, []);
emitter.emit(27);
assert.deepEqual(values, [27]);
disposable.dispose();
innerDisposable && innerDisposable.dispose();
});
it('finishes emitting even if a listener disposes of the emitter mid-emit', () => {
let disposableA = emitter.addListener(() => {
emitter.dispose();
});
let disposableB = emitter.addListener(numberListener);
emitter.emit(42);
assert.deepEqual(values, [42]);
disposableA.dispose();
disposableB.dispose();
});
it('clears listeners when disposed', () => {
let disposable = emitter.addListener(numberListener);
assert.deepEqual(emitter._listeners, [numberListener]);
emitter.dispose();
assert.deepEqual(emitter._listeners, []);
disposable.dispose();
});
it('throws when adding a listener when already disposed', () => {
emitter.dispose();
assert.throws(() => {
emitter.addListener(numberListener);
}, AlreadyDisposedError);
});
it('throws when emitting when already disposed', () => {
emitter.dispose();
assert.throws(() => {
emitter.emit(42);
}, AlreadyDisposedError);
});
it('can be disposed multiple times', () => {
emitter.dispose();
assert.doesNotThrow(() => {
emitter.dispose();
});
});
});