diff options
author | Chad Austin <chad@imvu.com> | 2014-05-08 21:41:34 -0700 |
---|---|---|
committer | Bruce Mitchener <bruce.mitchener@gmail.com> | 2014-05-21 22:58:53 +0700 |
commit | c75048adf764b9f14ed7a91dc46dfaee66dcbf3a (patch) | |
tree | a48c0405aa3e7bd5d81c31261697fba38d864f80 /src | |
parent | ec70dcb7bc76221949c057b5284c256d9959579a (diff) |
If embind knows about a live JavaScript instance and it matches a raw pointer that gets returned, then return the JS instance.
Diffstat (limited to 'src')
-rw-r--r-- | src/embind/embind.js | 72 |
1 files changed, 60 insertions, 12 deletions
diff --git a/src/embind/embind.js b/src/embind/embind.js index ef16e952..f9bfa9e8 100644 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -153,6 +153,30 @@ function _embind_repr(v) { } } +// raw pointer -> instance +var registeredInstances = {}; + +function registerInheritedInstance(ptr, instance) { + if (registeredInstances.hasOwnProperty(ptr)) { + throwBindingError('Tried to register registered instance: ' + ptr); + } else { + registeredInstances[ptr] = instance; + } +} + +function unregisterInheritedInstance(ptr) { + if (registeredInstances.hasOwnProperty(ptr)) { + delete registeredInstances[ptr]; + } else { + throwBindingError('Tried to unregister unregistered instance: ' + ptr); + } +} + +function getInheritedInstanceCount() { + return Object.keys(registeredInstances).length; +} +Module['getInheritedInstanceCount'] = getInheritedInstanceCount; + // typeID -> { toWireType: ..., fromWireType: ... } var registeredTypes = {}; @@ -1152,6 +1176,13 @@ RegisteredPointer.prototype['fromWireType'] = function fromWireType(ptr) { return null; } + var registeredInstance = registeredInstances[rawPointer]; + if (undefined !== registeredInstance) { + var rv = registeredInstance['clone'](); + this.destructor(ptr); + return rv; + } + function makeDefaultHandle() { if (this.isSmartPointer) { return makeClassHandle(this.registeredClass.instancePrototype, { @@ -1262,14 +1293,19 @@ ClassHandle.prototype['clone'] = function clone() { throwInstanceAlreadyDeleted(this); } - var clone = Object.create(Object.getPrototypeOf(this), { - $$: { - value: shallowCopy(this.$$), - } - }); + if (this.$$.preservePointerOnDelete) { + this.$$.count.value += 1; + return this; + } else { + var clone = Object.create(Object.getPrototypeOf(this), { + $$: { + value: shallowCopy(this.$$), + } + }); - clone.$$.count.value += 1; - return clone; + clone.$$.count.value += 1; + return clone; + } }; function runDestructor(handle) { @@ -1285,16 +1321,21 @@ ClassHandle.prototype['delete'] = function ClassHandle_delete() { if (!this.$$.ptr) { throwInstanceAlreadyDeleted(this); } + + // TODO: test for multiple deleteLater() on JS instance handle if (this.$$.deleteScheduled) { throwBindingError('Object already scheduled for deletion'); } this.$$.count.value -= 1; - if (0 === this.$$.count.value) { + var toDelete = 0 === this.$$.count.value; + if (toDelete) { runDestructor(this); } - this.$$.smartPtr = undefined; - this.$$.ptr = undefined; + if (toDelete || !this.$$.preservePointerOnDelete) { + this.$$.smartPtr = undefined; + this.$$.ptr = undefined; + } }; var deletionQueue = []; @@ -1359,7 +1400,9 @@ function RegisteredClass( function shallowCopy(o) { var rv = {}; for (var k in o) { - rv[k] = o[k]; + if (Object.prototype.hasOwnProperty.call(o, k)) { + rv[k] = o[k]; + } } return rv; } @@ -1764,16 +1807,21 @@ function __embind_create_inheriting_constructor(constructorName, wrapperType, pr }); // It's a little nasty that we're modifying the wrapper prototype here. + wrapperPrototype.__construct = function __construct() { var inner = baseConstructor.__$implement.apply( undefined, [this].concat(arraySlice.call(arguments))); + var $$ = inner.$$; + $$.preservePointerOnDelete = true; Object.defineProperty(this, '$$', { - value: inner.$$ + value: $$ }); + registerInheritedInstance($$.ptr, this); }; wrapperPrototype.__destruct = function __destruct() { + unregisterInheritedInstance(this.$$.ptr); }; ctor.prototype = Object.create(wrapperPrototype); |