Skip to content

Add ThreadSafeArrayReturn cpp class attribute #216

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: release/1.8.0-alpha
Choose a base branch
from
Open
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