mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-06 07:32:46 +00:00
Move model and ID abstract classes to l2jserver2-common
This commit is contained in:
@@ -178,6 +178,12 @@
|
||||
<artifactId>htmlparser</artifactId>
|
||||
<version>2.1</version>
|
||||
<type>jar</type>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.sun</groupId>
|
||||
<artifactId>tools</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
|
||||
@@ -21,7 +21,9 @@ import static org.jboss.netty.channel.Channels.pipeline;
|
||||
import org.jboss.netty.channel.ChannelPipeline;
|
||||
import org.jboss.netty.channel.ChannelPipelineFactory;
|
||||
import org.jboss.netty.handler.logging.LoggingHandler;
|
||||
import org.jboss.netty.handler.timeout.IdleStateHandler;
|
||||
import org.jboss.netty.logging.InternalLogLevel;
|
||||
import org.jboss.netty.util.HashedWheelTimer;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
@@ -33,6 +35,7 @@ import com.l2jserver.game.net.codec.Lineage2FrameEncoder;
|
||||
import com.l2jserver.game.net.codec.Lineage2PacketReader;
|
||||
import com.l2jserver.game.net.codec.Lineage2PacketWriter;
|
||||
import com.l2jserver.game.net.handler.Lineage2PacketHandler;
|
||||
import com.l2jserver.game.net.handler.Lineage2TimeoutHandler;
|
||||
import com.l2jserver.service.game.world.WorldService;
|
||||
import com.l2jserver.service.network.NettyNetworkService;
|
||||
import com.l2jserver.service.network.NetworkService;
|
||||
@@ -79,6 +82,9 @@ public class Lineage2PipelineFactory implements ChannelPipelineFactory {
|
||||
public ChannelPipeline getPipeline() throws Exception {
|
||||
final ChannelPipeline pipeline = pipeline();
|
||||
|
||||
pipeline.addLast("timeout.tiner", new IdleStateHandler(
|
||||
new HashedWheelTimer(), 30, 30, 0));
|
||||
|
||||
pipeline.addLast("frame.encoder", new Lineage2FrameEncoder());
|
||||
pipeline.addLast("frame.decoder", new Lineage2FrameDecoder());
|
||||
|
||||
@@ -95,8 +101,10 @@ public class Lineage2PipelineFactory implements ChannelPipelineFactory {
|
||||
pipeline.addLast("logger", new LoggingHandler(InternalLogLevel.DEBUG,
|
||||
true));
|
||||
|
||||
final Lineage2TimeoutHandler timeoutHandler = new Lineage2TimeoutHandler();
|
||||
pipeline.addLast("packet.handler", new Lineage2PacketHandler(
|
||||
nettyNetworkService, worldService));
|
||||
nettyNetworkService, worldService, timeoutHandler));
|
||||
pipeline.addLast("timeout.handler", timeoutHandler);
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,10 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
|
||||
* The {@link WorldService} instance
|
||||
*/
|
||||
private final WorldService worldService;
|
||||
/**
|
||||
* The timeout handler is responsible for disconnecting idle clients.
|
||||
*/
|
||||
private final Lineage2TimeoutHandler timeoutHandler;
|
||||
/**
|
||||
* The Lineage 2 connection
|
||||
*/
|
||||
@@ -60,11 +64,14 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
|
||||
* the netty network service
|
||||
* @param worldService
|
||||
* the world service
|
||||
* @param timeoutHandler
|
||||
* the timeout handler
|
||||
*/
|
||||
public Lineage2PacketHandler(NettyNetworkService nettyNetworkService,
|
||||
WorldService worldService) {
|
||||
WorldService worldService, Lineage2TimeoutHandler timeoutHandler) {
|
||||
this.nettyNetworkService = nettyNetworkService;
|
||||
this.worldService = worldService;
|
||||
this.timeoutHandler = timeoutHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,6 +80,7 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
|
||||
connection = new Lineage2Client(worldService, nettyNetworkService,
|
||||
e.getChannel());
|
||||
connection.getPacketWriter().setConnection(connection);
|
||||
timeoutHandler.setConnection(connection);
|
||||
|
||||
nettyNetworkService.register(connection);
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||
*
|
||||
* l2jserver2 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.
|
||||
*
|
||||
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.game.net.handler;
|
||||
|
||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||
import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
|
||||
import org.jboss.netty.handler.timeout.IdleStateEvent;
|
||||
|
||||
import com.l2jserver.game.net.Lineage2Client;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public class Lineage2TimeoutHandler extends IdleStateAwareChannelHandler {
|
||||
/**
|
||||
* The Lineage 2 connection
|
||||
*/
|
||||
private Lineage2Client connection;
|
||||
|
||||
@Override
|
||||
public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e)
|
||||
throws Exception {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
super.channelIdle(ctx, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the connection
|
||||
*/
|
||||
protected Lineage2Client getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param connection
|
||||
* the connection to set
|
||||
*/
|
||||
protected void setConnection(Lineage2Client connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||
*
|
||||
* l2jserver2 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.
|
||||
*
|
||||
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.model;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.l2jserver.model.id.ID;
|
||||
|
||||
/**
|
||||
* Simple model interface implementing {@link ID} related methods
|
||||
*
|
||||
* @param <T>
|
||||
* the ID type used to represent this {@link Model}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public abstract class AbstractModel<T extends ID<?>> implements Model<T> {
|
||||
/**
|
||||
* The object id
|
||||
*/
|
||||
protected T id;
|
||||
/**
|
||||
* The database object state
|
||||
*/
|
||||
protected transient ObjectDesire desire = ObjectDesire.INSERT;
|
||||
|
||||
@Override
|
||||
public T getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setID(T ID) {
|
||||
Preconditions.checkState(id == null, "ID is already set");
|
||||
desireInsert();
|
||||
this.id = ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectDesire getObjectDesire() {
|
||||
return desire;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObjectDesire(ObjectDesire desire) {
|
||||
if (desire == null)
|
||||
desire = ObjectDesire.NONE;
|
||||
this.desire = desire;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this object desire to {@link ObjectDesire#UPDATE}. If the desire is
|
||||
* {@link ObjectDesire#INSERT} or {@link ObjectDesire#DELETE} the desire
|
||||
* will not be changed.
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
protected void desireUpdate() {
|
||||
if (this.desire != ObjectDesire.INSERT
|
||||
&& this.desire != ObjectDesire.DELETE)
|
||||
this.desire = ObjectDesire.UPDATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this object desire to {@link ObjectDesire#INSERT}. If the desire is
|
||||
* {@link ObjectDesire#DELETE} the desire will not be changed.
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
protected void desireInsert() {
|
||||
if (this.desire != ObjectDesire.DELETE)
|
||||
this.desire = ObjectDesire.INSERT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((id == null) ? 0 : id.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;
|
||||
AbstractModel<?> other = (AbstractModel<?>) obj;
|
||||
if (id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!id.equals(other.id))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||
*
|
||||
* l2jserver2 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.
|
||||
*
|
||||
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.model;
|
||||
|
||||
import com.l2jserver.model.id.ID;
|
||||
import com.l2jserver.service.database.DatabaseService;
|
||||
|
||||
/**
|
||||
* Base model. Each object model must implement this interface to be able to be
|
||||
* inserted into the database.
|
||||
*
|
||||
* @param <T>
|
||||
* the {@link ID} type used to represent this {@link Model}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface Model<T extends ID<?>> {
|
||||
/**
|
||||
* @return the object ID
|
||||
*/
|
||||
T getID();
|
||||
|
||||
/**
|
||||
* Please note that the ID can only be set one time. Once it has been set,
|
||||
* it cannot be changed and a {@link IllegalStateException} will be thrown
|
||||
* if trying to change the ID.
|
||||
*
|
||||
* @param ID
|
||||
* the object ID to set
|
||||
* @throws IllegalStateException
|
||||
* if the ID was already set
|
||||
*/
|
||||
void setID(T ID) throws IllegalStateException;
|
||||
|
||||
/**
|
||||
* Each object has an desire. Desires express what the
|
||||
* {@link DatabaseService} should do with the object. The service
|
||||
* automatically keep tracks of every database object (and release them when
|
||||
* they are garbage collected).
|
||||
*
|
||||
* @return the database object desire
|
||||
*/
|
||||
ObjectDesire getObjectDesire();
|
||||
|
||||
/**
|
||||
* Each object has an desire. Desires express what the
|
||||
* {@link DatabaseService} should do with the object. The service
|
||||
* automatically keep tracks of every database object (and release them when
|
||||
* they are garbage collected).
|
||||
*
|
||||
* @param desire
|
||||
* the database object desire to set
|
||||
*/
|
||||
void setObjectDesire(ObjectDesire desire);
|
||||
|
||||
/**
|
||||
* Indicated what the object wants to do in the database. It indicates
|
||||
* whether the object should be inserted, updated or deleted from the
|
||||
* database.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum ObjectDesire {
|
||||
/**
|
||||
* Don't do anything
|
||||
*/
|
||||
NONE,
|
||||
/**
|
||||
* Insert a new object into database.
|
||||
* <p>
|
||||
* If the primary key is auto generated by the database a clone of this
|
||||
* object will be created.<br>
|
||||
* If the primary key is <b>not</b> auto generated by the database, an
|
||||
* database exception will occur.
|
||||
*/
|
||||
INSERT,
|
||||
/**
|
||||
* Updates the object in the database.
|
||||
* <p>
|
||||
* If the object is not in the database nothing will happen.
|
||||
*/
|
||||
UPDATE,
|
||||
/**
|
||||
* Deletes the object from the database.
|
||||
* <p>
|
||||
* If tge object is not in the database nothing will happen.
|
||||
*/
|
||||
DELETE;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||
*
|
||||
* l2jserver2 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.
|
||||
*
|
||||
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.model.id;
|
||||
|
||||
import com.l2jserver.model.Model;
|
||||
|
||||
/**
|
||||
* This is an abstract ID for most model objects that do not extend
|
||||
* {@link ObjectID}.
|
||||
*
|
||||
* @param <T>
|
||||
* the raw id type
|
||||
* @param <O>
|
||||
* the model this {@link ID} provides
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public abstract class AbstractModelID<T, O extends Model<? extends ID<T>>>
|
||||
extends ID<T> {
|
||||
/**
|
||||
* @param id
|
||||
* the id
|
||||
*/
|
||||
protected AbstractModelID(T id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link Model} object associated with this
|
||||
* {@link AbstractModelID}. <tt>null</tt> if {@link Model} does not
|
||||
* exists.
|
||||
*/
|
||||
public abstract O getObject();
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||
*
|
||||
* l2jserver2 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.
|
||||
*
|
||||
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.model.id;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* The ID interface. Each object must be represented by an unique ID.
|
||||
*
|
||||
* @param <T>
|
||||
* the raw id type
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public abstract class ID<T> {
|
||||
/**
|
||||
* The id itself
|
||||
*/
|
||||
protected final T id;
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* the raw id
|
||||
*/
|
||||
@Inject
|
||||
protected ID(T id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public T getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + " [id=" + id + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + id.hashCode() + this.getClass().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;
|
||||
@SuppressWarnings("rawtypes")
|
||||
ID other = (ID) obj;
|
||||
if (id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!id.equals(other.id))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||
*
|
||||
* l2jserver2 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.
|
||||
*
|
||||
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.model.id.compound;
|
||||
|
||||
import com.l2jserver.model.id.ID;
|
||||
|
||||
/**
|
||||
* The compound {@link ID} is composed of two IDs.
|
||||
*
|
||||
* @param <T1>
|
||||
* the first {@link ID} type
|
||||
* @param <T2>
|
||||
* the second {@link ID} type
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class AbstractCompoundID<T1, T2> extends ID<AbstractCompoundID<T1, T2>> {
|
||||
/**
|
||||
* The first ID
|
||||
*/
|
||||
private final T1 id1;
|
||||
/**
|
||||
* The second ID
|
||||
*/
|
||||
private final T2 id2;
|
||||
|
||||
/**
|
||||
* Creates a new compound ID
|
||||
*
|
||||
* @param id1
|
||||
* the first id
|
||||
* @param id2
|
||||
* the second id
|
||||
*/
|
||||
protected AbstractCompoundID(T1 id1, T2 id2) {
|
||||
super(null);
|
||||
this.id1 = id1;
|
||||
this.id2 = id2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the first id
|
||||
*/
|
||||
public T1 getID1() {
|
||||
return id1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the second id
|
||||
*/
|
||||
public T2 getID2() {
|
||||
return id2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractCompoundID<T1, T2> getID() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||
*
|
||||
* l2jserver2 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.
|
||||
*
|
||||
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.model.id.object.allocator;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.l2jserver.util.PrimeFinder;
|
||||
|
||||
/**
|
||||
* The {@link BitSet} id allocator allocates new IDs backed by an {@link BitSet}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class BitSetIDAllocator implements IDAllocator {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(BitSetIDAllocator.class);
|
||||
|
||||
/**
|
||||
* Lock to guarantee synchronization
|
||||
*/
|
||||
private Lock lock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* Available IDs
|
||||
*/
|
||||
private BitSet ids = new BitSet();
|
||||
/**
|
||||
* Amount of free ids
|
||||
*/
|
||||
private AtomicInteger freeIdCount = new AtomicInteger();
|
||||
/**
|
||||
* Next free ID
|
||||
*/
|
||||
private AtomicInteger nextId = new AtomicInteger();
|
||||
|
||||
/**
|
||||
* Initializes this allocator
|
||||
*/
|
||||
public void init() {
|
||||
ids = new BitSet(PrimeFinder.nextPrime(100000));
|
||||
ids.clear();
|
||||
freeIdCount = new AtomicInteger(ALLOCABLE_IDS);
|
||||
|
||||
nextId = new AtomicInteger(ids.nextClearBit(0));
|
||||
log.info("BitSet IDAllocator initialized. Next available ID is {}",
|
||||
nextId.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void allocate(int id) {
|
||||
if (ids.get(id - FIRST_ID))
|
||||
throw new IDAllocatorException("ID not allocated");
|
||||
log.debug("Allocating ID {}", id);
|
||||
lock.lock();
|
||||
try {
|
||||
if (id < FIRST_ID)
|
||||
return;
|
||||
ids.set(id - FIRST_ID);
|
||||
nextId = new AtomicInteger(ids.nextClearBit(0));
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int allocate() {
|
||||
lock.lock();
|
||||
try {
|
||||
final int newID = nextId.get();
|
||||
ids.set(newID);
|
||||
freeIdCount.decrementAndGet();
|
||||
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("Allocated a new ID {}", newID + FIRST_ID);
|
||||
|
||||
int nextFree = ids.nextClearBit(newID);
|
||||
|
||||
if (nextFree < 0) {
|
||||
nextFree = ids.nextClearBit(0);
|
||||
}
|
||||
if (nextFree < 0) {
|
||||
if (ids.size() < ALLOCABLE_IDS) {
|
||||
increaseBitSetCapacity();
|
||||
} else {
|
||||
log.error("ID exhaustion");
|
||||
throw new IDAllocatorException("ID exhaustion");
|
||||
}
|
||||
}
|
||||
|
||||
nextId.set(nextFree);
|
||||
return newID + FIRST_ID;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(int id) {
|
||||
if (id < FIRST_ID)
|
||||
throw new IDAllocatorException(
|
||||
"Can't release ID, smaller then initial ID");
|
||||
if (!ids.get(id - FIRST_ID))
|
||||
throw new IDAllocatorException("ID not allocated");
|
||||
|
||||
log.debug("Releasing allocated ID {}", id);
|
||||
lock.lock();
|
||||
try {
|
||||
ids.clear(id - FIRST_ID);
|
||||
freeIdCount.incrementAndGet();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
ids.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases the {@link BitSet} capacity
|
||||
*/
|
||||
private void increaseBitSetCapacity() {
|
||||
log.debug("Increasing BitSet capacity from {}", ids.size());
|
||||
BitSet newBitSet = new BitSet(
|
||||
PrimeFinder.nextPrime((getAllocatedIDs() * 11) / 10));
|
||||
newBitSet.or(ids);
|
||||
ids = newBitSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAllocatedIDs() {
|
||||
return ALLOCABLE_IDS - getFreeIDs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFreeIDs() {
|
||||
return freeIdCount.get();
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||
*
|
||||
* l2jserver2 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.
|
||||
*
|
||||
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.model.id.object.allocator;
|
||||
|
||||
/**
|
||||
* The ID allocator is used to alloc new ID and to release IDs that aren't used
|
||||
* anymore.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface IDAllocator {
|
||||
/**
|
||||
* The first ID ever allocated
|
||||
*/
|
||||
public final static int FIRST_ID = 0x10000000;
|
||||
/**
|
||||
* The last ID ever allocated
|
||||
*/
|
||||
public final static int LAST_ID = 0x7FFFFFFF;
|
||||
/**
|
||||
* Total of available IDs for allocation
|
||||
*/
|
||||
public final static int ALLOCABLE_IDS = LAST_ID - FIRST_ID;
|
||||
|
||||
/**
|
||||
* This is method is used to register IDs as used at startup time.
|
||||
*
|
||||
* @param id
|
||||
* the id
|
||||
*/
|
||||
void allocate(int id);
|
||||
|
||||
/**
|
||||
* Allocates a new ID
|
||||
*
|
||||
* @return the allocated ID value
|
||||
*/
|
||||
int allocate();
|
||||
|
||||
/**
|
||||
* Release an ID
|
||||
*
|
||||
* @param id
|
||||
* the id
|
||||
*/
|
||||
void release(int id);
|
||||
|
||||
/**
|
||||
* Release all allocated IDs
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Get the amount of already allocated IDs
|
||||
*
|
||||
* @return allocated ids count
|
||||
*/
|
||||
int getAllocatedIDs();
|
||||
|
||||
/**
|
||||
* Get the amount of IDs remaining to be allocated
|
||||
*
|
||||
* @return free ids count
|
||||
*/
|
||||
int getFreeIDs();
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* This file is part of l2jserver2 <l2jserver2.com>.
|
||||
*
|
||||
* l2jserver2 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.
|
||||
*
|
||||
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.model.id.object.allocator;
|
||||
|
||||
/**
|
||||
* Exception thrown by an {@link IDAllocator}.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class IDAllocatorException extends RuntimeException {
|
||||
/**
|
||||
* The Java Serialization Serial
|
||||
*/
|
||||
private static final long serialVersionUID = 111195059766878062L;
|
||||
|
||||
/**
|
||||
* Creates an empty instance of this exception
|
||||
*/
|
||||
public IDAllocatorException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
* the message
|
||||
* @param cause
|
||||
* the root cause
|
||||
*/
|
||||
public IDAllocatorException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message
|
||||
* the message
|
||||
*/
|
||||
public IDAllocatorException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cause
|
||||
* the root cause
|
||||
*/
|
||||
public IDAllocatorException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -48,10 +48,29 @@ public class ActorEffectContainer implements Iterable<Effect> {
|
||||
this.actor = actor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new effect to the actor's effect container.
|
||||
* <p>
|
||||
* Please note that if the <i>same</i> effect object is already in this
|
||||
* container, nothing no exception will be thrown and the effect will not be
|
||||
* applied twice.
|
||||
*
|
||||
* @param effect
|
||||
* the effect to be added
|
||||
*/
|
||||
public void addEffect(Effect effect) {
|
||||
effects.add(effect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an effect that is attached to the actor's effect container.
|
||||
* <p>
|
||||
* Please note that if the effect is not in the container, no exception will
|
||||
* be thrown.
|
||||
*
|
||||
* @param effect
|
||||
* the effect to be removed
|
||||
*/
|
||||
public void removeEffect(Effect effect) {
|
||||
effects.remove(effect);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user