Skip to content

Commit a18329c

Browse files
committed
output can create and have many connections but only the inputs are restricted to 1...
1 parent c9f6bde commit a18329c

File tree

2 files changed

+105
-24
lines changed

2 files changed

+105
-24
lines changed

src/Editor.ts

Lines changed: 96 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ export class Editor {
3535
private aspectCorrection = 1;
3636
private canvasAspect:number;
3737

38+
/**
39+
* Used to be able to identify when a user just clicks ( a mouse up woth no mouse movement )
40+
*/
41+
private mouseMoved = false;
3842
private handIcon : HandIcon;
3943

4044
/**
@@ -175,6 +179,9 @@ export class Editor {
175179

176180
//#region MOUSE MOVE
177181
canvas.addEventListener('mousemove', (event) => {
182+
183+
this.mouseMoved = true;
184+
178185
let scale = this.ctx.getTransform().a; // Get the current scale (assuming uniform scaling)
179186
const mousePos = this.getMousePos( event);
180187
const canvasPos = this.getCanvasMousePosition(mousePos);
@@ -228,6 +235,8 @@ export class Editor {
228235

229236
//#region MOUSE DOWN
230237
canvas.addEventListener("mousedown", ev=>{
238+
239+
this.mouseMoved = false;
231240
this.mouse = this.getMousePos( ev);
232241

233242
// middle mouse button to pan the workspace
@@ -277,10 +286,10 @@ export class Editor {
277286

278287
if( Math.abs( this.mouse.x - outlet.globalX )<=hitAreaRatio && Math.abs( this.mouse.y - outlet.globalY )<=hitAreaRatio )
279288
{
280-
//
281-
// destroy any connectionusing this outlet...
282-
//
283-
this.destroyConnectionsUsing( outlet );
289+
// //
290+
// // destroy any connectionusing this outlet...
291+
// //
292+
// this.destroyConnectionsUsing( outlet );
284293

285294
//
286295
// create a new "open" connection
@@ -336,7 +345,24 @@ export class Editor {
336345
// if we clicked an outlet, we need to know which of the available outlets are valid to be connected to...
337346
//
338347
if( this.selectedOutlet )
339-
{
348+
{
349+
350+
//@ts-ignore
351+
if( this.selectedOutlet.isInput )
352+
{
353+
//
354+
// in this case we will pretend that the connection was made by the other end of the connection if it was connected, to allow
355+
// for the visual impression of changing the endpoint of the connection that lead to us.
356+
//
357+
const oldOutlet = this.selectedOutlet;
358+
359+
if( this.disolveSelectedOutlet() )
360+
{
361+
outlets.push( oldOutlet );
362+
outlets.splice( outlets.indexOf( this.selectedOutlet ), 1 );
363+
}
364+
}
365+
340366
//
341367
// filter only outlet that we can connect to...
342368
//
@@ -403,18 +429,8 @@ export class Editor {
403429
}
404430
else
405431
{
406-
407-
if( this.chosenOutlet.length )
408-
{
409-
if( this.chosenOutlet.length>1 )
410-
this.chosenOutlet.sort((a,b)=>b.alignmentScore-a.alignmentScore);
411-
412-
413-
this.destroyConnectionsUsing( this.chosenOutlet[0].outlet );
414-
415-
this.connections.setOrphansTarget( this.chosenOutlet[0].outlet );
416-
417-
}
432+
if( this.mouseMoved)
433+
this.createChosenConnections();
418434

419435
this.clearOutletSelection();
420436
}
@@ -604,15 +620,71 @@ export class Editor {
604620

605621
}
606622

607-
protected destroyConnectionsUsing( outlet:IOutlet )
623+
protected destroyConnectionsUsing( outlet:IOutlet, onlyIfConnected=false )
608624
{
609-
this.connections.purge( connection=>connection.from!==outlet && (!isOutlet(connection.to) || connection.to!==outlet) )
610-
// const clean = this.connections.filter( c=>( c.from!==outlet )
611-
// && ( c.to !==outlet )
612-
// );
625+
this.connections.purge( connection=>(( connection.from!==outlet ) || ( onlyIfConnected && !isOutlet(connection.to) )) && ( !isOutlet(connection.to) || connection.to!==outlet) ) ;
626+
}
627+
628+
/**
629+
* An input can only recieve 1 connection. The connection array will never have "to" repeated referencing the same outlet.
630+
*/
631+
protected disolveSelectedOutlet() {
632+
if( !this.selectedOutlet || !this.selectedOutlet.isInput ) return false;
613633

614-
// this.connections.length = 0;
615-
// this.connections.push( ...clean );
634+
const other = this.selectedOutlet.connectedTo;
635+
if( other )
636+
{
637+
//
638+
// the first time we click an outlet a new connection if created with the "from" set to the clicked outlet and the "to" set to the mouse coordinates.
639+
//
640+
const openConnection = this.connections.find( c=>c.from==this.selectedOutlet && !isOutlet(c.to));
641+
642+
let target :Vector2Like | undefined;
643+
644+
if( openConnection )
645+
{
646+
target = openConnection.to as Vector2Like; //<--- mouse coordinates
647+
}
648+
649+
this.destroyConnectionsUsing( this.selectedOutlet );
650+
651+
this.selectedOutlet = other;
652+
653+
if( target )
654+
this.connections.push({
655+
from: other,
656+
to: target
657+
});
658+
659+
return true;
660+
}
661+
662+
return false;
663+
}
664+
665+
/**
666+
* The user dragged the mouse out of an outlet aiming to create a new connection.
667+
*/
668+
protected createChosenConnections() {
669+
670+
if( !this.chosenOutlet.length || !this.selectedOutlet ) return;
671+
672+
//
673+
// pick the best one for the current one...
674+
//
675+
if( this.chosenOutlet.length>1 )
676+
this.chosenOutlet.sort((a,b)=>b.alignmentScore-a.alignmentScore);
677+
678+
679+
const chosenTarget = this.chosenOutlet[0].outlet;
680+
681+
if( this.selectedOutlet.isInput )
682+
this.destroyConnectionsUsing( this.selectedOutlet, true );
683+
684+
//
685+
// all the connections that were following the mouse will not have this outlet as their endpoint connection.
686+
//
687+
this.connections.setOrphansTarget( chosenTarget );
616688
}
617689

618690
protected clearOutletSelection() {

src/core/Connection.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@ export class ConnectionsArray<T extends Connection=Connection> {
9393
return this._array.map(mapper);
9494
}
9595

96+
find( finder:( connection:T, index:number, connections:T[])=>boolean ) {
97+
for (let i = 0; i < this._array.length; i++) {
98+
const connection = this._array[i];
99+
if( finder( connection, i, this._array )) {
100+
return connection;
101+
}
102+
}
103+
}
104+
96105
purge( judge:( connection:T )=>boolean ){
97106
this._array = this._array.filter( con=> {
98107

0 commit comments

Comments
 (0)