@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
133 lines (132 loc) • 4.79 kB
JavaScript
;
import { TypedNode } from "../_Base";
import { NodeContext } from "../../poly/NodeContext";
import { pushOnArrayAtEntry } from "../../../core/MapUtils";
import { Poly } from "../../Poly";
export class TypedEventNode extends TypedNode {
constructor() {
super(...arguments);
// ensures that event nodes are cooked when scene is loaded
// private _eval_all_params_on_dirty_bound = this._eval_all_params_on_dirty.bind(this);
// _eval_all_params_on_dirty() {
// this.params.eval_all();
// }
this._cookWithoutInputsBound = this._cookWithoutInputs.bind(this);
}
static context() {
return NodeContext.EVENT;
}
initializeBaseNode() {
this.uiData.setLayoutHorizontal();
this.addPostDirtyHook("cookWithoutInputsOnDirty", this._cookWithoutInputsBound);
this.io.inputs.setDependsOnInputs(false);
this.io.connections.initInputs();
this.io.connection_points.spare_params.initializeNode();
}
_cookWithoutInputs() {
this.cookController.cookMainWithoutInputs();
}
cook() {
this.cookController.endCook();
}
// eval_params_and_processEvent(event_context: EventContext<Event>, connection_point: BaseEventConnectionPoint) {
// // not evaluation params now, since we are evaluating them on dirty
// // this.params.eval_all().then(()=>{
// this.processEvent(event_context, connection_point)
// // })
// }
processEventViaConnectionPoint(eventContext, connectionPoint) {
if (connectionPoint.event_listener) {
connectionPoint.event_listener(eventContext);
} else {
this.processEvent(eventContext);
}
}
processEvent(event_context) {
}
//
//
// It may be more practical to use cook, rather than process_event
// to benefit from params evaluation.
// But that would mean that each node receiving an event would make the successors dirty,
// which may also be problematic. So for now, I use process_event
//
//
async dispatchEventToOutput(output_name, event_context) {
this.run_on_dispatch_hook(output_name, event_context);
const index = this.io.outputs.getOutputIndex(output_name);
if (index >= 0) {
const outputConnections = this.io.connections.outputConnectionsByOutputIndex(index);
if (outputConnections) {
let destNode;
if (!Poly.playerMode()) {
const dispatcher = this.scene().eventsDispatcher.connectionTriggerDispatcher;
outputConnections.forEach((connection) => {
dispatcher.dispatchTrigger(connection);
});
}
outputConnections.forEach((connection) => {
destNode = connection.nodeDest();
const destNodeConnectionPoints = destNode.io.inputs.namedInputConnectionPoints();
if (destNodeConnectionPoints) {
const connection_point = destNodeConnectionPoints[connection.inputIndex()];
destNode.processEventViaConnectionPoint(event_context, connection_point);
}
});
}
} else {
console.warn(`requested output '${output_name}' does not exist on node '${this.path()}'`);
}
}
/**
* onDispatch is called when an output triggers an event.
*
* Here is an example usage to listen to events:
*
* ``` ts
*let _currentState = false;
*function setHit( newState ){
* if( _currentState != newState ){
* if( newState ){
* playSound();
* }
* _currentState = newState;
* }
*}
*
*const raycastNode = scene.node('<path to the node>');
*raycastNode.onDispatch('hit', ()=>setHit(true) );
*raycastNode.onDispatch('miss', ()=>setHit(false) );
* ```
*
* Alternatively, you can also have the following arguments from the callback
*
* - viewer: the [viewer](https://polygonjs.com/docs/api/TypedViewer) displaying the scene.
* - event: the mouse/pointer/keyboard event that originally triggered the event
* - emitter: the domElement the event was triggered from (either the canvas or the document)
* - value: an optional value linked to the event.
*
* ``` ts
*raycastNode.onDispatch('hit',(eventContext)=>{
* const {viewer, event, emitter, value} = eventContext;
*});
* ```
*
*/
onDispatch(outputName, callback) {
this._on_dispatch_hooks_by_output_name = this._on_dispatch_hooks_by_output_name || /* @__PURE__ */ new Map();
pushOnArrayAtEntry(this._on_dispatch_hooks_by_output_name, outputName, callback);
}
run_on_dispatch_hook(output_name, event_context) {
if (this._on_dispatch_hooks_by_output_name) {
const hooks = this._on_dispatch_hooks_by_output_name.get(output_name);
if (hooks) {
for (const hook of hooks) {
hook(event_context);
}
}
}
}
}
export class BaseEventNodeClass extends TypedEventNode {
}