3
3
import com .github .benmanes .caffeine .cache .CacheLoader ;
4
4
import com .github .benmanes .caffeine .cache .Caffeine ;
5
5
import com .github .benmanes .caffeine .cache .LoadingCache ;
6
+ import com .github .benmanes .caffeine .cache .Scheduler ;
6
7
import io .izzel .mesmerize .api .cause .CauseManager ;
7
8
import io .izzel .mesmerize .api .event .DamageCalculator ;
8
9
import io .izzel .mesmerize .api .event .StatsRefreshEvent ;
29
30
import org .bukkit .entity .Entity ;
30
31
import org .bukkit .persistence .PersistentDataContainer ;
31
32
import org .bukkit .persistence .PersistentDataType ;
33
+ import org .checkerframework .checker .index .qual .Positive ;
34
+ import org .checkerframework .checker .nullness .qual .NonNull ;
32
35
import org .jetbrains .annotations .NotNull ;
33
36
34
37
import java .util .Collections ;
35
38
import java .util .Set ;
36
39
import java .util .concurrent .Callable ;
37
40
import java .util .concurrent .ConcurrentHashMap ;
41
+ import java .util .concurrent .Executor ;
42
+ import java .util .concurrent .Future ;
43
+ import java .util .concurrent .FutureTask ;
38
44
import java .util .concurrent .TimeUnit ;
39
45
40
46
public class SimpleStatsService implements StatsService {
@@ -45,32 +51,34 @@ public class SimpleStatsService implements StatsService {
45
51
private final ElementFactory elementFactory = new SimpleElementFactory ();
46
52
private final DamageCalculator calculator = new SimpleCalculator ();
47
53
48
- private final Set <Integer > entityLock = Collections .newSetFromMap (new ConcurrentHashMap <>());
49
-
50
54
private final CacheLoader <Entity , StatsSet > cacheLoader = entity -> {
51
- Callable < StatsSet > callable = () -> {
52
- if (! entity . isValid () || entity . isDead ()) {
53
- return null ;
54
- }
55
+ if (! entity . isValid () || entity . isDead ()) {
56
+ return null ;
57
+ }
58
+ if ( Bukkit . isPrimaryThread ()) {
55
59
StatsSet statsSet = new StatsSet ();
56
60
newEntityReader (entity ).accept (statsSet , VisitMode .VALUE );
57
61
Bukkit .getPluginManager ().callEvent (new StatsRefreshEvent (entity , statsSet ));
58
62
return statsSet ;
59
- };
60
- if (Bukkit .isPrimaryThread ()) {
61
- return callable .call ();
62
63
} else {
63
- try {
64
- entityLock .add (entity .getEntityId ());
65
- return Bukkit .getScheduler ().callSyncMethod (Mesmerize .instance (), callable ).get ();
66
- } finally {
67
- entityLock .remove (entity .getEntityId ());
68
- }
64
+ throw new IllegalStateException ("async stats load" );
69
65
}
70
66
};
71
67
72
68
private final LoadingCache <Entity , StatsSet > statsSetCache = Caffeine
73
69
.newBuilder ()
70
+ .scheduler ((executor , command , delay , unit ) -> {
71
+ FutureTask <?> task = new FutureTask <>(command , null );
72
+ Bukkit .getScheduler ().runTaskLater (Mesmerize .instance (), () -> executor .execute (task ), unit .toMillis (delay ) / 50 );
73
+ return task ;
74
+ })
75
+ .executor (r -> {
76
+ if (Bukkit .isPrimaryThread ()) {
77
+ r .run ();
78
+ } else {
79
+ throw new IllegalStateException ("async stats load" );
80
+ }
81
+ })
74
82
.refreshAfterWrite (ConfigSpec .spec ().performance ().entityStatsCacheMs (), TimeUnit .MILLISECONDS )
75
83
.build (cacheLoader );
76
84
@@ -91,20 +99,7 @@ public CauseManager getCauseManager() {
91
99
92
100
@ Override
93
101
public StatsSet cachedSetFor (@ NotNull Entity entity ) {
94
- if (!Bukkit .isPrimaryThread ()) {
95
- throw new IllegalStateException ("async stats get" );
96
- }
97
- StatsSet set ;
98
- if (entityLock .contains (entity .getEntityId ())) {
99
- try {
100
- set = cacheLoader .load (entity );
101
- } catch (Exception e ) {
102
- throw new RuntimeException (e );
103
- }
104
- } else {
105
- set = statsSetCache .get (entity );
106
- }
107
- return set == null ? new StatsSet () : set ;
102
+ return statsSetCache .get (entity );
108
103
}
109
104
110
105
@ Override
0 commit comments