// SpriteMap returns a sprite from the passed glob and sprite // parameters. func SpriteMap(ctx *libsass.Context, usv libsass.UnionSassValue) libsass.UnionSassValue { var glob string var spacing libsass.SassNumber err := libsass.Unmarshal(usv, &glob, &spacing) if err != nil { return libsass.Error(err) } imgs := sw.ImageList{ ImageDir: ctx.ImageDir, BuildDir: ctx.BuildDir, GenImgDir: ctx.GenImgDir, } imgs.Padding = int(spacing.Value) if cglob, err := strconv.Unquote(glob); err == nil { glob = cglob } key := glob + strconv.FormatInt(int64(spacing.Value), 10) // TODO: benchmark a single write lock against this // read lock then write lock ctx.Sprites.RLock() if _, ok := ctx.Sprites.M[key]; ok { ctx.Sprites.RUnlock() res, err := libsass.Marshal(key) if err != nil { return libsass.Error(err) } return res } ctx.Sprites.RUnlock() err = imgs.Decode(glob) if err != nil { return libsass.Error(err) } _, err = imgs.Combine() if err != nil { return libsass.Error(err) } _, err = imgs.Export() if err != nil { return libsass.Error(err) } res, err := libsass.Marshal(key) ctx.Sprites.Lock() ctx.Sprites.M[key] = imgs ctx.Sprites.Unlock() if err != nil { return libsass.Error(err) } return res }