' Copyright 2017 <chaishushan{AT}gmail.com>. All rights reserved.
' Use of this source code is governed by a Apache
' license that can be found in the LICENSE file.

@startuml

title qsort

participant go
participant c

[--> go: qsort
activate go

go -> go
activate go #DarkSalmon
note left
	go_qsort_compare_info.elemsize = sv.Type().Elem().Size()
	go_qsort_compare_info.fn = fn
end note

deactivate go

go -> c: C.qsort_proxy(cmp=go_qsort_compare)
activate c
note right
void qsort_proxy(
	void* base, size_t num, size_t size,
	int (*compare)(const void* a, const void* b)
) {
	go_qsort_compare_save_base(base);
	qsort(base, num, size, compare);
}
end note

' begin
	c -> c: C.go_qsort_compare_save_base
	activate c #DarkSalmon
	note right: callback go func

	go <- c: go_qsort_compare_save_base
	activate go #DarkSalmon
	note left
		//export go_qsort_compare_save_base
		func go_qsort_compare_save_base(base unsafe.Pointer) {
			go_qsort_compare_info.base = uintptr(base)
		}
		var go_qsort_compare_info struct {
			base     uintptr
			elemsize uintptr
			fn       func(a, b int) int
			sync.RWMutex
		}
	end note

	go -> c: go_qsort_compare_save_base done
	deactivate go

	deactivate c
' end

loop
	c -> c: C.go_qsort_compare
	activate c #DarkSalmon
	note right: callback go func

	c -> go: go_qsort_compare
	activate go #DarkSalmon
	note left
		//export go_qsort_compare_save_base
		func go_qsort_compare_save_base(base unsafe.Pointer) {
			go_qsort_compare_info.base = uintptr(base)
		}
	end note

	go -> c: go_qsort_compare done
	deactivate go

	deactivate c
end

go <- c: C.qsort_proxy done
deactivate c

[<-- go: done
deactivate go

@enduml
