go-python / gopy

gopy generates a CPython extension module from a go package.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

gopy: only one function signature arg allowed

mauserzjeh opened this issue · comments

First of all, my aim is to be able to load certain assets in memory with multiple goroutines for speed/performance and once an asset is loaded into memory I would like to call a callback function that would be passed from python.

i.e:

  • Have a golang function that loads assets/files into memory
  • This function is built into the python module, thus I can call it from python and additionally pass callback functions to it
  • Assets are loaded in multiple goroutines
  • Every time an asset is loaded, call a callback function, which was passed to the import function

What am I doing wrong?

I get the following error when trying to build my package:

gopy: only one function signature arg allowed

$ ./build_importer.sh
go build -v importer

--- Processing package: importer ---
ignoring python incompatible method: importer.func (*importer.Importer).ImportIBSP(assetPath string, filePath string, poolSize uint, callbackIbsp func(importer.LoadedIBSP), callbackMaterial func(importer.LoadedMaterial), callbackXmodel func(importer.LoadedModel)) error: func(assetPath string, filePath string, poolSize uint, callbackIbsp func(importer.LoadedIBSP), callbackMaterial func(importer.LoadedMaterial), callbackXmodel func(importer.LoadedModel)) error: gopy: only one function signature arg allowed: func(assetPath string, filePath string, poolSize uint, callbackIbsp func(importer.LoadedIBSP), callbackMaterial func(importer.LoadedMaterial), callbackXmodel func(importer.LoadedModel)) error
no LibDir -- copy from IncDir: C:/Users/soma/AppData/Local/Programs/Python/Python311/Include
no LibPy -- set to: python311
no LibDir -- copy from IncDir: C:/Users/soma/AppData/Local/Programs/Python/Python311/Include
no LibPy -- set to: python311

--- building package ---
gopy.exe build -output=importer -vm=python importer
goimports -w importer.go
no LibDir -- copy from IncDir: C:/Users/soma/AppData/Local/Programs/Python/Python311/Include
no LibPy -- set to: python311
go build -mod=mod -buildmode=c-shared -o importer_go.pyd .
C:\Users\soma\AppData\Local\Programs\Python\Python311\python.exe build.py
Doing windows sed hack to fix declspec for PyInit
CGO_CFLAGS=-IC:/Users/soma/AppData/Local/Programs/Python/Python311/Include -fPIC -Ofast
CGO_LDFLAGS=-LC:/Users/soma/AppData/Local/Programs/Python/Python311/Include -lpython311
go build -mod=mod -buildmode=c-shared -o _importer.cp311-win_amd64.pyd .

this is the part of the code the error talks about:

// ImportBSP
func (imp *Importer) ImportIBSP(assetPath, filePath string, poolSize uint, callbackIbsp func(LoadedIBSP), callbackMaterial func(LoadedMaterial), callbackXmodel func(LoadedModel)) error {
	ibsp := assets.IBSP{}
	err := ibsp.Load(filePath)
	if err != nil {
		return errorLogAndReturn(err)
	}

	wp := newWorkerPool(poolSize)

	wg := sync.WaitGroup{}
	for _, mat := range ibsp.Materials {
		wg.Add(1)

		wp.addTask(func() {
			defer wg.Done()

			version := assets.VERSION_COD1
			if ibsp.Header.Version == assets.IBSP_VER_v4 {
				version = assets.VERSION_COD2
			}
			loadedMaterial, err := imp.loadMaterial(assetPath, mat.GetName(), version)
			if err != nil {
				errorLog(err)
				return
			}
                        
                        // python callback function
			callbackMaterial(loadedMaterial) // <--
		})

	}

	wg.Wait()

        // python callback function
	callbackIbsp(LoadedIBSP{
		IBSP: ibsp,
	}) // <--

	for _, ent := range ibsp.Entities {
		wg.Add(1)

		wp.addTask(func() {
			defer wg.Done()

			xmodelFilePath := path.Join(assetPath, assets.ASSETPATH_XMODEL, ent.Name)
			loadedModel, err := imp.ImportXModel(assetPath, xmodelFilePath)
			if err != nil {
				errorLog(err)
				return
			}

			loadedModel.Angles = ent.Angles
			loadedModel.Origin = ent.Origin
			loadedModel.Scale = ent.Scale
                        
                        // python callback function
			callbackXmodel(loadedModel) // <--
		})
	}

	wg.Wait()

	wp.stop()
	return nil
}

// ImportXModel
func (imp *Importer) ImportXModel(assetPath, filePath string) (LoadedModel, error) {
	xmodel := assets.XModel{}
	err := xmodel.Load(filePath)
	if err != nil {
		return LoadedModel{}, errorLogAndReturn(err)
	}

	lod0 := xmodel.Lods[0]
	xmodelPartFilePath := path.Join(assetPath, assets.ASSETPATH_XMODELPARTS, lod0.Name)
	xmodelPart := &assets.XModelPart{}
	err = xmodelPart.Load(xmodelPartFilePath)
	if err != nil {
		errorLog(err)
		xmodelPart = nil
	}

	xmodelSurfFilePath := path.Join(assetPath, assets.ASSETPATH_XMODELSURFS, lod0.Name)
	xmodelSurf := assets.XModelSurf{}
	err = xmodelSurf.Load(xmodelSurfFilePath, xmodelPart)
	if err != nil {
		return LoadedModel{}, errorLogAndReturn(err)
	}

	loadedMaterials := []LoadedMaterial{}
	if xmodel.Version == assets.VERSION_COD2 || xmodel.Version == assets.VERSION_COD4 {
		for _, mat := range lod0.Materials {
			loadedMaterial, err := imp.loadMaterial(assetPath, mat, int(xmodel.Version))
			if err != nil {
				errorLog(err)
				continue
			}

			loadedMaterials = append(loadedMaterials, loadedMaterial)
		}
	}

	loadedModel := LoadedModel{
		XModel:     xmodel,
		XModelSurf: xmodelSurf,
		Materials:  loadedMaterials,
		Angles:     assets.Vec3{},
		Origin:     assets.Vec3{},
		Scale: assets.Vec3{
			X: 1,
			Y: 1,
			Z: 1,
		},
	}

	if xmodelPart != nil {
		loadedModel.XModelPart = *xmodelPart
	}

	return loadedModel, nil
}

// loadMaterial
func (imp *Importer) loadMaterial(assetPath, materialName string, version int) (LoadedMaterial, error) {
	materialFilePath := path.Join(assetPath, assets.ASSETPATH_MATERIALS, materialName)
	material := assets.Material{}
	err := material.Load(materialFilePath, version)
	if err != nil {
		return LoadedMaterial{}, errorLogAndReturn(err)
	}

	loadedTextures := map[string]assets.IWI{}
	for _, tex := range material.Textures {
		if _, ok := loadedTextures[tex.Name]; ok {
			continue
		}

		textFilePath := path.Join(assetPath, assets.ASSETPATH_TEXTURES, tex.Name)
		texture := assets.IWI{}
		err := texture.Load(textFilePath)
		if err != nil {
			errorLog(err)
			continue
		}

		loadedTextures[tex.Name] = texture
	}

	return LoadedMaterial{
		Material: material,
		Textures: loadedTextures,
	}, nil
}

If I only pass one callback function it doesn't throw the error. How could I solve this problem when I need to call multiple callback functions, depending on the type of asset loaded?