internal/restorable/images.go
func (i *images) restore() error {
	if !IsRestoringEnabled() {
		panic("restorable: restore cannot be called when restoring is disabled")
	}

	// Dispose image explicitly
	for img := range i.images {
		img.image.Dispose()
		// img.image can't be set nil here, or Size() panics when restoring.
	}

	// Let's do topological sort based on dependencies of drawing history.
	// It is assured that there are not loops since cyclic drawing makes images stale.
	type edge struct {
		source *Image
		target *Image
	}
	images := map[*Image]struct{}{}
	for i := range i.images {
		if !i.priority {
			images[i] = struct{}{}
		}
	}
	edges := map[edge]struct{}{}
	for t := range images {
		for s := range t.dependingImages() {
			edges[edge{source: s, target: t}] = struct{}{}
		}
	}

	sorted := []*Image{}
	for i := range i.images {
		if i.priority {
			sorted = append(sorted, i)
		}
	}
	for len(images) > 0 {
		// current repesents images that have no incoming edges.
		current := map[*Image]struct{}{}
		for i := range images {
			current[i] = struct{}{}
		}
		for e := range edges {
			if _, ok := current[e.target]; ok {
				delete(current, e.target)
			}
		}
		for i := range current {
			delete(images, i)
			sorted = append(sorted, i)
		}
		removed := []edge{}
		for e := range edges {
			if _, ok := current[e.source]; ok {
				removed = append(removed, e)
			}
		}
		for _, e := range removed {
			delete(edges, e)
		}
	}

	for _, img := range sorted {
		if err := img.restore(); err != nil {
			return err
		}
	}
	return nil
}
func (i *images) restore() error {
	if !IsRestoringEnabled() {
		panic("restorable: restore cannot be called when restoring is disabled")
	}

	// Dispose image explicitly
	for img := range i.images {
		img.image.Dispose()
		// img.image can't be set nil here, or Size() panics when restoring.
	}

	// Let's do topological sort based on dependencies of drawing history.
	// It is assured that there are not loops since cyclic drawing makes images stale.
	type edge struct {
		source *Image
		target *Image
	}
	images := map[*Image]struct{}{}
	for i := range i.images {
		if !i.priority {
			images[i] = struct{}{}
		}
	}
	edges := map[edge]struct{}{}
	for t := range images {
		for s := range t.dependingImages() {
			edges[edge{source: s, target: t}] = struct{}{}
		}
	}

	sorted := []*Image{}
	for i := range i.images {
		if i.priority {
			sorted = append(sorted, i)
		}
	}
	for len(images) > 0 {
		// current repesents images that have no incoming edges.
		current := map[*Image]struct{}{}
		for i := range images {
			current[i] = struct{}{}
		}
		for e := range edges {
			if _, ok := current[e.target]; ok {
				delete(current, e.target)
			}
		}
		for i := range current {
			delete(images, i)
			sorted = append(sorted, i)
		}
		removed := []edge{}
		for e := range edges {
			if _, ok := current[e.source]; ok {
				removed = append(removed, e)
			}
		}
		for _, e := range removed {
			delete(edges, e)
		}
	}

	for _, img := range sorted {
		if err := img.restore(); err != nil {
			return err
		}
	}
	return nil
}
func ( i * images ) restore ( ) error { if ! IsRestoringEnabled ( ) { panic ( " " ) } // Dispose image explicitly for img := range i . images { img . image . Dispose ( ) // img.image can't be set nil here, or Size() panics when restoring. } // Let's do topological sort based on dependencies of drawing history. // It is assured that there are not loops since cyclic drawing makes images stale. type edge struct { source * Image target * Image } images := map [ * Image ] struct { } { } for i := range i . images { if ! i . priority { images [ i ] = struct { } { } } } edges := map [ edge ] struct { } { } for t := range images { for s := range t . dependingImages ( ) { edges [ edge { source : s , target : t } ] = struct { } { } } } sorted := [ ] * Image { } for i := range i . images { if i . priority { sorted = append ( sorted , i ) } } for len ( images ) > 0 { // current repesents images that have no incoming edges. current := map [ * Image ] struct { } { } for i := range images { current [ i ] = struct { } { } } for e := range edges { if _ , ok := current [ e . target ] ; ok { delete ( current , e . target ) } } for i := range current { delete ( images , i ) sorted = append ( sorted , i ) } removed := [ ] edge { } for e := range edges { if _ , ok := current [ e . source ] ; ok { removed = append ( removed , e ) } } for _ , e := range removed { delete ( edges , e ) } } for _ , img := range sorted { if err := img . restore ( ) ; err != nil { return err } } return nil }
// restore restores the images.
//
// Restoring means to make all *graphicscommand.Image objects have their textures and framebuffers.
restore restores the images . Restoring means to make all * graphicscommand . Image objects have their textures and framebuffers .