Skip to content

Commit 344f077

Browse files
Embind: Make subclasses inherit class functions (#18794)
1 parent 4874997 commit 344f077

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

src/embind/embind.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,6 +2047,15 @@ var LibraryEmbind = {
20472047
upcast,
20482048
downcast);
20492049

2050+
if (registeredClass.baseClass) {
2051+
// Keep track of class hierarchy. Used to allow sub-classes to inherit class functions.
2052+
if (registeredClass.baseClass.__derivedClasses === undefined) {
2053+
registeredClass.baseClass.__derivedClasses = [];
2054+
}
2055+
2056+
registeredClass.baseClass.__derivedClasses.push(registeredClass);
2057+
}
2058+
20502059
var referenceConverter = new RegisteredPointer(name,
20512060
registeredClass,
20522061
true,
@@ -2353,6 +2362,16 @@ var LibraryEmbind = {
23532362
} else {
23542363
proto[methodName].overloadTable[argCount-1] = func;
23552364
}
2365+
2366+
if (classType.registeredClass.__derivedClasses) {
2367+
for (const derivedClass of classType.registeredClass.__derivedClasses) {
2368+
if (!derivedClass.constructor.hasOwnProperty(methodName)) {
2369+
// TODO: Add support for overloads
2370+
derivedClass.constructor[methodName] = func;
2371+
}
2372+
}
2373+
}
2374+
23562375
return [];
23572376
});
23582377
return [];

test/embind/embind.test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ module({
111111
derived.delete();
112112
});
113113

114+
test("class functions are inherited in subclasses", function() {
115+
assert.equal("Base", cm.Base.classFunction());
116+
assert.equal("Derived", cm.Derived.classFunction());
117+
assert.equal("Derived", cm.DerivedTwice.classFunction());
118+
});
119+
114120
test("calling method on unrelated class throws error", function() {
115121
var a = new cm.HasTwoBases;
116122
var e = assert.throws(cm.BindingError, function() {

test/embind/embind_test.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,9 @@ class Base {
490490
int getBaseMember() {
491491
return baseMember;
492492
}
493+
static std::string classFunction() {
494+
return "Base";
495+
};
493496
std::string name;
494497
int member;
495498
int baseMember;
@@ -546,6 +549,9 @@ class Derived : public Base{
546549
int getMember() {
547550
return member;
548551
}
552+
static std::string classFunction() {
553+
return "Derived";
554+
}
549555
int member;
550556
private:
551557
std::string name_;
@@ -2019,6 +2025,7 @@ EMSCRIPTEN_BINDINGS(tests) {
20192025
.function("getMember", &Derived::getMember)
20202026
.function("setMember", &Derived::setMember)
20212027
.property("member", &Derived::member)
2028+
.class_function("classFunction", &Derived::classFunction)
20222029
;
20232030

20242031
class_<Base>("Base")
@@ -2033,6 +2040,7 @@ EMSCRIPTEN_BINDINGS(tests) {
20332040
.function("setBaseMember", &Base::setBaseMember)
20342041
.property("member", &Base::member)
20352042
.property("baseMember", &Base::baseMember)
2043+
.class_function("classFunction", &Base::classFunction)
20362044
;
20372045

20382046
class_<SecondBase>("SecondBase")

0 commit comments

Comments
 (0)