Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions Source/buildbindingccpp.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ func writeDynamicCPPMethodDeclaration(method ComponentDefinitionMethod, w Langua
}

func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, NameSpace string, ClassIdentifier string, ClassName string,
implementationLines []string, isGlobal bool, includeComments bool, doNotThrow bool, useCPPTypes bool, ExplicitLinking bool, forWASM bool) error {
implementationLines []string, isGlobal bool, includeComments bool, doNotThrow bool, useCPPTypes bool, ExplicitLinking bool, forWASM bool, threadSafeArrayReturn bool) error {

WASMPrefix := ""
WASMCast := ""
Expand Down Expand Up @@ -875,6 +875,12 @@ func writeDynamicCPPMethod(method ComponentDefinitionMethod, w LanguageWriter, N
}

w.Writeln(" {")

threadSafeArrayReturnRequired := threadSafeArrayReturn && requiresInitCall
if threadSafeArrayReturnRequired {
w.Writeln(" std::lock_guard<std::mutex> lock(%s);", getThreadSafeArrayReturnMutexName())
}

w.Writelns(" ", definitionCodeLines)
if requiresInitCall {
w.Writeln(" %s%s(%s)%s;", checkErrorCodeBegin, CMethodName, initCallParameters, checkErrorCodeEnd)
Expand Down Expand Up @@ -1185,6 +1191,14 @@ func getBindingCppVariableName(param ComponentDefinitionParam) string {
return ""
}

func getThreadSafeArrayReturnMutexName() string {
return "ArrayReturnMutex"
}

func isThreadSafeArrayReturn(param ComponentDefinitionClass) bool {
return param.ArrayReturnOption == "ThreadSafe"
}

func getCPPInheritanceSpecifier(component ComponentDefinition, class ComponentDefinitionClass, cppClassPrefix string, ClassIdentifier string) (string, string) {
cppParentClassName := ""
inheritanceSpecifier := ""
Expand Down Expand Up @@ -1377,6 +1391,10 @@ func writeClassDeclarations(w LanguageWriter, component ComponentDefinition, cpp
w.Writeln(" Class %s ", cppClassName)
w.Writeln("**************************************************************************************************************************/")
w.Writeln("class %s %s{", cppClassName, inheritanceSpecifier)
if isThreadSafeArrayReturn(class) {
w.Writeln("private:")
w.Writeln(" std::mutex %s;", getThreadSafeArrayReturnMutexName())
}
w.Writeln("public:")
w.Writeln(" ")
if !component.isBaseClass(class) {
Expand Down Expand Up @@ -1510,6 +1528,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s
w.Writeln("#include <array>")
w.Writeln("#include <string>")
w.Writeln("#include <memory>")
w.Writeln("#include <mutex>")
w.Writeln("#include <vector>")
w.Writeln("#include <exception>")
w.Writeln("")
Expand Down Expand Up @@ -1622,7 +1641,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s
implementationLines = append(implementationLines, fmt.Sprintf(" throw E%sException(%s_ERROR_COULDNOTLOADLIBRARY, \"Unknown namespace \" + %s);", NameSpace, strings.ToUpper(NameSpace), sParamName))
}

err = writeDynamicCPPMethod(method, w, NameSpace, ClassIdentifier, "Wrapper", implementationLines, true, true, false, useCPPTypes, ExplicitLinking, false)
err = writeDynamicCPPMethod(method, w, NameSpace, ClassIdentifier, "Wrapper", implementationLines, true, true, false, useCPPTypes, ExplicitLinking, false, false)
if err != nil {
return err
}
Expand All @@ -1648,7 +1667,7 @@ func buildCppHeader(component ComponentDefinition, w LanguageWriter, NameSpace s
w.Writeln(" */")
for j := 0; j < len(class.Methods); j++ {
method := class.Methods[j]
err := writeDynamicCPPMethod(method, w, NameSpace, ClassIdentifier, class.ClassName, make([]string, 0), false, true, false, useCPPTypes, ExplicitLinking, false)
err := writeDynamicCPPMethod(method, w, NameSpace, ClassIdentifier, class.ClassName, make([]string, 0), false, true, false, useCPPTypes, ExplicitLinking, false, isThreadSafeArrayReturn(class))
if err != nil {
return err
}
Expand Down Expand Up @@ -2217,7 +2236,7 @@ func buildCppwasmGuestHeader(component ComponentDefinition, w LanguageWriter, Na
implementationLines = append(implementationLines, fmt.Sprintf(" throw E%sException(%s_ERROR_COULDNOTLOADLIBRARY, \"Unknown namespace \" + %s);", NameSpace, strings.ToUpper(NameSpace), sParamName))
}

err = writeDynamicCPPMethod(method, w, NameSpace, ClassIdentifier, "Wrapper", implementationLines, true, true, false, useCPPTypes, ExplicitLinking, true)
err = writeDynamicCPPMethod(method, w, NameSpace, ClassIdentifier, "Wrapper", implementationLines, true, true, false, useCPPTypes, ExplicitLinking, true, false)
if err != nil {
return err
}
Expand All @@ -2236,7 +2255,7 @@ func buildCppwasmGuestHeader(component ComponentDefinition, w LanguageWriter, Na
w.Writeln(" */")
for j := 0; j < len(class.Methods); j++ {
method := class.Methods[j]
err := writeDynamicCPPMethod(method, w, NameSpace, ClassIdentifier, class.ClassName, make([]string, 0), false, true, false, useCPPTypes, ExplicitLinking, true)
err := writeDynamicCPPMethod(method, w, NameSpace, ClassIdentifier, class.ClassName, make([]string, 0), false, true, false, useCPPTypes, ExplicitLinking, true, isThreadSafeArrayReturn(class))
if err != nil {
return err
}
Expand Down
13 changes: 13 additions & 0 deletions Source/componentdefinition.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ type ComponentDefinitionClass struct {
ClassName string `xml:"name,attr"`
ClassDescription string `xml:"description,attr"`
ParentClass string `xml:"parent,attr"`
ArrayReturnOption string `xml:"arrayReturnOption,attr"`
Methods []ComponentDefinitionMethod `xml:"method"`
}

Expand Down Expand Up @@ -531,6 +532,9 @@ func (component *ComponentDefinition) checkClasses() (error) {
if len(class.ClassDescription) > 0 && !descriptionIsValid(class.ClassDescription) {
return fmt.Errorf ("invalid class description \"%s\" in class \"%s\"", class.ClassDescription, class.ClassName);
}
if len(class.ArrayReturnOption) > 0 && !arrayReturnOptionIsValid(class.ArrayReturnOption) {
return fmt.Errorf("invalid class array return option \"%s\" in class \"%s\"", class.ArrayReturnOption, class.ClassName)
}
collision, hashExists := classTypeIdIndex[classTypeHash]
if hashExists {
return fmt.Errorf ("Classes \"%s\" and \"%s\" have a collision in their Class Type Id. Change class name.", classes[collision].ClassName, class.ClassName);
Expand Down Expand Up @@ -796,6 +800,15 @@ func descriptionIsValid(description string) bool {
return false;
}

func arrayReturnOptionIsValid(arrayReturnOption string) bool {
switch arrayReturnOption {
case "ThreadSafe":
return true
}

return false
}

func isScalarType(typeStr string) bool {
switch (typeStr) {
case "uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64", "bool", "single", "double", "pointer":
Expand Down