dsdapobp26141 2019-05-08 17:54
浏览 111
已采纳

在Go中的Goroutine中运行并使用SDL

I have a program with multiple multiple loops, each one ran in a Goroutine. I need to plug or unplug monitors while my program runs, so I have to restart the sdl to let it find my new monitors, I do it by sdl.quit() to quit the last sdl and sdl.init(sdl.InitEverything) to initialize it again. My problem is that I have to handle the sdl events in a loop, If I don't it will become unresponsive, but this loop will block my Main code. I don't need to handle any events like mouse clicks, I just want to show some simple picture and manipulate them, is there any way to stop events or run the whole sdl in a goroutine? I tried but get weird results. This is my struct:

type SDLstruct{
    window *sdl.Window
    renderer *sdl.Renderer
    texture *sdl.Texture
    src, dst sdl.Rect
    event sdl.Event
    Close bool
    winWidth, winHeight int32
}

This function starts a window and a renderer:

func (sdlVars *SDLstruct)StartWindow() (err error) {

    sdlVars.winWidth, sdlVars.winHeight = 1920,1080
    sdl.Init(sdl.INIT_VIDEO)
    Num,err :=sdl.GetNumVideoDisplays()
    if err!=nil {
        return err
    }
    var rect sdl.Rect
    rect,err = sdl.GetDisplayBounds(0)
    if err!=nil {
        return err
    }
    for i:=Num-1;i>=0;i--{
        Mod , _:=sdl.GetDisplayMode(i,0)
        if Mod.W ==info.winWidth && Mod.H==info.winHeight{
            rect,err = sdl.GetDisplayBounds(i)
            if err!=nil {
                return err
            }
            break
        }
    }
    sdlVars.window, err = sdl.CreateWindow(winTitle, rect.X, rect.Y,
        rect.W, rect.H, sdl.WINDOW_SHOWN)
    sdlVars.window.SetBordered(false)
    sdlVars.window.SetFullscreen(1)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Failed to create window: %s
", err)
        return err
    }
    sdlVars.renderer, err = sdl.CreateRenderer(sdlVars.window, -1, sdl.RENDERER_ACCELERATED)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Failed to create renderer: %s
", err)
        return err
    }
    sdlVars.renderer.Clear()
    sdlVars.renderer.SetDrawColor(0, 0, 0, 255)
    sdlVars.renderer.FillRect(&sdl.Rect{0, 0, int32(info.winWidth), int32(info.winHeight)})
    sdlVars.renderer.Present()
    sdl.ShowCursor(0)
    return nil
}

This function handle events:

func (sdlVars *SDLstruct)HandleEvents()  {
    for sdlVars.event = sdl.PollEvent(); sdlVars.event != nil; sdlVars.event = sdl.PollEvent() {
        switch t := sdlVars.event.(type) {
        case *sdl.QuitEvent:
            sdlVars.Close = true
        }
    }
}

and this one closes everything:

func (sdlVars *SDLstruct)CloseSDL() (err error) {
    err =sdlVars.renderer.Destroy()
    if err!=nil{
        return err
    }
    err = sdlVars.window.Destroy()
    if err!=nil{
        return err
    }
    sdl.Quit()
    return nil
}

This is my Main function:

func main()  {
    var wg sync.WaitGroup
    SdlVars:= new(SDLstruct)
    wg.Add(1)
    go SdlVars.StartSDL()
    time.Sleep(time.Second*5)
    SdlVars.Close = true
    time.Sleep(time.Second*15)
}

In my Main function I tell it to start the sdl and after 5 seconds close everything and wait 15 seconds, but it doesn't close window.

  • 写回答

1条回答 默认 最新

  • duanjunao9348 2019-05-08 18:22
    关注

    Be careful as using SDL from multiple threads is not entirely trivial. Typically, your SDL loop must sit in the main thread. There is a good reason for that and it's because the event loop is part of the main thread and many of your objects are created and mutated on the main thread...or at least they should be.

    When you introduce multiple threads weird undefined and dangerous behavior could happen. This is why a good rule of thumb is to use runtime.LockOSThread to ensure the Go runtime doesn't pin your main goroutine to other threads and keeps it on the main thread.

    See this for more details: enter link description here

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于c++外部库文件宏的问题,求解
  • ¥15 office打开卡退(新电脑重装office系统后)
  • ¥300 FLUENT 火箭发动机燃烧EDC仿真
  • ¥15 【Hadoop 问题】Hadoop编译所遇问题hadoop-common: make failed with error code 2
  • ¥15 vb6.0+webbrowser无法加载某个网页求解
  • ¥15 RPA财务机器人采购付款流程
  • ¥15 计算机图形多边形及三次样条曲线绘制
  • ¥15 根据protues画的图用keil写程序
  • ¥200 如何使用postGis实现最短领规划?
  • ¥15 pyinstaller打包错误