////////////////////////////////////////////////////////////////////////////////
// Do not modify!
// Generated by codergen
////////////////////////////////////////////////////////////////////////////////

package service

import (
	"android.googlesource.com/platform/tools/gpu/binary/registry"
	"android.googlesource.com/platform/tools/gpu/log"
	"android.googlesource.com/platform/tools/gpu/multiplexer"
	"android.googlesource.com/platform/tools/gpu/rpc"
	"android.googlesource.com/platform/tools/gpu/service/path"
)

// Client is the client interface for Service calls.
type Client interface {
	// Client exposes all the Service interface methods.
	Service
	// Multiplexer returns the multiplexer used for communication to the server.
	Multiplexer() *multiplexer.Multiplexer
	// Namespace returns the custom namespace used for decoding responses from the
	// server, or nil if no custom namespace has been specified.
	Namespace() *registry.Namespace
}
type client struct{ rpc.Client }

// NewClient creates a new rpc client object that uses the multiplexer m for
// communication the namespace n for decoding objects. If n is nil then the
// global namespace is used.
func NewClient(m *multiplexer.Multiplexer, n *registry.Namespace) Client {
	return client{rpc.NewClient(m, n)}
}

// Client compliance
func (c client) Follow(p path.Path, l log.Logger) (res path.Path, err error) {
	var val interface{}
	if val, err = c.Send(&callFollow{p: p}); err == nil {
		res = val.(*resultFollow).value
	} else {
		log.Errorf(l, "Service Follow failed with error: %v", err)
	}
	return
}

func (c client) Get(p path.Path, l log.Logger) (res interface{}, err error) {
	var val interface{}
	if val, err = c.Send(&callGet{p: p}); err == nil {
		res = val.(*resultGet).value
	} else {
		log.Errorf(l, "Service Get failed with error: %v", err)
	}
	return
}

func (c client) GetCaptures(l log.Logger) (res []*path.Capture, err error) {
	var val interface{}
	if val, err = c.Send(&callGetCaptures{}); err == nil {
		res = val.(*resultGetCaptures).value
	} else {
		log.Errorf(l, "Service GetCaptures failed with error: %v", err)
	}
	return
}

func (c client) GetDevices(l log.Logger) (res []*path.Device, err error) {
	var val interface{}
	if val, err = c.Send(&callGetDevices{}); err == nil {
		res = val.(*resultGetDevices).value
	} else {
		log.Errorf(l, "Service GetDevices failed with error: %v", err)
	}
	return
}

func (c client) GetFramebufferColor(device *path.Device, after *path.Atom, settings RenderSettings, l log.Logger) (res *path.ImageInfo, err error) {
	var val interface{}
	if val, err = c.Send(&callGetFramebufferColor{device: device, after: after, settings: settings}); err == nil {
		res = val.(*resultGetFramebufferColor).value
	} else {
		log.Errorf(l, "Service GetFramebufferColor failed with error: %v", err)
	}
	return
}

func (c client) GetFramebufferDepth(device *path.Device, after *path.Atom, l log.Logger) (res *path.ImageInfo, err error) {
	var val interface{}
	if val, err = c.Send(&callGetFramebufferDepth{device: device, after: after}); err == nil {
		res = val.(*resultGetFramebufferDepth).value
	} else {
		log.Errorf(l, "Service GetFramebufferDepth failed with error: %v", err)
	}
	return
}

func (c client) GetSchema(l log.Logger) (res Schema, err error) {
	var val interface{}
	if val, err = c.Send(&callGetSchema{}); err == nil {
		res = val.(*resultGetSchema).value
	} else {
		log.Errorf(l, "Service GetSchema failed with error: %v", err)
	}
	return
}

func (c client) GetTimingInfo(device *path.Device, capture *path.Capture, flags TimingFlags, l log.Logger) (res *path.TimingInfo, err error) {
	var val interface{}
	if val, err = c.Send(&callGetTimingInfo{device: device, capture: capture, flags: flags}); err == nil {
		res = val.(*resultGetTimingInfo).value
	} else {
		log.Errorf(l, "Service GetTimingInfo failed with error: %v", err)
	}
	return
}

func (c client) Import(name string, Data []uint8, l log.Logger) (res *path.Capture, err error) {
	var val interface{}
	if val, err = c.Send(&callImport{name: name, Data: Data}); err == nil {
		res = val.(*resultImport).value
	} else {
		log.Errorf(l, "Service Import failed with error: %v", err)
	}
	return
}

func (c client) PrerenderFramebuffers(device *path.Device, capture *path.Capture, api ApiID, width uint32, height uint32, atomIDs []uint64, l log.Logger) error {
	_, err := c.Send(&callPrerenderFramebuffers{device: device, capture: capture, api: api, width: width, height: height, atomIDs: atomIDs})
	return err
}

func (c client) Set(p path.Path, v interface{}, l log.Logger) (res path.Path, err error) {
	var val interface{}
	if val, err = c.Send(&callSet{p: p, v: v}); err == nil {
		res = val.(*resultSet).value
	} else {
		log.Errorf(l, "Service Set failed with error: %v", err)
	}
	return
}
