Beta universe implementation.

This commit is contained in:
Olof Larsson 2012-09-01 18:31:33 +02:00
parent 46b044e5c4
commit 4883d0754f
15 changed files with 363 additions and 24 deletions

View File

@ -47,7 +47,7 @@ public class MCore extends MPlugin
// CONSTRUCT // CONSTRUCT
// -------------------------------------------- // // -------------------------------------------- //
protected static MCore p; public static MCore p;
public MCore() public MCore()
{ {
p = this; p = this;

View File

@ -9,12 +9,12 @@ import com.massivecraft.mcore4.store.Coll;
import com.massivecraft.mcore4.util.PlayerUtil; import com.massivecraft.mcore4.util.PlayerUtil;
import com.massivecraft.mcore4.util.Txt; import com.massivecraft.mcore4.util.Txt;
public class AHPlayerWrapperNew<E> extends AHBase<E> public class AHPlayerWrapperColl<E> extends AHBase<E>
{ {
final Coll<E, ?> coll; final Coll<E, ?> coll;
public Coll<E, ?> coll() { return this.coll; }; public Coll<E, ?> coll() { return this.coll; };
public AHPlayerWrapperNew(Coll<E, ?> coll) public AHPlayerWrapperColl(Coll<E, ?> coll)
{ {
this.coll = coll; this.coll = coll;
} }

View File

@ -0,0 +1,28 @@
package com.massivecraft.mcore4.cmd.arg;
import org.bukkit.command.CommandSender;
import com.massivecraft.mcore4.MPlugin;
import com.massivecraft.mcore4.store.Coll;
import com.massivecraft.mcore4.store.Colls;
public class AHPlayerWrapperColls<E> extends AHBase<E>
{
protected final Colls<Coll<E, ?>, E, ?> colls;
public Colls<Coll<E, ?>, E, ?> colls() { return this.colls; };
@SuppressWarnings("unchecked")
public AHPlayerWrapperColls(Object colls)
{
this.colls = (Colls<Coll<E, ?>, E, ?>) colls;
}
@Override
public E parse(String str, String style, CommandSender sender, MPlugin p)
{
Coll<E, ?> coll = colls.get(sender);
AHPlayerWrapperColl<E> ahinner = new AHPlayerWrapperColl<E>(coll);
E ret = ahinner.parse(str, style, sender, p);
this.error.addAll(ahinner.error);
return ret;
}
}

View File

@ -14,6 +14,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import com.massivecraft.mcore4.MCore; import com.massivecraft.mcore4.MCore;
import com.massivecraft.mcore4.MPlugin; import com.massivecraft.mcore4.MPlugin;
import com.massivecraft.mcore4.Predictate; import com.massivecraft.mcore4.Predictate;
import com.massivecraft.mcore4.store.accessor.Accessor;
import com.massivecraft.mcore4.store.idstrategy.IdStrategy; import com.massivecraft.mcore4.store.idstrategy.IdStrategy;
import com.massivecraft.mcore4.store.storeadapter.StoreAdapter; import com.massivecraft.mcore4.store.storeadapter.StoreAdapter;
@ -121,9 +122,14 @@ public class Coll<E, L> implements CollInterface<E, L>
@Override public boolean isDefault(E entity) { return false; } @Override public boolean isDefault(E entity) { return false; }
// -------------------------------------------- // // -------------------------------------------- //
// CREATE // COPY AND CREATE
// -------------------------------------------- // // -------------------------------------------- //
public void copy(Object ofrom, Object oto)
{
Accessor.get(this.entityClass()).copy(ofrom, oto);
}
// This simply creates and returns a new instance // This simply creates and returns a new instance
// It does not detach/attach or anything. Just creates a new instance. // It does not detach/attach or anything. Just creates a new instance.
@Override @Override
@ -176,6 +182,7 @@ public class Coll<E, L> implements CollInterface<E, L>
return this.attach(entity, oid, true); return this.attach(entity, oid, true);
} }
@SuppressWarnings({ "unchecked", "rawtypes" })
protected synchronized L attach(E entity, Object oid, boolean noteChange) protected synchronized L attach(E entity, Object oid, boolean noteChange)
{ {
// Check entity // Check entity
@ -201,6 +208,12 @@ public class Coll<E, L> implements CollInterface<E, L>
this.id2entity.put(id, entity); this.id2entity.put(id, entity);
this.entity2id.put(entity, id); this.entity2id.put(entity, id);
// Set this as the coll if possible.
if (entity instanceof Entity)
{
((Entity)entity).setColl(this);
}
// Make note of the change // Make note of the change
if (noteChange) if (noteChange)
{ {

View File

@ -60,9 +60,11 @@ public interface CollInterface<E, L>
public boolean isDefault(E entity); public boolean isDefault(E entity);
// -------------------------------------------- // // -------------------------------------------- //
// CREATE // COPY AND CREATE
// -------------------------------------------- // // -------------------------------------------- //
public void copy(Object fromo, Object too);
// This simply creates and returns a new instance // This simply creates and returns a new instance
// It does not detach/attach or anything. Just creates a new instance. // It does not detach/attach or anything. Just creates a new instance.
public E createNewInstance(); public E createNewInstance();

View File

@ -0,0 +1,41 @@
package com.massivecraft.mcore4.store;
import java.util.HashMap;
import java.util.Map;
import com.massivecraft.mcore4.util.MUtil;
public abstract class Colls<C extends Coll<E, L>, E, L>
{
public abstract String name();
public abstract C createColl(String collName);
public String collNameFromCategory(String category)
{
return this.name() + "_" + category;
}
protected Map<String, C> name2coll = new HashMap<String, C>();
public C get(Object worldNameExtractable)
{
String worldName = MUtil.extract(String.class, "worldName", worldNameExtractable);
String category = WCatColl.i.get(this.name()).categorize(worldName);
String collName = this.collNameFromCategory(category);
C ret = this.name2coll.get(collName);
if (ret == null)
{
ret = this.createColl(collName);
this.name2coll.put(collName, ret);
}
return ret;
}
public E get2(Object worldNameExtractable)
{
C coll = this.get(worldNameExtractable);
if (coll == null) return null;
return coll.get(worldNameExtractable);
}
}

View File

@ -1,6 +1,8 @@
package com.massivecraft.mcore4.store; package com.massivecraft.mcore4.store;
import com.massivecraft.mcore4.MCore;
import com.massivecraft.mcore4.store.accessor.Accessor; import com.massivecraft.mcore4.store.accessor.Accessor;
import com.massivecraft.mcore4.xlib.gson.Gson;
/** /**
* Usage of this class is highly optional. You may persist anything. If you are * Usage of this class is highly optional. You may persist anything. If you are
@ -12,23 +14,34 @@ import com.massivecraft.mcore4.store.accessor.Accessor;
// http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ206 // http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ206
public abstract class Entity<E extends Entity<E, L>, L> public abstract class Entity<E extends Entity<E, L>, L>
{ {
public abstract Coll<E, L> getColl(); protected transient Coll<E, L> coll;
protected void setColl(Coll<E, L> val) { this.coll = val; }
public Coll<E, L> getColl() { return this.coll; }
protected abstract E getThis(); protected abstract E getThis();
protected abstract Class<E> getClazz();
public L attach() public abstract E getDefaultInstance();
public L attach(Coll<E, L> coll)
{ {
return this.getColl().attach(getThis()); return coll.attach(getThis());
} }
public E detach() public E detach()
{ {
return this.getColl().detach(getThis()); Coll<E, L> coll = this.getColl();
if (coll == null) return null;
return coll.detach(getThis());
} }
public boolean attached() public boolean attached()
{ {
return this.getColl().getAll().contains(getThis()); Coll<E, L> coll = this.getColl();
if (coll == null) return false;
return coll.getAll().contains(getThis());
} }
public boolean detached() public boolean detached()
@ -38,15 +51,16 @@ public abstract class Entity<E extends Entity<E, L>, L>
public L getId() public L getId()
{ {
return this.getColl().id(getThis()); Coll<E, L> coll = this.getColl();
if (coll == null) return null;
return coll.id(this.getThis());
} }
// TODO: Perhaps even brute force methods to save or load from remote.
public void changed() public void changed()
{ {
L id = this.getId(); L id = this.getId();
if (id == null) return; if (id == null) return;
this.getColl().changedIds.add(id); this.getColl().changedIds.add(id);
} }
@ -54,6 +68,7 @@ public abstract class Entity<E extends Entity<E, L>, L>
{ {
L id = this.getId(); L id = this.getId();
if (id == null) return; if (id == null) return;
this.getColl().syncId(id); this.getColl().syncId(id);
} }
@ -61,6 +76,7 @@ public abstract class Entity<E extends Entity<E, L>, L>
{ {
L id = this.getId(); L id = this.getId();
if (id == null) return; if (id == null) return;
this.getColl().saveToRemote(id); this.getColl().saveToRemote(id);
} }
@ -68,29 +84,29 @@ public abstract class Entity<E extends Entity<E, L>, L>
{ {
L id = this.getId(); L id = this.getId();
if (id == null) return; if (id == null) return;
this.getColl().loadFromRemote(id); this.getColl().loadFromRemote(id);
} }
@Override @Override
public String toString() public String toString()
{ {
return this.getClass().getSimpleName()+this.getColl().mplugin().gson.toJson(this, this.getColl().entityClass()); Gson gson = MCore.gson;
} Coll<E, L> coll = this.getColl();
if (coll != null) gson = coll.mplugin().gson;
public E getDefaultInstance() return this.getClazz().getSimpleName()+gson.toJson(this, this.getClazz());
{
return this.getColl().createNewInstance();
} }
public E loadDefaults() public E loadDefaults()
{ {
Accessor.get(this.getColl().entityClass()).copy(this.getDefaultInstance(), this.getThis()); Accessor.get(this.getClazz()).copy(this.getDefaultInstance(), this.getThis());
return this.getThis(); return this.getThis();
} }
public E load(E entity) public E load(E entity)
{ {
Accessor.get(this.getColl().entityClass()).copy(entity, this.getThis()); Accessor.get(this.getClazz()).copy(entity, this.getThis());
return this.getThis(); return this.getThis();
} }
} }

View File

@ -0,0 +1,92 @@
package com.massivecraft.mcore4.store;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import com.massivecraft.mcore4.util.MUtil;
/**
* WCat stands for World Categorizer.
* They provide a recursive matching system.
*/
public class WCat extends Entity<WCat, String>
{
public final static transient String RETURN = "_return";
public final static transient String RUN = "_run";
public final static transient String _DEFAULT = "_default";
public final static transient String DEFAULT = "default";
public final static transient List<WCatRule> DEFAULT_RULES = MUtil.list(new WCatRule(RUN, _DEFAULT));
public final static transient List<WCatRule> DEFAULT_DEFAULT_RULES = MUtil.list(new WCatRule(RETURN, DEFAULT));
// -------------------------------------------- //
// META
// -------------------------------------------- //
@Override public Coll<WCat, String> getColl() { return WCatColl.i; }
@Override protected WCat getThis() { return this; }
private final static transient WCat defaultInstance = new WCat();
@Override public WCat getDefaultInstance(){ return defaultInstance; }
@Override protected Class<WCat> getClazz() { return WCat.class; }
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
protected List<WCatRule> rules;
public List<WCatRule> rules() { return this.rules; };
public void rules(List<WCatRule> val) { this.rules = new ArrayList<WCatRule>(val); };
public void rules(String... namesAndParams)
{
this.rules = new ArrayList<WCatRule>();
Iterator<String> iter = Arrays.asList(namesAndParams).iterator();
while (iter.hasNext())
{
String name = iter.next();
String param = iter.next();
this.rules.add(new WCatRule(name, param));
}
}
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public WCat()
{
this.rules(DEFAULT_RULES);
}
// -------------------------------------------- //
// THAT SPECIAL LOGIC
// -------------------------------------------- //
public String categorize(String worldName)
{
for (WCatRule rule : this.rules())
{
String name = rule.name();
String param = rule.param();
if (name.equals(RETURN))
{
return param;
}
else if (name.equals(RUN))
{
WCat subcat = WCatColl.i.get(param);
String subcatresult = subcat.categorize(worldName);
if (subcatresult != null) return subcatresult;
}
else if (name.equalsIgnoreCase(worldName))
{
return param;
}
}
return null;
}
}

View File

@ -0,0 +1,41 @@
package com.massivecraft.mcore4.store;
import com.massivecraft.mcore4.MCore;
public class WCatColl extends Coll<WCat, String>
{
// -------------------------------------------- //
// META
// -------------------------------------------- //
public static WCatColl i = new WCatColl();
private WCatColl()
{
super(MCore.p, "ai", "mcore_wcat", WCat.class, String.class, true);
}
@Override
public void copy(Object ofrom, Object oto)
{
WCat from = (WCat)ofrom;
WCat to = (WCat)oto;
to.rules = from.rules;
}
@Override
public void init()
{
super.init();
// Ensure the default WorldCategorizer is present.
WCat d = this.get(WCat._DEFAULT);
d.rules(WCat.DEFAULT_DEFAULT_RULES);
}
@Override
public boolean isDefault(WCat entity)
{
return entity.rules().equals(WCat.DEFAULT_RULES);
}
}

View File

@ -0,0 +1,22 @@
package com.massivecraft.mcore4.store;
public class WCatRule
{
protected final String name;
public String name() { return this.name; }
protected final String param;
public String param() { return this.param; }
public WCatRule()
{
this.name = null;
this.param = null;
}
public WCatRule(String name, String param)
{
this.name = name;
this.param = param;
}
}

View File

@ -1,7 +1,6 @@
package com.massivecraft.mcore4.store.storeadapter; package com.massivecraft.mcore4.store.storeadapter;
import com.massivecraft.mcore4.store.Coll; import com.massivecraft.mcore4.store.Coll;
import com.massivecraft.mcore4.store.accessor.Accessor;
import com.massivecraft.mcore4.xlib.gson.JsonElement; import com.massivecraft.mcore4.xlib.gson.JsonElement;
public class StoreAdapterGson extends StoreAdapterAbstract public class StoreAdapterGson extends StoreAdapterAbstract
@ -21,7 +20,7 @@ public class StoreAdapterGson extends StoreAdapterAbstract
public void write(Coll<?, ?> coll, Object raw, Object entity) public void write(Coll<?, ?> coll, Object raw, Object entity)
{ {
Object temp = coll.mplugin().gson.fromJson((JsonElement)raw, coll.entityClass()); Object temp = coll.mplugin().gson.fromJson((JsonElement)raw, coll.entityClass());
Accessor.get(coll.entityClass()).copy(temp, entity); coll.copy(temp, entity);
} }
// -------------------------------------------- // // -------------------------------------------- //

View File

@ -3,6 +3,7 @@ package com.massivecraft.mcore4.util;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -23,6 +24,8 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import com.massivecraft.mcore4.MCore; import com.massivecraft.mcore4.MCore;
import com.massivecraft.mcore4.util.extractor.Extractor;
import com.massivecraft.mcore4.util.extractor.ExtractorWorldName;
public class MUtil public class MUtil
{ {
@ -171,4 +174,58 @@ public class MUtil
if (MCore.random.nextDouble() < prob) ret += 1; if (MCore.random.nextDouble() < prob) ret += 1;
return ret; return ret;
} }
// -------------------------------------------- //
// EXTRACTION
// -------------------------------------------- //
protected static Map<Class<?>, Map<String, Set<Extractor>>> classesPropertiesExtractors = new HashMap<Class<?>, Map<String, Set<Extractor>>>();
protected static Map<String, Set<Extractor>> getPropertiesExtractors(Class<?> propertyClass)
{
Map<String, Set<Extractor>> ret = classesPropertiesExtractors.get(propertyClass);
if (ret == null)
{
ret = new HashMap<String, Set<Extractor>>();
classesPropertiesExtractors.put(propertyClass, ret);
}
return ret;
}
protected static Set<Extractor> getExtractors(Class<?> propertyClass, String propertyName)
{
Map<String, Set<Extractor>> propertiesExtractors = getPropertiesExtractors(propertyClass);
Set<Extractor> ret = propertiesExtractors.get(propertyName);
if (ret == null)
{
ret = new HashSet<Extractor>();
propertiesExtractors.put(propertyName, ret);
}
return ret;
}
@SuppressWarnings("unchecked")
public static <T> T extract(Class<T> propertyClass, String propertyName, Object o)
{
Object ret = null;
for (Extractor extractor : getExtractors(propertyClass, propertyName))
{
ret = extractor.extract(o);
if (ret != null) break;
}
return (T) ret;
}
public static <T> void registerExtractor(Class<T> clazz, String propertyName, Extractor extractor)
{
getExtractors(clazz, propertyName).add(extractor);
}
// -------------------------------------------- //
// STATIC CONSTRUCT
// -------------------------------------------- //
static
{
registerExtractor(String.class, "worldName", new ExtractorWorldName());
}
} }

View File

@ -226,7 +226,7 @@ public class Txt
} }
else else
{ {
ret.append(list[i].toString()); ret.append(str);
} }
} }
return ret.toString(); return ret.toString();

View File

@ -0,0 +1,6 @@
package com.massivecraft.mcore4.util.extractor;
public interface Extractor
{
public Object extract(Object o);
}

View File

@ -0,0 +1,22 @@
package com.massivecraft.mcore4.util.extractor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.event.player.PlayerEvent;
public class ExtractorWorldName implements Extractor
{
@Override
public Object extract(Object o)
{
if (o instanceof String) return o;
if (o instanceof World) return ((World)o).getName();
if (o instanceof Block) return ((Block)o).getWorld().getName();
if (o instanceof Location) return ((Location)o).getWorld().getName();
if (o instanceof Entity) return ((Entity)o).getWorld().getName();
if (o instanceof PlayerEvent) return ((PlayerEvent)o).getPlayer().getWorld().getName();
return null;
}
}