mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-10 09:22:49 +00:00
Base AI, new Cache system, DAO changes and better geometry handling
Signed-off-by: Rogiel <rogiel@rogiel.com>
This commit is contained in:
113
src/main/java/com/l2jserver/service/cache/AbstractReferenceCache.java
vendored
Normal file
113
src/main/java/com/l2jserver/service/cache/AbstractReferenceCache.java
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.l2jserver.service.cache.SoftCacheService.SoftCache;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
import com.sun.beans.WeakCache;
|
||||
|
||||
/**
|
||||
* Base class for {@link WeakCache} and {@link SoftCache}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <K>
|
||||
* the key type
|
||||
* @param <V>
|
||||
* the value type
|
||||
*/
|
||||
abstract class AbstractReferenceCache<K, V> implements Cache<K, V> {
|
||||
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* The cache name
|
||||
*/
|
||||
protected final String cacheName;
|
||||
|
||||
/**
|
||||
* Map storing references to cached objects
|
||||
*/
|
||||
protected final Map<K, Reference<V>> cacheMap = CollectionFactory.newMap();
|
||||
/**
|
||||
* The reference queue
|
||||
*/
|
||||
protected final ReferenceQueue<V> refQueue = CollectionFactory
|
||||
.newReferenceQueue();
|
||||
|
||||
/**
|
||||
* @param cacheName
|
||||
* the cache name
|
||||
*/
|
||||
protected AbstractReferenceCache(String cacheName) {
|
||||
this.cacheName = cacheName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(K key, V value) {
|
||||
cleanQueue();
|
||||
|
||||
Reference<V> entry = newReference(key, value, refQueue);
|
||||
cacheMap.put(key, entry);
|
||||
|
||||
log.debug("{}: added for key: {}", cacheName, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(K key) {
|
||||
cleanQueue();
|
||||
|
||||
Reference<V> reference = cacheMap.get(key);
|
||||
if (reference == null)
|
||||
return null;
|
||||
|
||||
V res = reference.get();
|
||||
if (res != null)
|
||||
log.debug("{}: obtained for key: {}", cacheName, key);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(K key) {
|
||||
cleanQueue();
|
||||
return cacheMap.containsKey(key);
|
||||
}
|
||||
|
||||
protected abstract void cleanQueue();
|
||||
|
||||
@Override
|
||||
public void remove(K key) {
|
||||
cacheMap.remove(key);
|
||||
log.debug("{}: removed for key: {}", cacheName, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
cacheMap.clear();
|
||||
log.debug("{}: cleared", cacheName);
|
||||
}
|
||||
|
||||
protected abstract Reference<V> newReference(K key, V value,
|
||||
ReferenceQueue<V> queue);
|
||||
}
|
||||
64
src/main/java/com/l2jserver/service/cache/Cache.java
vendored
Normal file
64
src/main/java/com/l2jserver/service/cache/Cache.java
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
/**
|
||||
* This interface represents a Map structure for cache usage.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface Cache<K, V> {
|
||||
/**
|
||||
* Adds a pair <key,value> to cache.<br>
|
||||
* <br>
|
||||
*
|
||||
* <font color='red'><b>NOTICE:</b> </font> if there is already a value with
|
||||
* given id in the map, {@link IllegalArgumentException} will be thrown.
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
void put(K key, V value);
|
||||
|
||||
/**
|
||||
* Returns cached value correlated to given key.
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
V get(K key);
|
||||
|
||||
/**
|
||||
* Checks whether this map contains a value related to given key.
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
boolean contains(K key);
|
||||
|
||||
/**
|
||||
* Removes an entry from the map, that has given key.
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
void remove(K key);
|
||||
|
||||
/**
|
||||
* Clears this cache
|
||||
*/
|
||||
void clear();
|
||||
}
|
||||
@@ -16,8 +16,6 @@
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
|
||||
import com.l2jserver.service.Service;
|
||||
|
||||
/**
|
||||
@@ -31,7 +29,6 @@ import com.l2jserver.service.Service;
|
||||
* {@link IgnoreCaching}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public interface CacheService extends Service {
|
||||
/**
|
||||
@@ -50,39 +47,60 @@ public interface CacheService extends Service {
|
||||
|
||||
/**
|
||||
* Creates a new cache with default configurations. Eviction mode is LRU
|
||||
* (Last Recently Used). If you wish more customization, you should manually
|
||||
* create the cache and register it using {@link #register(Cache)}.
|
||||
* (Last Recently Used). The size is only a guarantee that you can store
|
||||
* <b>at least</b> <tt>n</tt> items.
|
||||
*
|
||||
* @param <K>
|
||||
* the cache key type
|
||||
* @param <V>
|
||||
* the cache value type
|
||||
* @param name
|
||||
* the cache name
|
||||
* @size the maximum cache size
|
||||
* @return the created cache
|
||||
*/
|
||||
Cache createCache(String name, int size);
|
||||
<K, V> Cache<K, V> createCache(String name, int size);
|
||||
|
||||
/**
|
||||
* Creates a new eternal cache with default configurations. An eternal cache
|
||||
* is guaranteed to never automatically expire items. The size is only a
|
||||
* guarantee that you can store <b>at least</b> <tt>n</tt> items.
|
||||
*
|
||||
* @param <K>
|
||||
* the cache key type
|
||||
* @param <V>
|
||||
* the cache value type
|
||||
* @param name
|
||||
* the cache name
|
||||
* @size the maximum cache size
|
||||
* @return the created cache
|
||||
*/
|
||||
<K, V> Cache<K, V> createEternalCache(String name, int size);
|
||||
|
||||
/**
|
||||
* Creates a new cache with default configurations. The default cache size
|
||||
* is 200.
|
||||
* is 200. The size is only a guarantee that you can store <b>at least</b>
|
||||
* 200 items.
|
||||
*
|
||||
* @param <K>
|
||||
* the cache key type
|
||||
* @param <V>
|
||||
* the cache value type
|
||||
* @param name
|
||||
* the cache name
|
||||
* @return the created cache
|
||||
*/
|
||||
Cache createCache(String name);
|
||||
<K, V> Cache<K, V> createCache(String name);
|
||||
|
||||
/**
|
||||
* Registers a new cache
|
||||
* Disposes the cache. Once the cache is disposed it cannot be used anymore.
|
||||
*
|
||||
* @param <K>
|
||||
* the cache key type
|
||||
* @param <V>
|
||||
* the cache value type
|
||||
* @param cache
|
||||
* the cache
|
||||
*/
|
||||
void register(Cache cache);
|
||||
|
||||
/**
|
||||
* Unregisters an already registered cache
|
||||
*
|
||||
* @param cache
|
||||
* the cache
|
||||
*/
|
||||
void unregister(Cache cache);
|
||||
<K, V> void dispose(Cache<K, V> cache);
|
||||
}
|
||||
|
||||
@@ -20,9 +20,7 @@ import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import net.sf.ehcache.Element;
|
||||
import net.sf.ehcache.config.CacheConfiguration;
|
||||
@@ -48,7 +46,7 @@ public class EhCacheService extends AbstractService implements CacheService {
|
||||
/**
|
||||
* The interface cache
|
||||
*/
|
||||
private Cache interfaceCache;
|
||||
private Cache<MethodInvocation, Object> interfaceCache;
|
||||
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
@@ -76,10 +74,7 @@ public class EhCacheService extends AbstractService implements CacheService {
|
||||
return method.invoke(instance, args);
|
||||
final MethodInvocation invocation = new MethodInvocation(
|
||||
method, args);
|
||||
Element element = interfaceCache.get(invocation);
|
||||
if (element == null)
|
||||
return doInvoke(invocation, proxy, method, args);
|
||||
Object result = element.getObjectValue();
|
||||
Object result = interfaceCache.get(invocation);
|
||||
if (result == null)
|
||||
return doInvoke(invocation, proxy, method, args);
|
||||
return result;
|
||||
@@ -90,43 +85,94 @@ public class EhCacheService extends AbstractService implements CacheService {
|
||||
throws IllegalArgumentException,
|
||||
IllegalAccessException, InvocationTargetException {
|
||||
Object result = method.invoke(instance, args);
|
||||
interfaceCache.put(new Element(invocation, result));
|
||||
interfaceCache.put(invocation, result);
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return proxy;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Cache createCache(String name, int size) {
|
||||
// Preconditions.checkNotNull(name, "name");
|
||||
// Preconditions.checkArgument(size > 0, "size <= 0");
|
||||
//
|
||||
// Cache cache = new Cache(new CacheConfiguration(name, size)
|
||||
// .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
|
||||
// .overflowToDisk(true).eternal(false).timeToLiveSeconds(60)
|
||||
// .timeToIdleSeconds(30).diskPersistent(false)
|
||||
// .diskExpiryThreadIntervalSeconds(0));
|
||||
// register(cache);
|
||||
// return cache;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Cache createCache(String name) {
|
||||
// Preconditions.checkNotNull(name, "name");
|
||||
// return createCache(name, 200);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void register(Cache cache) {
|
||||
// Preconditions.checkNotNull(cache, "cache");
|
||||
// manager.addCache(cache);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void unregister(Cache cache) {
|
||||
// Preconditions.checkNotNull(cache, "cache");
|
||||
// manager.removeCache(cache.getName());
|
||||
// }
|
||||
|
||||
@Override
|
||||
public Cache createCache(String name, int size) {
|
||||
public <K, V> Cache<K, V> createCache(String name, int size) {
|
||||
Preconditions.checkNotNull(name, "name");
|
||||
Preconditions.checkArgument(size > 0, "size <= 0");
|
||||
|
||||
Cache cache = new Cache(new CacheConfiguration(name, size)
|
||||
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(false).timeToLiveSeconds(60)
|
||||
.timeToIdleSeconds(30).diskPersistent(false)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
register(cache);
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cache createCache(String name) {
|
||||
Preconditions.checkNotNull(name, "name");
|
||||
return createCache(name, 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Cache cache) {
|
||||
Preconditions.checkNotNull(cache, "cache");
|
||||
net.sf.ehcache.Cache cache = new net.sf.ehcache.Cache(
|
||||
new CacheConfiguration(name, size)
|
||||
.memoryStoreEvictionPolicy(
|
||||
MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(false)
|
||||
.timeToLiveSeconds(60).timeToIdleSeconds(30)
|
||||
.diskPersistent(false)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
manager.addCache(cache);
|
||||
return new EhCacheFacade<K, V>(cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister(Cache cache) {
|
||||
Preconditions.checkNotNull(cache, "cache");
|
||||
manager.removeCache(cache.getName());
|
||||
public <K, V> Cache<K, V> createEternalCache(String name, int size) {
|
||||
Preconditions.checkNotNull(name, "name");
|
||||
Preconditions.checkArgument(size > 0, "size <= 0");
|
||||
|
||||
net.sf.ehcache.Cache cache = new net.sf.ehcache.Cache(
|
||||
new CacheConfiguration(name, size)
|
||||
.memoryStoreEvictionPolicy(
|
||||
MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(true)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
manager.addCache(cache);
|
||||
return new EhCacheFacade<K, V>(cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createCache(String name) {
|
||||
net.sf.ehcache.Cache cache = new net.sf.ehcache.Cache(
|
||||
new CacheConfiguration(name, 200)
|
||||
.memoryStoreEvictionPolicy(
|
||||
MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(true)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
manager.addCache(cache);
|
||||
return new EhCacheFacade<K, V>(cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> void dispose(Cache<K, V> cache) {
|
||||
if (cache instanceof EhCacheFacade) {
|
||||
manager.removeCache(((EhCacheFacade<K, V>) cache).cache.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -136,42 +182,40 @@ public class EhCacheService extends AbstractService implements CacheService {
|
||||
interfaceCache = null;
|
||||
}
|
||||
|
||||
private static class MethodInvocation {
|
||||
private final Method method;
|
||||
private final Object[] args;
|
||||
private class EhCacheFacade<K, V> implements Cache<K, V> {
|
||||
private final net.sf.ehcache.Cache cache;
|
||||
|
||||
public MethodInvocation(Method method, Object[] args) {
|
||||
this.method = method;
|
||||
this.args = args;
|
||||
public EhCacheFacade(net.sf.ehcache.Cache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + Arrays.hashCode(args);
|
||||
result = prime * result
|
||||
+ ((method == null) ? 0 : method.hashCode());
|
||||
return result;
|
||||
public void put(K key, V value) {
|
||||
cache.put(new Element(key, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
MethodInvocation other = (MethodInvocation) obj;
|
||||
if (!Arrays.equals(args, other.args))
|
||||
return false;
|
||||
if (method == null) {
|
||||
if (other.method != null)
|
||||
return false;
|
||||
} else if (!method.equals(other.method))
|
||||
return false;
|
||||
return true;
|
||||
@SuppressWarnings("unchecked")
|
||||
public V get(K key) {
|
||||
final Element element = cache.get(key);
|
||||
if (element == null)
|
||||
return null;
|
||||
return (V) element.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(K key) {
|
||||
return cache.get(key) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(K key) {
|
||||
cache.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
cache.removeAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
87
src/main/java/com/l2jserver/service/cache/EternalCache.java
vendored
Normal file
87
src/main/java/com/l2jserver/service/cache/EternalCache.java
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
/**
|
||||
* Cache class for an eternal cache
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <K>
|
||||
* the key type
|
||||
* @param <V>
|
||||
* the value type
|
||||
*/
|
||||
class EternalCache<K, V> implements Cache<K, V> {
|
||||
protected final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* The cache name
|
||||
*/
|
||||
protected final String cacheName;
|
||||
|
||||
/**
|
||||
* Map storing references to cached objects
|
||||
*/
|
||||
protected final Map<K, V> cacheMap = CollectionFactory.newMap();
|
||||
|
||||
/**
|
||||
* @param cacheName
|
||||
* the cache name
|
||||
*/
|
||||
protected EternalCache(String cacheName) {
|
||||
this.cacheName = cacheName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(K key, V value) {
|
||||
cacheMap.put(key, value);
|
||||
log.debug("{}: added for key: {}", cacheName, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(K key) {
|
||||
V obj = cacheMap.get(key);
|
||||
if (obj != null)
|
||||
log.debug("{}: obtained for key: {}", cacheName, key);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(K key) {
|
||||
return cacheMap.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(K key) {
|
||||
cacheMap.remove(key);
|
||||
log.debug("{}: removed for key: {}", cacheName, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
cacheMap.clear();
|
||||
log.debug("{}: cleared", cacheName);
|
||||
}
|
||||
}
|
||||
69
src/main/java/com/l2jserver/service/cache/MethodInvocation.java
vendored
Normal file
69
src/main/java/com/l2jserver/service/cache/MethodInvocation.java
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Simple class used to store method invocations for the proxied cache.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
class MethodInvocation {
|
||||
/**
|
||||
* The invoked method
|
||||
*/
|
||||
private final Method method;
|
||||
/**
|
||||
* The invocation arguments
|
||||
*/
|
||||
private final Object[] args;
|
||||
|
||||
public MethodInvocation(Method method, Object[] args) {
|
||||
this.method = method;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + Arrays.hashCode(args);
|
||||
result = prime * result + ((method == null) ? 0 : method.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
MethodInvocation other = (MethodInvocation) obj;
|
||||
if (!Arrays.equals(args, other.args))
|
||||
return false;
|
||||
if (method == null) {
|
||||
if (other.method != null)
|
||||
return false;
|
||||
} else if (!method.equals(other.method))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
164
src/main/java/com/l2jserver/service/cache/SoftCacheService.java
vendored
Normal file
164
src/main/java/com/l2jserver/service/cache/SoftCacheService.java
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
|
||||
/**
|
||||
* This {@link Cache} service implementation uses a {@link SoftReference} to
|
||||
* store values.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class SoftCacheService extends AbstractService implements CacheService {
|
||||
/**
|
||||
* The interface cache
|
||||
*/
|
||||
private Cache<MethodInvocation, Object> interfaceCache;
|
||||
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
interfaceCache = createCache("interface-cache");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Cacheable> T decorate(final Class<T> interfaceType,
|
||||
final T instance) {
|
||||
Preconditions.checkNotNull(interfaceType, "interfaceType");
|
||||
Preconditions.checkNotNull(instance, "instance");
|
||||
|
||||
if (!interfaceType.isInterface())
|
||||
return null;
|
||||
@SuppressWarnings("unchecked")
|
||||
final T proxy = (T) Proxy.newProxyInstance(this.getClass()
|
||||
.getClassLoader(), new Class[] { interfaceType },
|
||||
new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method,
|
||||
Object[] args) throws Throwable {
|
||||
if (method.isAnnotationPresent(IgnoreCaching.class))
|
||||
return method.invoke(instance, args);
|
||||
final MethodInvocation invocation = new MethodInvocation(
|
||||
method, args);
|
||||
Object result = interfaceCache.get(invocation);
|
||||
if (result == null)
|
||||
return doInvoke(invocation, proxy, method, args);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object doInvoke(MethodInvocation invocation,
|
||||
Object proxy, Method method, Object[] args)
|
||||
throws IllegalArgumentException,
|
||||
IllegalAccessException, InvocationTargetException {
|
||||
Object result = method.invoke(instance, args);
|
||||
interfaceCache.put(invocation, result);
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createCache(String name, int size) {
|
||||
return new SoftCache<K, V>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createEternalCache(String name, int size) {
|
||||
return new EternalCache<K, V>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createCache(String name) {
|
||||
return new SoftCache<K, V>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> void dispose(Cache<K, V> cache) {
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
dispose(interfaceCache);
|
||||
interfaceCache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is a simple map implementation for cache usage.<br>
|
||||
* <br>
|
||||
* Value may be stored in map really long, but it for sure will be removed
|
||||
* if there is low memory (and of course there isn't any strong reference to
|
||||
* value object)
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class SoftCache<K, V> extends AbstractReferenceCache<K, V> implements
|
||||
Cache<K, V> {
|
||||
/**
|
||||
* This class is a {@link SoftReference} with additional responsibility
|
||||
* of holding key object
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
private class SoftEntry extends SoftReference<V> {
|
||||
private K key;
|
||||
|
||||
SoftEntry(K key, V referent, ReferenceQueue<? super V> q) {
|
||||
super(referent, q);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
K getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public SoftCache(String cacheName) {
|
||||
super(cacheName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected synchronized void cleanQueue() {
|
||||
SoftEntry en = null;
|
||||
while ((en = (SoftEntry) refQueue.poll()) != null) {
|
||||
K key = en.getKey();
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("{} : cleaned up {} for key: {}", cacheName, key);
|
||||
cacheMap.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Reference<V> newReference(K key, V value,
|
||||
ReferenceQueue<V> vReferenceQueue) {
|
||||
return new SoftEntry(key, value, vReferenceQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
164
src/main/java/com/l2jserver/service/cache/WeakCacheService.java
vendored
Normal file
164
src/main/java/com/l2jserver/service/cache/WeakCacheService.java
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* This file is part of l2jserver <l2jserver.com>.
|
||||
*
|
||||
* l2jserver is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* l2jserver is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
|
||||
/**
|
||||
* This {@link Cache} service implementation uses a {@link SoftReference} to
|
||||
* store values.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class WeakCacheService extends AbstractService implements CacheService {
|
||||
/**
|
||||
* The interface cache
|
||||
*/
|
||||
private Cache<MethodInvocation, Object> interfaceCache;
|
||||
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
interfaceCache = createCache("interface-cache");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Cacheable> T decorate(final Class<T> interfaceType,
|
||||
final T instance) {
|
||||
Preconditions.checkNotNull(interfaceType, "interfaceType");
|
||||
Preconditions.checkNotNull(instance, "instance");
|
||||
|
||||
if (!interfaceType.isInterface())
|
||||
return null;
|
||||
@SuppressWarnings("unchecked")
|
||||
final T proxy = (T) Proxy.newProxyInstance(this.getClass()
|
||||
.getClassLoader(), new Class[] { interfaceType },
|
||||
new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method,
|
||||
Object[] args) throws Throwable {
|
||||
if (method.isAnnotationPresent(IgnoreCaching.class))
|
||||
return method.invoke(instance, args);
|
||||
final MethodInvocation invocation = new MethodInvocation(
|
||||
method, args);
|
||||
Object result = interfaceCache.get(invocation);
|
||||
if (result == null)
|
||||
return doInvoke(invocation, proxy, method, args);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object doInvoke(MethodInvocation invocation,
|
||||
Object proxy, Method method, Object[] args)
|
||||
throws IllegalArgumentException,
|
||||
IllegalAccessException, InvocationTargetException {
|
||||
Object result = method.invoke(instance, args);
|
||||
interfaceCache.put(invocation, result);
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createCache(String name, int size) {
|
||||
return new WeakCache<K, V>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createEternalCache(String name, int size) {
|
||||
return new EternalCache<K, V>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> Cache<K, V> createCache(String name) {
|
||||
return new WeakCache<K, V>(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <K, V> void dispose(Cache<K, V> cache) {
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
dispose(interfaceCache);
|
||||
interfaceCache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is a simple map implementation for cache usage.<br>
|
||||
* <br>
|
||||
* Values from the map will be removed after the first garbage collector run
|
||||
* if there isn't any strong reference to the value object.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
private class WeakCache<K, V> extends AbstractReferenceCache<K, V>
|
||||
implements Cache<K, V> {
|
||||
/**
|
||||
* This class is a {@link WeakReference} with additional responsibility
|
||||
* of holding key object
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
private class Entry extends WeakReference<V> {
|
||||
private K key;
|
||||
|
||||
Entry(K key, V referent, ReferenceQueue<? super V> q) {
|
||||
super(referent, q);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
K getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
WeakCache(String cacheName) {
|
||||
super(cacheName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected synchronized void cleanQueue() {
|
||||
Entry en = null;
|
||||
while ((en = (Entry) refQueue.poll()) != null) {
|
||||
K key = en.getKey();
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("{}: cleaned up for key: {}", cacheName, key);
|
||||
cacheMap.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Reference<V> newReference(K key, V value,
|
||||
ReferenceQueue<V> vReferenceQueue) {
|
||||
return new Entry(key, value, vReferenceQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,11 +28,6 @@ import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.Element;
|
||||
import net.sf.ehcache.config.CacheConfiguration;
|
||||
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
|
||||
|
||||
import org.apache.commons.dbcp.ConnectionFactory;
|
||||
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
|
||||
import org.apache.commons.dbcp.PoolableConnectionFactory;
|
||||
@@ -53,6 +48,7 @@ import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.AbstractService.Depends;
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
import com.l2jserver.service.cache.Cache;
|
||||
import com.l2jserver.service.cache.CacheService;
|
||||
import com.l2jserver.service.configuration.ConfigurationService;
|
||||
import com.l2jserver.service.core.LoggingService;
|
||||
@@ -105,7 +101,7 @@ public class JDBCDatabaseService extends AbstractService implements
|
||||
/**
|
||||
* An cache object
|
||||
*/
|
||||
private Cache objectCache;
|
||||
private Cache<Object, Object> objectCache;
|
||||
|
||||
@Inject
|
||||
public JDBCDatabaseService(ConfigurationService configService,
|
||||
@@ -125,12 +121,8 @@ public class JDBCDatabaseService extends AbstractService implements
|
||||
|
||||
// cache must be large enough for all world objects, to avoid
|
||||
// duplication... this would endanger non-persistent states
|
||||
objectCache = new Cache(new CacheConfiguration("database-service",
|
||||
IDAllocator.ALLOCABLE_IDS)
|
||||
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(true).diskPersistent(false)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
cacheService.register(objectCache);
|
||||
objectCache = cacheService.createEternalCache("database-service",
|
||||
IDAllocator.ALLOCABLE_IDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -186,21 +178,18 @@ public class JDBCDatabaseService extends AbstractService implements
|
||||
|
||||
public Object getCachedObject(Object id) {
|
||||
Preconditions.checkNotNull(id, "id");
|
||||
final Element element = objectCache.get(id);
|
||||
if (element == null)
|
||||
return null;
|
||||
return element.getObjectValue();
|
||||
return objectCache.get(id);
|
||||
}
|
||||
|
||||
public boolean hasCachedObject(Object id) {
|
||||
Preconditions.checkNotNull(id, "id");
|
||||
return objectCache.get(id) != null;
|
||||
return objectCache.contains(id);
|
||||
}
|
||||
|
||||
public void updateCache(Object key, Object value) {
|
||||
Preconditions.checkNotNull(key, "key");
|
||||
Preconditions.checkNotNull(value, "value");
|
||||
objectCache.put(new Element(key, value));
|
||||
objectCache.put(key, value);
|
||||
}
|
||||
|
||||
public void removeCache(Object key) {
|
||||
@@ -210,8 +199,7 @@ public class JDBCDatabaseService extends AbstractService implements
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
if (objectCache != null)
|
||||
objectCache.dispose();
|
||||
cacheService.dispose(objectCache);
|
||||
objectCache = null;
|
||||
|
||||
try {
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.l2jserver.service.game.ai;
|
||||
|
||||
import com.l2jserver.model.world.Actor;
|
||||
import com.l2jserver.service.Service;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
|
||||
/**
|
||||
* This service executes AI operations
|
||||
|
||||
@@ -27,7 +27,7 @@ import com.l2jserver.service.game.template.TemplateService;
|
||||
import com.l2jserver.service.game.world.WorldService;
|
||||
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
||||
import com.l2jserver.service.network.NetworkService;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link AIService}.
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.l2jserver.service.game.ai.script;
|
||||
|
||||
import com.l2jserver.model.world.PositionableObject;
|
||||
import com.l2jserver.service.game.ai.AIScript;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a
|
||||
|
||||
@@ -23,8 +23,8 @@ import com.l2jserver.service.game.npc.NotAttackableNPCServiceException;
|
||||
import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException;
|
||||
import com.l2jserver.service.game.spawn.NotSpawnedServiceException;
|
||||
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* This service manages {@link L2Character} instances
|
||||
@@ -132,7 +132,7 @@ public interface CharacterService extends Service {
|
||||
* @param point
|
||||
* the validated point
|
||||
*/
|
||||
void validate(L2Character character, Point point);
|
||||
void validate(L2Character character, Point3D point);
|
||||
|
||||
/**
|
||||
* Called when received the validation of the position of an character
|
||||
@@ -142,7 +142,7 @@ public interface CharacterService extends Service {
|
||||
* @param point
|
||||
* the validated point
|
||||
*/
|
||||
void receivedValidation(L2Character character, Point point);
|
||||
void receivedValidation(L2Character character, Point3D point);
|
||||
|
||||
/**
|
||||
* Set the character to walking mode
|
||||
|
||||
@@ -74,8 +74,8 @@ import com.l2jserver.service.game.world.filter.impl.IDFilter;
|
||||
import com.l2jserver.service.game.world.filter.impl.KnownListFilter;
|
||||
import com.l2jserver.service.game.world.filter.impl.KnownListUpdateFilter;
|
||||
import com.l2jserver.service.network.NetworkService;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link CharacterService}.
|
||||
@@ -417,21 +417,21 @@ public class CharacterServiceImpl extends AbstractService implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(L2Character character, Point point) {
|
||||
public void validate(L2Character character, Point3D point) {
|
||||
Preconditions.checkNotNull(character, "character");
|
||||
Preconditions.checkNotNull(point, "point");
|
||||
// TODO implement position validation
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receivedValidation(L2Character character, Point point) {
|
||||
public void receivedValidation(L2Character character, Point3D point) {
|
||||
Preconditions.checkNotNull(character, "character");
|
||||
Preconditions.checkNotNull(point, "point");
|
||||
if (character.isTeleporting())
|
||||
// ignore while teleporting, for some reason the client sends a
|
||||
// validation just before teleport packet
|
||||
return;
|
||||
final Point old = character.getPoint();
|
||||
final Point3D old = character.getPoint();
|
||||
character.setPoint(point);
|
||||
eventDispatcher.dispatch(new CharacterMoveEvent(character, old));
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ import com.l2jserver.service.game.character.CharacterService;
|
||||
import com.l2jserver.service.game.world.WorldService;
|
||||
import com.l2jserver.service.game.world.event.TypedWorldListener;
|
||||
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* <h1>This implementation does not validate pathing!</h1>
|
||||
@@ -97,7 +97,7 @@ public class MapperPathingService extends AbstractService implements
|
||||
CharacterMoveEvent.class) {
|
||||
@Override
|
||||
protected boolean dispatch(CharacterMoveEvent e) {
|
||||
final Point point = e.getPoint();
|
||||
final Point3D point = e.getPoint();
|
||||
final CoordinateStruct struct = CoordinateStruct
|
||||
.fromCoordinate(point.getCoordinate());
|
||||
try {
|
||||
|
||||
@@ -24,8 +24,8 @@ import com.l2jserver.model.world.event.SpawnEvent;
|
||||
import com.l2jserver.model.world.player.event.PlayerTeleportedEvent;
|
||||
import com.l2jserver.model.world.player.event.PlayerTeleportingEvent;
|
||||
import com.l2jserver.service.Service;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* This service is responsible for spawning monsters, npcs and players.
|
||||
@@ -50,7 +50,7 @@ public interface SpawnService extends Service {
|
||||
* @throws AlreadySpawnedServiceException
|
||||
* if the object is already spawned in the world
|
||||
*/
|
||||
void spawn(PositionableObject object, Point point)
|
||||
void spawn(PositionableObject object, Point3D point)
|
||||
throws SpawnPointNotFoundServiceException,
|
||||
AlreadySpawnedServiceException;
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ import com.l2jserver.service.AbstractService.Depends;
|
||||
import com.l2jserver.service.game.world.WorldService;
|
||||
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
|
||||
import com.l2jserver.service.network.NetworkService;
|
||||
import com.l2jserver.util.dimensional.Coordinate;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Coordinate;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Default implementation for {@link SpawnService}
|
||||
@@ -69,7 +69,7 @@ public class SpawnServiceImpl extends AbstractService implements SpawnService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn(PositionableObject object, Point point)
|
||||
public void spawn(PositionableObject object, Point3D point)
|
||||
throws SpawnPointNotFoundServiceException {
|
||||
Preconditions.checkNotNull(object, "object");
|
||||
// sanitize
|
||||
|
||||
@@ -96,11 +96,6 @@ public class ScriptTemplateService extends AbstractService implements
|
||||
// TODO templates.remove(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
context.reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
if (context.isInitialized())
|
||||
|
||||
@@ -31,9 +31,4 @@ public interface TemplateService extends Service {
|
||||
* @return the template
|
||||
*/
|
||||
<T extends Template<?>> T getTemplate(TemplateID<T, ?> id);
|
||||
|
||||
/**
|
||||
* Reload the template list.
|
||||
*/
|
||||
void reload();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.l2jserver.service.game.template;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
@@ -46,22 +45,25 @@ import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.AbstractService.Depends;
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
import com.l2jserver.service.cache.Cache;
|
||||
import com.l2jserver.service.cache.CacheService;
|
||||
import com.l2jserver.service.configuration.ConfigurationService;
|
||||
import com.l2jserver.service.core.LoggingService;
|
||||
import com.l2jserver.service.core.vfs.VFSService;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
import com.l2jserver.util.jaxb.CharacterTemplateIDAdapter;
|
||||
import com.l2jserver.util.jaxb.ItemTemplateIDAdapter;
|
||||
import com.l2jserver.util.jaxb.NPCTemplateIDAdapter;
|
||||
import com.l2jserver.util.jaxb.TeleportationTemplateIDAdapter;
|
||||
import com.l2jserver.util.vfs.ExtensionFileSelector;
|
||||
|
||||
@Depends({ LoggingService.class, VFSService.class, ConfigurationService.class })
|
||||
@Depends({ LoggingService.class, VFSService.class, CacheService.class,
|
||||
ConfigurationService.class })
|
||||
public class XMLTemplateService extends AbstractService implements
|
||||
TemplateService {
|
||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final VFSService vfsService;
|
||||
private final CacheService cacheService;
|
||||
|
||||
private final XMLTemplateServiceConfiguration config;
|
||||
private final NPCTemplateIDAdapter npcTemplateIdAdapter;
|
||||
@@ -73,16 +75,17 @@ public class XMLTemplateService extends AbstractService implements
|
||||
private Unmarshaller unmarshaller;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Map<TemplateID, Template> templates = CollectionFactory.newMap();
|
||||
private Cache<TemplateID, Template> templates;
|
||||
|
||||
@Inject
|
||||
public XMLTemplateService(final VFSService vfsService,
|
||||
ConfigurationService configService,
|
||||
CacheService cacheService, ConfigurationService configService,
|
||||
NPCTemplateIDAdapter npcTemplateIdAdapter,
|
||||
ItemTemplateIDAdapter itemTemplateIdAdapter,
|
||||
CharacterTemplateIDAdapter charIdTemplateAdapter,
|
||||
TeleportationTemplateIDAdapter teleportationIdTemplateAdapter) {
|
||||
this.vfsService = vfsService;
|
||||
this.cacheService = cacheService;
|
||||
this.config = configService.get(XMLTemplateServiceConfiguration.class);
|
||||
this.npcTemplateIdAdapter = npcTemplateIdAdapter;
|
||||
this.itemTemplateIdAdapter = itemTemplateIdAdapter;
|
||||
@@ -92,6 +95,7 @@ public class XMLTemplateService extends AbstractService implements
|
||||
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
templates = cacheService.createEternalCache("templates", 100 * 1000);
|
||||
try {
|
||||
log.debug("Creating JAXBContext instance");
|
||||
context = JAXBContext.newInstance(CharacterTemplate.class,
|
||||
@@ -112,9 +116,9 @@ public class XMLTemplateService extends AbstractService implements
|
||||
|
||||
final FileObject root = vfsService.resolve(config
|
||||
.getTemplateDirectory());
|
||||
|
||||
|
||||
log.info("Scanning {} for XML templates", root);
|
||||
|
||||
|
||||
FileObject[] files = root.findFiles(ExtensionFileSelector
|
||||
.ext("xml"));
|
||||
|
||||
@@ -167,15 +171,10 @@ public class XMLTemplateService extends AbstractService implements
|
||||
templates.remove(template.getID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
templates.clear();
|
||||
cacheService.dispose(templates);
|
||||
templates = null;
|
||||
unmarshaller = null;
|
||||
context = null;
|
||||
}
|
||||
|
||||
@@ -18,11 +18,6 @@ package com.l2jserver.service.game.world;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.Element;
|
||||
import net.sf.ehcache.config.CacheConfiguration;
|
||||
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.CharacterDAO;
|
||||
@@ -35,6 +30,7 @@ import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.AbstractService.Depends;
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
import com.l2jserver.service.cache.Cache;
|
||||
import com.l2jserver.service.cache.CacheService;
|
||||
import com.l2jserver.service.database.DatabaseService;
|
||||
|
||||
@@ -73,7 +69,7 @@ public class CachedWorldIDService extends AbstractService implements
|
||||
/**
|
||||
* The ID cache
|
||||
*/
|
||||
private Cache cache;
|
||||
private Cache<Integer, ObjectID<?>> cache;
|
||||
|
||||
/**
|
||||
* The loaded state
|
||||
@@ -94,12 +90,8 @@ public class CachedWorldIDService extends AbstractService implements
|
||||
@Override
|
||||
protected void doStart() throws ServiceStartException {
|
||||
// we allocate an cache which can fit all ids
|
||||
cache = new Cache(new CacheConfiguration("id-cache",
|
||||
IDAllocator.ALLOCABLE_IDS)
|
||||
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
|
||||
.overflowToDisk(true).eternal(true).diskPersistent(false)
|
||||
.diskExpiryThreadIntervalSeconds(0));
|
||||
cacheService.register(cache);
|
||||
cache = cacheService.createEternalCache("id-cache",
|
||||
IDAllocator.ALLOCABLE_IDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,7 +104,7 @@ public class CachedWorldIDService extends AbstractService implements
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
cache.removeAll();
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,17 +129,13 @@ public class CachedWorldIDService extends AbstractService implements
|
||||
// ignore resolving before all IDs are loaded
|
||||
return null;
|
||||
}
|
||||
|
||||
final Element element = cache.get(id);
|
||||
if (element == null)
|
||||
return null;
|
||||
return (I) element.getObjectValue();
|
||||
return (I) cache.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <I extends ObjectID<?>> void add(I id) {
|
||||
Preconditions.checkNotNull(id, "id");
|
||||
cache.put(new Element(id.getID(), id));
|
||||
cache.put(id.getID(), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,7 +146,7 @@ public class CachedWorldIDService extends AbstractService implements
|
||||
|
||||
@Override
|
||||
protected void doStop() throws ServiceStopException {
|
||||
cacheService.unregister(cache);
|
||||
cacheService.dispose(cache);
|
||||
cache = null;
|
||||
allocator.clear();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.l2jserver.model.world.PositionableObject;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.service.game.world.filter.AndFilter;
|
||||
import com.l2jserver.service.game.world.filter.NotFilter;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* This filter will only accept {@link WorldObject} which are in vision of
|
||||
@@ -32,7 +32,7 @@ public class KnownListUpdateFilter extends AndFilter<PositionableObject> {
|
||||
public static final int KNOWNLIST_RANGE = 2000;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KnownListUpdateFilter(PositionableObject object, Point old) {
|
||||
public KnownListUpdateFilter(PositionableObject object, Point3D old) {
|
||||
super(new KnownListFilter(object), new NotFilter<PositionableObject>(
|
||||
new RangePointFilter(old, KNOWNLIST_RANGE)));
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package com.l2jserver.service.game.world.filter.impl;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.l2jserver.model.world.PositionableObject;
|
||||
import com.l2jserver.service.game.world.filter.WorldObjectFilter;
|
||||
import com.l2jserver.util.dimensional.Point;
|
||||
import com.l2jserver.util.geometry.Point3D;
|
||||
|
||||
/**
|
||||
* Filter objects that are in the <tt>range</tt> of <tt>coordinate</tt>
|
||||
@@ -30,7 +30,7 @@ public class RangePointFilter implements WorldObjectFilter<PositionableObject> {
|
||||
/**
|
||||
* The coordinate point
|
||||
*/
|
||||
private final Point point;
|
||||
private final Point3D point;
|
||||
/**
|
||||
* The desired maximum distance of the object
|
||||
*/
|
||||
@@ -44,7 +44,7 @@ public class RangePointFilter implements WorldObjectFilter<PositionableObject> {
|
||||
* @param range
|
||||
* the desired maximum distance of the object
|
||||
*/
|
||||
public RangePointFilter(final Point point, final int range) {
|
||||
public RangePointFilter(final Point3D point, final int range) {
|
||||
Preconditions.checkNotNull(point, "point");
|
||||
Preconditions.checkState(range >= 0, "range < 0");
|
||||
this.point = point;
|
||||
|
||||
Reference in New Issue
Block a user