mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
Simplify internal API not to return errors
This commit is contained in:
parent
cad051437d
commit
147798e14d
4
image.go
4
image.go
@ -123,9 +123,7 @@ func (i *images) clearVolatileImages() error {
|
|||||||
i.m.Lock()
|
i.m.Lock()
|
||||||
defer i.m.Unlock()
|
defer i.m.Unlock()
|
||||||
for img := range i.images {
|
for img := range i.images {
|
||||||
if err := img.clearIfVolatile(); err != nil {
|
img.clearIfVolatile()
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
41
imageimpl.go
41
imageimpl.go
@ -52,13 +52,8 @@ func newImageImpl(width, height int, filter Filter, volatile bool) (*imageImpl,
|
|||||||
if err := checkSize(width, height); err != nil {
|
if err := checkSize(width, height); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
img, err := restorable.NewImage(width, height, glFilter(filter), volatile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
i := &imageImpl{
|
i := &imageImpl{
|
||||||
restorable: img,
|
restorable: restorable.NewImage(width, height, glFilter(filter), volatile),
|
||||||
}
|
}
|
||||||
runtime.SetFinalizer(i, (*imageImpl).Dispose)
|
runtime.SetFinalizer(i, (*imageImpl).Dispose)
|
||||||
return i, nil
|
return i, nil
|
||||||
@ -77,12 +72,8 @@ func newImageImplFromImage(source image.Image, filter Filter) (*imageImpl, error
|
|||||||
// an image is delayed and we can't expect the source image is not modified
|
// an image is delayed and we can't expect the source image is not modified
|
||||||
// until the construction.
|
// until the construction.
|
||||||
rgbaImg := graphics.CopyImage(source)
|
rgbaImg := graphics.CopyImage(source)
|
||||||
img, err := restorable.NewImageFromImage(rgbaImg, w, h, glFilter(filter))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
i := &imageImpl{
|
i := &imageImpl{
|
||||||
restorable: img,
|
restorable: restorable.NewImageFromImage(rgbaImg, w, h, glFilter(filter)),
|
||||||
}
|
}
|
||||||
runtime.SetFinalizer(i, (*imageImpl).Dispose)
|
runtime.SetFinalizer(i, (*imageImpl).Dispose)
|
||||||
return i, nil
|
return i, nil
|
||||||
@ -92,13 +83,8 @@ func newScreenImageImpl(width, height int) (*imageImpl, error) {
|
|||||||
if err := checkSize(width, height); err != nil {
|
if err := checkSize(width, height); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
img, err := restorable.NewScreenFramebufferImage(width, height)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
i := &imageImpl{
|
i := &imageImpl{
|
||||||
restorable: img,
|
restorable: restorable.NewScreenFramebufferImage(width, height),
|
||||||
}
|
}
|
||||||
runtime.SetFinalizer(i, (*imageImpl).Dispose)
|
runtime.SetFinalizer(i, (*imageImpl).Dispose)
|
||||||
return i, nil
|
return i, nil
|
||||||
@ -111,22 +97,17 @@ func (i *imageImpl) Fill(clr color.Color) error {
|
|||||||
return errors.New("ebiten: image is already disposed")
|
return errors.New("ebiten: image is already disposed")
|
||||||
}
|
}
|
||||||
rgba := color.RGBAModel.Convert(clr).(color.RGBA)
|
rgba := color.RGBAModel.Convert(clr).(color.RGBA)
|
||||||
if err := i.restorable.Fill(rgba); err != nil {
|
i.restorable.Fill(rgba)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imageImpl) clearIfVolatile() error {
|
func (i *imageImpl) clearIfVolatile() {
|
||||||
i.m.Lock()
|
i.m.Lock()
|
||||||
defer i.m.Unlock()
|
defer i.m.Unlock()
|
||||||
if i.restorable == nil {
|
if i.restorable == nil {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
if err := i.restorable.ClearIfVolatile(); err != nil {
|
i.restorable.ClearIfVolatile()
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error {
|
func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error {
|
||||||
@ -160,9 +141,7 @@ func (i *imageImpl) DrawImage(image *Image, options *DrawImageOptions) error {
|
|||||||
return errors.New("ebiten: image is already disposed")
|
return errors.New("ebiten: image is already disposed")
|
||||||
}
|
}
|
||||||
mode := opengl.CompositeMode(options.CompositeMode)
|
mode := opengl.CompositeMode(options.CompositeMode)
|
||||||
if err := i.restorable.DrawImage(image.impl.restorable, vs, options.ColorM.impl, mode); err != nil {
|
i.restorable.DrawImage(image.impl.restorable, vs, options.ColorM.impl, mode)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,9 +241,7 @@ func (i *imageImpl) ReplacePixels(p []uint8) error {
|
|||||||
for j := 0; j < h; j++ {
|
for j := 0; j < h; j++ {
|
||||||
copy(pix[j*w2*4:], p[j*w*4:(j+1)*w*4])
|
copy(pix[j*w2*4:], p[j*w*4:(j+1)*w*4])
|
||||||
}
|
}
|
||||||
if err := i.restorable.ReplacePixels(pix); err != nil {
|
i.restorable.ReplacePixels(pix)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ type Image struct {
|
|||||||
|
|
||||||
const ImageMaxSize = viewportSize
|
const ImageMaxSize = viewportSize
|
||||||
|
|
||||||
func NewImage(width, height int, filter opengl.Filter) (*Image, error) {
|
func NewImage(width, height int, filter opengl.Filter) *Image {
|
||||||
i := &Image{
|
i := &Image{
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
@ -90,10 +90,10 @@ func NewImage(width, height int, filter opengl.Filter) (*Image, error) {
|
|||||||
filter: filter,
|
filter: filter,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
return i, nil
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImageFromImage(img *image.RGBA, width, height int, filter opengl.Filter) (*Image, error) {
|
func NewImageFromImage(img *image.RGBA, width, height int, filter opengl.Filter) *Image {
|
||||||
i := &Image{
|
i := &Image{
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
@ -104,10 +104,10 @@ func NewImageFromImage(img *image.RGBA, width, height int, filter opengl.Filter)
|
|||||||
filter: filter,
|
filter: filter,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
return i, nil
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewScreenFramebufferImage(width, height int) (*Image, error) {
|
func NewScreenFramebufferImage(width, height int) *Image {
|
||||||
i := &Image{
|
i := &Image{
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
@ -118,32 +118,30 @@ func NewScreenFramebufferImage(width, height int) (*Image, error) {
|
|||||||
height: height,
|
height: height,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
return i, nil
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) Dispose() error {
|
func (i *Image) Dispose() {
|
||||||
c := &disposeCommand{
|
c := &disposeCommand{
|
||||||
target: i,
|
target: i,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) Size() (int, int) {
|
func (i *Image) Size() (int, int) {
|
||||||
return i.width, i.height
|
return i.width, i.height
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) Fill(clr color.RGBA) error {
|
func (i *Image) Fill(clr color.RGBA) {
|
||||||
// TODO: Need to clone clr value
|
// TODO: Need to clone clr value
|
||||||
c := &fillCommand{
|
c := &fillCommand{
|
||||||
dst: i,
|
dst: i,
|
||||||
color: clr,
|
color: clr,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) DrawImage(src *Image, vertices []float32, clr affine.ColorM, mode opengl.CompositeMode) error {
|
func (i *Image) DrawImage(src *Image, vertices []float32, clr affine.ColorM, mode opengl.CompositeMode) {
|
||||||
c := &drawImageCommand{
|
c := &drawImageCommand{
|
||||||
dst: i,
|
dst: i,
|
||||||
src: src,
|
src: src,
|
||||||
@ -153,7 +151,6 @@ func (i *Image) DrawImage(src *Image, vertices []float32, clr affine.ColorM, mod
|
|||||||
}
|
}
|
||||||
theCommandQueue.AppendVertices(vertices)
|
theCommandQueue.AppendVertices(vertices)
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) Pixels(context *opengl.Context) ([]uint8, error) {
|
func (i *Image) Pixels(context *opengl.Context) ([]uint8, error) {
|
||||||
@ -168,7 +165,7 @@ func (i *Image) Pixels(context *opengl.Context) ([]uint8, error) {
|
|||||||
return context.FramebufferPixels(f.native, NextPowerOf2Int(i.width), NextPowerOf2Int(i.height))
|
return context.FramebufferPixels(f.native, NextPowerOf2Int(i.width), NextPowerOf2Int(i.height))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) ReplacePixels(p []uint8) error {
|
func (i *Image) ReplacePixels(p []uint8) {
|
||||||
pixels := make([]uint8, len(p))
|
pixels := make([]uint8, len(p))
|
||||||
copy(pixels, p)
|
copy(pixels, p)
|
||||||
c := &replacePixelsCommand{
|
c := &replacePixelsCommand{
|
||||||
@ -176,7 +173,6 @@ func (i *Image) ReplacePixels(p []uint8) error {
|
|||||||
pixels: pixels,
|
pixels: pixels,
|
||||||
}
|
}
|
||||||
theCommandQueue.Enqueue(c)
|
theCommandQueue.Enqueue(c)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) IsInvalidated(context *opengl.Context) bool {
|
func (i *Image) IsInvalidated(context *opengl.Context) bool {
|
||||||
|
@ -46,46 +46,33 @@ type Image struct {
|
|||||||
screen bool
|
screen bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImage(width, height int, filter opengl.Filter, volatile bool) (*Image, error) {
|
func NewImage(width, height int, filter opengl.Filter, volatile bool) *Image {
|
||||||
img, err := graphics.NewImage(width, height, filter)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Image{
|
return &Image{
|
||||||
image: img,
|
image: graphics.NewImage(width, height, filter),
|
||||||
filter: filter,
|
filter: filter,
|
||||||
volatile: volatile,
|
volatile: volatile,
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImageFromImage(source *image.RGBA, width, height int, filter opengl.Filter) (*Image, error) {
|
func NewImageFromImage(source *image.RGBA, width, height int, filter opengl.Filter) *Image {
|
||||||
img, err := graphics.NewImageFromImage(source, width, height, filter)
|
|
||||||
if err != nil {
|
|
||||||
// TODO: texture should be removed here?
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
w2, h2 := graphics.NextPowerOf2Int(width), graphics.NextPowerOf2Int(height)
|
w2, h2 := graphics.NextPowerOf2Int(width), graphics.NextPowerOf2Int(height)
|
||||||
p := make([]uint8, 4*w2*h2)
|
p := make([]uint8, 4*w2*h2)
|
||||||
for j := 0; j < height; j++ {
|
for j := 0; j < height; j++ {
|
||||||
copy(p[j*w2*4:(j+1)*w2*4], source.Pix[j*source.Stride:])
|
copy(p[j*w2*4:(j+1)*w2*4], source.Pix[j*source.Stride:])
|
||||||
}
|
}
|
||||||
return &Image{
|
return &Image{
|
||||||
image: img,
|
image: graphics.NewImageFromImage(source, width, height, filter),
|
||||||
basePixels: p,
|
basePixels: p,
|
||||||
filter: filter,
|
filter: filter,
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewScreenFramebufferImage(width, height int) (*Image, error) {
|
func NewScreenFramebufferImage(width, height int) *Image {
|
||||||
img, err := graphics.NewScreenFramebufferImage(width, height)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Image{
|
return &Image{
|
||||||
image: img,
|
image: graphics.NewScreenFramebufferImage(width, height),
|
||||||
volatile: true,
|
volatile: true,
|
||||||
screen: true,
|
screen: true,
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Image) Size() (int, int) {
|
func (p *Image) Size() (int, int) {
|
||||||
@ -99,9 +86,9 @@ func (p *Image) makeStale() {
|
|||||||
p.stale = true
|
p.stale = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Image) ClearIfVolatile() error {
|
func (p *Image) ClearIfVolatile() {
|
||||||
if !p.volatile {
|
if !p.volatile {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
p.basePixels = nil
|
p.basePixels = nil
|
||||||
p.baseColor = color.RGBA{}
|
p.baseColor = color.RGBA{}
|
||||||
@ -110,44 +97,32 @@ func (p *Image) ClearIfVolatile() error {
|
|||||||
if p.image == nil {
|
if p.image == nil {
|
||||||
panic("not reach")
|
panic("not reach")
|
||||||
}
|
}
|
||||||
if err := p.image.Fill(color.RGBA{}); err != nil {
|
p.image.Fill(color.RGBA{})
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Image) Fill(clr color.RGBA) error {
|
func (p *Image) Fill(clr color.RGBA) {
|
||||||
p.basePixels = nil
|
p.basePixels = nil
|
||||||
p.baseColor = clr
|
p.baseColor = clr
|
||||||
p.drawImageHistory = nil
|
p.drawImageHistory = nil
|
||||||
p.stale = false
|
p.stale = false
|
||||||
if err := p.image.Fill(clr); err != nil {
|
p.image.Fill(clr)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Image) ReplacePixels(pixels []uint8) error {
|
func (p *Image) ReplacePixels(pixels []uint8) {
|
||||||
if err := p.image.ReplacePixels(pixels); err != nil {
|
p.image.ReplacePixels(pixels)
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.basePixels = pixels
|
p.basePixels = pixels
|
||||||
p.baseColor = color.RGBA{}
|
p.baseColor = color.RGBA{}
|
||||||
p.drawImageHistory = nil
|
p.drawImageHistory = nil
|
||||||
p.stale = false
|
p.stale = false
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Image) DrawImage(img *Image, vertices []float32, colorm affine.ColorM, mode opengl.CompositeMode) error {
|
func (p *Image) DrawImage(img *Image, vertices []float32, colorm affine.ColorM, mode opengl.CompositeMode) {
|
||||||
if img.stale || img.volatile {
|
if img.stale || img.volatile {
|
||||||
p.makeStale()
|
p.makeStale()
|
||||||
} else {
|
} else {
|
||||||
p.appendDrawImageHistory(img, vertices, colorm, mode)
|
p.appendDrawImageHistory(img, vertices, colorm, mode)
|
||||||
}
|
}
|
||||||
if err := p.image.DrawImage(img.image, vertices, colorm, mode); err != nil {
|
p.image.DrawImage(img.image, vertices, colorm, mode)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Image) appendDrawImageHistory(image *Image, vertices []float32, colorm affine.ColorM, mode opengl.CompositeMode) {
|
func (p *Image) appendDrawImageHistory(image *Image, vertices []float32, colorm affine.ColorM, mode opengl.CompositeMode) {
|
||||||
@ -196,7 +171,6 @@ func (p *Image) MakeStaleIfDependingOn(target *Image) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Image) readPixelsFromVRAM(image *graphics.Image, context *opengl.Context) error {
|
func (p *Image) readPixelsFromVRAM(image *graphics.Image, context *opengl.Context) error {
|
||||||
@ -234,11 +208,7 @@ func (p *Image) Restore(context *opengl.Context) error {
|
|||||||
if p.screen {
|
if p.screen {
|
||||||
// The screen image should also be recreated because framebuffer might
|
// The screen image should also be recreated because framebuffer might
|
||||||
// be changed.
|
// be changed.
|
||||||
var err error
|
p.image = graphics.NewScreenFramebufferImage(w, h)
|
||||||
p.image, err = graphics.NewScreenFramebufferImage(w, h)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.basePixels = nil
|
p.basePixels = nil
|
||||||
p.baseColor = color.RGBA{}
|
p.baseColor = color.RGBA{}
|
||||||
p.drawImageHistory = nil
|
p.drawImageHistory = nil
|
||||||
@ -246,11 +216,7 @@ func (p *Image) Restore(context *opengl.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if p.volatile {
|
if p.volatile {
|
||||||
var err error
|
p.image = graphics.NewImage(w, h, p.filter)
|
||||||
p.image, err = graphics.NewImage(w, h, p.filter)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.basePixels = nil
|
p.basePixels = nil
|
||||||
p.baseColor = color.RGBA{}
|
p.baseColor = color.RGBA{}
|
||||||
p.drawImageHistory = nil
|
p.drawImageHistory = nil
|
||||||
@ -258,6 +224,7 @@ func (p *Image) Restore(context *opengl.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if p.stale {
|
if p.stale {
|
||||||
|
// TODO: panic here?
|
||||||
return errors.New("restorable: pixels must not be stale when restoring")
|
return errors.New("restorable: pixels must not be stale when restoring")
|
||||||
}
|
}
|
||||||
w2, h2 := graphics.NextPowerOf2Int(w), graphics.NextPowerOf2Int(h)
|
w2, h2 := graphics.NextPowerOf2Int(w), graphics.NextPowerOf2Int(h)
|
||||||
@ -267,29 +234,23 @@ func (p *Image) Restore(context *opengl.Context) error {
|
|||||||
copy(img.Pix[j*img.Stride:], p.basePixels[j*w2*4:(j+1)*w2*4])
|
copy(img.Pix[j*img.Stride:], p.basePixels[j*w2*4:(j+1)*w2*4])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gimg, err := graphics.NewImageFromImage(img, w, h, p.filter)
|
gimg := graphics.NewImageFromImage(img, w, h, p.filter)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if p.baseColor != (color.RGBA{}) {
|
if p.baseColor != (color.RGBA{}) {
|
||||||
if p.basePixels != nil {
|
if p.basePixels != nil {
|
||||||
panic("not reach")
|
panic("not reach")
|
||||||
}
|
}
|
||||||
if err := gimg.Fill(p.baseColor); err != nil {
|
gimg.Fill(p.baseColor)
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for _, c := range p.drawImageHistory {
|
for _, c := range p.drawImageHistory {
|
||||||
// c.image.image must be already restored.
|
// c.image.image must be already restored.
|
||||||
if c.image.HasDependency() {
|
if c.image.HasDependency() {
|
||||||
panic("not reach")
|
panic("not reach")
|
||||||
}
|
}
|
||||||
if err := gimg.DrawImage(c.image.image, c.vertices, c.colorm, c.mode); err != nil {
|
gimg.DrawImage(c.image.image, c.vertices, c.colorm, c.mode)
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
p.image = gimg
|
p.image = gimg
|
||||||
|
|
||||||
|
var err error
|
||||||
p.basePixels, err = gimg.Pixels(context)
|
p.basePixels, err = gimg.Pixels(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -301,9 +262,7 @@ func (p *Image) Restore(context *opengl.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Image) Dispose() error {
|
func (p *Image) Dispose() error {
|
||||||
if err := p.image.Dispose(); err != nil {
|
p.image.Dispose()
|
||||||
return err
|
|
||||||
}
|
|
||||||
p.image = nil
|
p.image = nil
|
||||||
p.basePixels = nil
|
p.basePixels = nil
|
||||||
p.baseColor = color.RGBA{}
|
p.baseColor = color.RGBA{}
|
||||||
|
Loading…
Reference in New Issue
Block a user