File size: 2,760 Bytes
d46f4a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package com.mojang.blaze3d.resource;

import com.google.common.annotations.VisibleForTesting;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

@OnlyIn(Dist.CLIENT)
public class CrossFrameResourcePool implements GraphicsResourceAllocator, AutoCloseable {
    private final int framesToKeepResource;
    private final Deque<CrossFrameResourcePool.ResourceEntry<?>> pool = new ArrayDeque<>();

    public CrossFrameResourcePool(int p_363418_) {
        this.framesToKeepResource = p_363418_;
    }

    public void endFrame() {
        Iterator<? extends CrossFrameResourcePool.ResourceEntry<?>> iterator = this.pool.iterator();

        while (iterator.hasNext()) {
            CrossFrameResourcePool.ResourceEntry<?> resourceentry = (CrossFrameResourcePool.ResourceEntry<?>)iterator.next();
            if (resourceentry.framesToLive-- == 0) {
                resourceentry.close();
                iterator.remove();
            }
        }
    }

    @Override
    public <T> T acquire(ResourceDescriptor<T> p_364134_) {
        Iterator<? extends CrossFrameResourcePool.ResourceEntry<?>> iterator = this.pool.iterator();

        while (iterator.hasNext()) {
            CrossFrameResourcePool.ResourceEntry<?> resourceentry = (CrossFrameResourcePool.ResourceEntry<?>)iterator.next();
            if (resourceentry.descriptor.equals(p_364134_)) {
                iterator.remove();
                return (T)resourceentry.value;
            }
        }

        return p_364134_.allocate();
    }

    @Override
    public <T> void release(ResourceDescriptor<T> p_370226_, T p_369520_) {
        this.pool.addFirst(new CrossFrameResourcePool.ResourceEntry<>(p_370226_, p_369520_, this.framesToKeepResource));
    }

    public void clear() {
        this.pool.forEach(CrossFrameResourcePool.ResourceEntry::close);
        this.pool.clear();
    }

    @Override
    public void close() {
        this.clear();
    }

    @VisibleForTesting
    protected Collection<CrossFrameResourcePool.ResourceEntry<?>> entries() {
        return this.pool;
    }

    @OnlyIn(Dist.CLIENT)
    @VisibleForTesting
    protected static final class ResourceEntry<T> implements AutoCloseable {
        final ResourceDescriptor<T> descriptor;
        final T value;
        int framesToLive;

        ResourceEntry(ResourceDescriptor<T> p_361734_, T p_367770_, int p_363856_) {
            this.descriptor = p_361734_;
            this.value = p_367770_;
            this.framesToLive = p_363856_;
        }

        @Override
        public void close() {
            this.descriptor.free(this.value);
        }
    }
}