Evented listener metadata now distinct per instance

events
Mike Gerwitz 2014-08-03 00:53:51 -04:00
parent eeea892967
commit e55288c989
2 changed files with 48 additions and 7 deletions

View File

@ -20,10 +20,7 @@
*/ */
var Trait = require( 'easejs' ).Trait, var Trait = require( 'easejs' ).Trait,
isArray = require( '../std/Array' ).isArray, isArray = require( '../std/Array' ).isArray;
// used for hiding cached event indexes
_evid = Symbol();
/** /**
@ -55,6 +52,26 @@ module.exports = Trait( 'Evented',
*/ */
_gaps: {}, _gaps: {},
/**
* Private listener metadata field
* @type {Symbol}
*/
_evid: null,
/**
* Prepare private listener metadata field
*
* The event identifier field is set on registered listeners to provide
* constant-time lookups when querying for listener indexes or status.
*
* @O {1} constant time
*/
__mixin()
{
this._evid = Symbol();
},
/** /**
* Defines a list of events by unique identifier * Defines a list of events by unique identifier
@ -226,7 +243,8 @@ module.exports = Trait( 'Evented',
'virtual protected hookEvent'( ev, listener ) 'virtual protected hookEvent'( ev, listener )
{ {
let evls = this._events[ ev ], let evls = this._events[ ev ],
avail = this._gaps[ ev ].pop(); avail = this._gaps[ ev ].pop(),
_evid = this._evid;
if ( listener[ _evid ] === undefined ) if ( listener[ _evid ] === undefined )
{ {
@ -262,7 +280,7 @@ module.exports = Trait( 'Evented',
*/ */
hooksEvent( ev, listener ) hooksEvent( ev, listener )
{ {
let levdata = listener[ _evid ]; let levdata = listener[ this._evid ];
return !!( levdata && ( levdata[ ev ] !== undefined ) ); return !!( levdata && ( levdata[ ev ] !== undefined ) );
}, },
@ -307,7 +325,7 @@ module.exports = Trait( 'Evented',
} }
let evls = this._events[ ev ], let evls = this._events[ ev ],
levdata = listener[ _evid ] || {}, levdata = listener[ this._evid ] || {},
index = levdata[ ev ]; index = levdata[ ev ];
// this is important, since we (a) cannot necessarily trust that the // this is important, since we (a) cannot necessarily trust that the

View File

@ -646,5 +646,28 @@ describe( 'event.Evented', () =>
expect( stub.hooksEvent( ev2, f2 ) ).to.be.true; expect( stub.hooksEvent( ev2, f2 ) ).to.be.true;
} ); } );
} ); } );
describe( 'listener metadata', () =>
{
/**
* It is important that each Evented instance store its listener
* metadata in a distinct field; otherwise, they would query
* each-other, which would produce conflicts if the events happen to
* have the same name (which would not be uncommon).
*/
it( 'is not accessible to other Evented instances', () =>
{
var ev = 'foo',
f = () => {};
// this would fail if data were shared because the system would
// consider f to have already been registered with event `foo'
[ stub, EvStub() ].forEach( s =>
s.evDefineEvents( [ ev ] )
.on( ev, f )
);
} );
} );
} ); } );