import { SignalID } from "../blueprint.js" ; import { anything , each , Endpoint , everything } from "../entities/Entity.js" ; import { logger } from "../logger.js" ; let redCounter = 1 ; let greenCounter = 1 ; export let nets ; export function resetNets ( ) { nets = { red : new Set < Network > ( ) , green : new Set < Network > ( ) } ; redCounter = 1 ; greenCounter = 1 ; } export class Network { public points = new Set < Endpoint > ( ) ; public id : number ; public color : "red" | "green" ; public signals = new Set < SignalID > ( ) ; constructor ( color ) { this . color = color ; if ( color == "red" ) { this . id = redCounter ++ ; } else { this . id = greenCounter ++ ; } nets [ color ] . add ( this ) ; } add ( e ) { if ( e [ this . color ] === this ) return ; if ( e [ this . color ] ) logger . assert ( false , "cannot add endpoint which is part of a different network" ) ; this . points . add ( e ) ; e [ this . color ] = this ; if ( e . outSignals . has ( anything ) || e . outSignals . has ( everything ) || e . outSignals . has ( each ) ) { throw new Error ( "special signal not allowed" ) ; } for ( const s of this . signals ) { e . entity ?. netSignalAdd ( e , s ) ; } for ( const s of e . outSignals ) { this . addSignal ( s ) ; } } remove ( e ) { if ( ! this . points . has ( e ) ) debugger ; this . points . delete ( e ) ; e [ this . color ] = null ; if ( this . points . size == 1 ) { this . delete ( ) ; return ; } for ( const s of e . outSignals ) { this . removeSignal ( s ) ; } } addSignal ( s ) { if ( this . signals . has ( s ) ) return ; this . signals . add ( s ) ; for ( const p of this . points ) { p . entity ?. netSignalAdd ( p , s ) ; } } removeSignal ( s ) { let has = false ; for ( const p of this . points ) { if ( p . outSignals . has ( s ) ) { has = true ; break ; } } if ( ! has ) { this . signals . delete ( s ) ; logger . assert ( false , "removeSignal propagation not implemented" ) ; } } hasWriter ( ) { for ( const e of this . points ) { if ( e == e . entity . output && e . outSignals . size != 0 ) return true ; } return false ; } hasOtherWriters ( e ) { for ( const o of this . points ) { if ( e == o || o . outSignals . size == 0 || o == o . entity . input ) continue ; for ( const s of e . outSignals ) { if ( o . outSignals . has ( s ) ) return true ; } } return false ; } hasOtherReaders ( e ) { for ( const o of this . points ) { if ( o !== e && o == o . entity . input ) return true ; } return false ; } hasOtherColor ( ) { let color = this . color == "red" ? "green" : "red" ; for ( const o of this . points ) { if ( o [ color ] ) return true ; } return false ; } delete ( ) { for ( const p of this . points ) { p [ this . color ] = null ; } this . points . clear ( ) ; nets [ this . color ] . delete ( this ) ; } static merge ( a , b ) { console . assert ( a . color == b . color , "Trying to merge different color networks" ) ; let n = new Network ( a . color ) ; for ( const p of a . points ) { p [ a . color ] = null ; n . add ( p ) ; } for ( const p of b . points ) { p [ a . color ] = null ; n . add ( p ) ; } a . points . clear ( ) ; b . points . clear ( ) ; nets [ a . color ] . delete ( a ) ; nets [ a . color ] . delete ( b ) ; return n ; } }