Skip to content

gopy: only one function signature arg allowed #332

Description

@mauserzjeh

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
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions