<go語言編程>第三章音樂庫代碼整理

目錄結構:
目錄結構

manager.go

package library

import (
    "errors"
)

type MusicEntry struct {
    Id     string
    Name   string
    Artist string
    Source string
    Type   string
}

type MusicManager struct {
    musics []MusicEntry
}

func NewMusicManager() *MusicManager {
    return &MusicManager{make([]MusicEntry, 0)}
}

func (m *MusicManager) Len() int {
    return len(m.musics)
}

func (m *MusicManager) Get(index int) (music *MusicEntry, err error) {
    if index < 0 || index >= len(m.musics) {
        return nil, errors.New("Index out of range.")
    }
    return &m.musics[index], nil
}

func (m *MusicManager) Find(name string) *MusicEntry {
    if len(m.musics) == 0 {
        return nil
    }
    for _, m := range m.musics {
        if m.Name == name {
            return &m
        }
    }
    return nil
}

func (m *MusicManager) RemoveByName(name string) *MusicEntry {
    if len(m.musics) == 0 {
        return nil
    }

    for i, v := range m.musics {
        if v.Name == name {
            return m.Remove(i)
        }
    }
    return nil
}

func (m *MusicManager) Add(music *MusicEntry) {
    m.musics = append(m.musics, *music)
}

func (m *MusicManager) Remove(index int) *MusicEntry {
    if index < 0 || index >= len(m.musics) {
        return nil
    }

    removeMusic := &m.musics[index]

    //從數組切片中刪除元素
    if index < len(m.musics)-1 {
        m.musics = append(m.musics[:index-1], m.musics[index+1:]...)
    } else if index == 0 {
        m.musics = make([]MusicEntry, 0)
    } else {
        m.musics = m.musics[:index-1]
    }

    return removeMusic
}

manager_test.go

package library

import (
    "testing"
)

func TestOps(t *testing.T) {
    mm := NewMusicManager()
    if mm == nil {
        t.Error("NewMusicManager failed.")
    }
    if mm.Len() != 0 {
        t.Error("NewMusicManager failed, not empty.")
    }
    m0 := &MusicEntry{
        "2", "smx", "smx", "/www/lll.mp3", "MP3"}
    mm.Add(m0)

    if mm.Len() != 1 {
        t.Error("MusicManager.Add() failed.")
    }

    m := mm.Find(m0.Name)
    if m == nil {
        t.Error("MusicManager.Find() Failed.")
    }
    if m.Id != m0.Id || m.Artist != m0.Artist || m.Name != m0.Name || m.Source != m0.Source || m.Type != m0.Type {
        t.Error("MusicManager.Find() failed. Found item mismatch.")
    }

    m, err := mm.Get(0)
    if m == nil {
        t.Error("MusicManager.Get() failed.", err)
    }

    m = mm.Remove(0)
    if m == nil || mm.Len() != 0 {
        t.Error("MusicManager.Remove() failed.", err)
    }
}

mp3.go

package mp

import (
    "fmt"
    "time"
)

type MP3Player struct {
    stat     int
    progress int
}

func (p *MP3Player) Play(source string) {
    fmt.Println("Playing MP3 MUSIC", source)

    p.progress = 0

    for p.progress < 100 {
        time.Sleep(100 * time.Millisecond)
        fmt.Print(".")
        p.progress += 10
    }

    fmt.Println("\nFinished playing", source)
}

play.go

package mp

import (
    "fmt"
)

type Player interface {
    Play(source string)
}

func Play(source, mtype string) {
    var p Player
    switch mtype {
    case "MP3":
        p = &MP3Player{}
    case "MAV":
        //p = &MAVPlayer{}
    default:
        fmt.Println("Unsupported music type", mtype)
        return
    }
    p.Play(source)
}

mplayer.go

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"

    "music/library"
    "music/mp"
)

var lib *library.MusicManager
var id int = 1
var ctrl, signal chan int

func handleLibCommands(tokens []string) {
    switch tokens[1] {
    case "list":
        for i := 0; i < lib.Len(); i++ {
            e, _ := lib.Get(i)
            fmt.Println(i+1, ":", e.Name, e.Artist, e.Source, e.Type)
        }
    case "add":
        {
            if len(tokens) == 6 {
                id++
                lib.Add(&library.MusicEntry{strconv.Itoa(id), tokens[2], tokens[3], tokens[4], tokens[5]})
            } else {
                fmt.Println("USAGE: lib add <name><artist><source><type>")
            }
        }
    case "remove":
        if len(tokens) == 3 {
            index, _ := strconv.Atoi(tokens[2])
            lib.Remove(index)
            //lib.RemoveByName(tokens[2])
        } else {
            fmt.Println("USAGE: lib remove <name>")
        }
    default:
        fmt.Println("Unrecognized lib command:", tokens[1])
    }

}

func handlePlayCommand(tokens []string) {
    if len(tokens) != 2 {
        fmt.Println("USAGE:play <name>")
        return
    }

    e := lib.Find(tokens[1])
    if e == nil {
        fmt.Println("The music", tokens[1], "does not exist")
        return
    }

    mp.Play(e.Source, e.Type)
}

func main() {
    fmt.Println(`Enter following commands to control the player:
        lib list -- View the existing music lib 8 
        lib add <name><artist><source><type> -- Add a music to the music lib 
        lib remove <name> -- Remove the specified music from the lib
        play <name> -- Play the specified music
        q   -- quit `)
    lib = library.NewMusicManager()
    r := bufio.NewReader(os.Stdin)
    for {
        fmt.Print("Enter command->")
        rawLine, _, _ := r.ReadLine()
        line := string(rawLine)
        if line == "q" || line == "e" {
            break
        }

        tokens := strings.Split(line, " ")

        if tokens[0] == "lib" {
            handleLibCommands(tokens)
        } else if tokens[0] == "play" {
            handlePlayCommand(tokens)
        } else {
            fmt.Println("Unrecognized command:", tokens[0])
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章