This commit is contained in:
Tassilo Schweyer 2026-06-11 11:28:49 +02:00
parent fb77d13eb5
commit 56e19e8039
30 changed files with 485 additions and 37 deletions

View file

@ -20,16 +20,7 @@ package de.welterde.em;
*
* @author welterde
*/
public abstract class Entity {
protected final EntityStorage ctx;
protected final int id;
public Entity(EntityStorage ctx, int id) {
this.id = id;
this.ctx = ctx;
}
public int getEntityId() {
return this.id;
}
public interface Entity {
public int getEntityId();
public void initEntity(EntityStorage ctx, int id);
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (C) 2026 welterde
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.welterde.em;
import de.welterde.em.io.EntityRecord;
/**
*
* @author welterde
*/
public abstract class EntityBase implements Entity {
protected EntityStorage ctx;
protected int id;
public EntityBase() {
this.id = -1;
this.ctx = null;
}
public EntityBase(EntityStorage ctx, int id) {
this.id = id;
this.ctx = ctx;
}
public EntityBase(EntityRecord r) {
this.id = r.getID();
this.ctx = r.getContext();
}
public int getEntityId() {
if(this.id == -1)
throw new IllegalStateException("Entity not initialized");
return this.id;
}
public void initEntity(EntityStorage ctx, int id) {
if((this.id != -1) && (this.ctx != null))
throw new IllegalStateException("Entity already initialized");
if(id == -1)
throw new IllegalArgumentException("Invalid ID -1");
if(ctx == null)
throw new NullPointerException("Context is null");
this.id = id;
this.ctx = ctx;
}
public boolean isEntityInitialized() {
return this.id != -1;
}
}

View file

@ -24,6 +24,10 @@ import java.lang.ref.WeakReference;
* @param <X>
*/
public class EntityRef<X extends Entity> {
static Location maybeGet(EntityRef<Location> currentLocation) {
throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
}
protected final EntityStorage ctx;
protected WeakReference<X> ref;

View file

@ -21,5 +21,5 @@ package de.welterde.em;
* @author welterde
*/
public interface EntityStorage {
public Entity getEntity(int entityId);
public EntityBase getEntity(int entityId);
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2026 welterde
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.welterde.em;
/**
*
* @author welterde
*/
public class LocatedEntity extends EntityBase {
protected EntityRef<Location> currentLocation;
public Location getLocation() {
if(this.currentLocation == null)
return null;
else
return this.currentLocation.get();
}
}

View file

@ -14,13 +14,13 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.welterde.em.data;
package de.welterde.em;
/**
*
* @author welterde
*/
public sealed interface Location permits LocationBase, Corridor, Room {
public interface Location extends Entity {
public short getSecurityLevel();
public Location setSecurityLevel(short newLevel);
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) 2026 welterde
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.welterde.em;
import de.welterde.em.data.Direction;
import de.welterde.em.data.MapCoord;
/**
*
* @author welterde
*/
public interface PositionTracker {
/**
* Get current position of entity if managed by this Position Tracker
* (Otherwise null)
* @param e
* @return
*/
public MapCoord getPosition(Entity e);
public void teleportEntity(Entity e, MapCoord destination);
public void moveEntityCardinal(Entity e, Direction dir);
public void enrollEntity(Entity e, MapCoord startCoord);
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2026 welterde
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.welterde.em;
import de.welterde.em.data.MapCoord;
/**
*
* @author welterde
*/
public class PositionTrackerImpl implements PositionTracker {
@Override
public MapCoord getPosition(Entity e) {
throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (C) 2026 welterde
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.welterde.em;
/**
*
* @author welterde
*/
public interface Positioned {
public PositionTracker getPositionTracker();
public void setPositionTracker();
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (C) 2026 welterde
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.welterde.em;
/**
* Something that has some location
* @author welterde
*/
public class Thing extends EntityBase {
protected EntityRef<Location> currentLocation;
public Location getLocation() {
return EntityRef.maybeGet(this.currentLocation);
}
public void setLocation(Location loc) {
this.currentLocation = new EntityRef<>(this.ctx, loc);
}
}

View file

@ -16,6 +16,8 @@
*/
package de.welterde.em.data;
import de.welterde.em.Location;
/**
*
* @author welterde

View file

@ -16,6 +16,8 @@
*/
package de.welterde.em.data;
import de.welterde.em.Location;
/**
*
* @author welterde

View file

@ -16,6 +16,8 @@
*/
package de.welterde.em.data;
import de.welterde.em.Location;
/**
*
* @author welterde

View file

@ -4,6 +4,9 @@
*/
package de.welterde.em.data;
import de.welterde.em.data.CoordVector;
import de.welterde.em.data.Direction;
/**
* z coordinate goes from 65km to 0, where ground-level is at 50km
* @author welterde

View file

@ -4,6 +4,7 @@
*/
package de.welterde.em.data;
import de.welterde.em.Location;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;

View file

@ -16,6 +16,8 @@
*/
package de.welterde.em.data;
import de.welterde.em.Location;
/**
*
* @author welterde

View file

@ -16,6 +16,8 @@
*/
package de.welterde.em.data;
import de.welterde.em.Location;
/**
*
* @author welterde

View file

@ -16,6 +16,7 @@
*/
package de.welterde.em.data;
import de.welterde.em.Location;
import de.welterde.em.CollisionException;
/**

View file

@ -16,13 +16,20 @@
*/
package de.welterde.em.e;
import de.welterde.em.EntityBase;
import de.welterde.em.EntityRef;
import de.welterde.em.Location;
import de.welterde.em.w.Org;
/**
*
* @author welterde
*/
public class Employee {
public class Employee extends EntityBase {
protected String name;
protected EntityRef<Org> employer;
public Employee(String name) {
this.name = name;

View file

@ -16,12 +16,16 @@
*/
package de.welterde.em.entity;
import de.welterde.em.data.Entity;
import de.welterde.em.EntityBase;
import de.welterde.em.EntityStorage;
/**
*
* @author welterde
*/
public abstract class ItemBase implements Entity {
public abstract class ItemBase extends EntityBase {
public ItemBase(EntityStorage ctx, int id) {
super(ctx, id);
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2026 welterde
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.welterde.em.io;
import de.welterde.em.EntityBase;
import java.lang.reflect.InvocationTargetException;
/**
*
* @author welterde
*/
public class EntityLoader {
protected EntityBase loadEntity(EntityRecord r, String entityClassName) {
try {
var c = Class.forName(entityClassName);
var cc = c.getConstructor(EntityRecord.class);
return (EntityBase) cc.newInstance(r);
} catch (ClassNotFoundException ex) {
throw new RuntimeException("Could not find class: " + entityClassName);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Entity class " + entityClassName + " does not support loading (missing EntityRecord constructor)");
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex);
}
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (C) 2026 welterde
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.welterde.em.io;
import de.welterde.em.EntityStorage;
/**
*
* @author welterde
*/
public interface EntityRecord {
public int getID();
public EntityStorage getContext();
}

View file

@ -16,7 +16,9 @@
*/
package de.welterde.em.w;
import de.welterde.em.data.Location;
import de.welterde.em.EntityBase;
import de.welterde.em.EntityStorage;
import de.welterde.em.Location;
import de.welterde.em.data.TerrainGen;
import java.util.HashMap;
import java.util.Map;
@ -27,15 +29,14 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
*
* @author welterde
*/
public class Area {
protected final int id;
public class Area extends EntityBase {
protected final ReadWriteLock structLock;
protected final AreaMap map;
protected final Map<Integer, Location> locations;
public Area(int id, TerrainGen gen) {
this.id = id;
public Area(EntityStorage ctx, int id, TerrainGen gen) {
super(ctx, id);
this.structLock = new ReentrantReadWriteLock();
this.map = new AreaMap(gen);

View file

@ -16,10 +16,15 @@
*/
package de.welterde.em.w;
import de.welterde.em.EntityBase;
import de.welterde.em.EntityStorage;
/**
*
* @author welterde
*/
public class City {
public class City extends EntityBase {
public City(EntityStorage ctx, int id) {
super(ctx, id);
}
}

View file

@ -16,14 +16,14 @@
*/
package de.welterde.em.w;
import de.welterde.em.Entity;
import de.welterde.em.EntityBase;
import de.welterde.em.EntityStorage;
/**
*
* @author welterde
*/
public class Country extends Entity {
public class Country extends EntityBase {
public Country(EntityStorage ctx, int id) {
super(ctx, id);

View file

@ -16,7 +16,7 @@
*/
package de.welterde.em.w;
import de.welterde.em.Entity;
import de.welterde.em.EntityBase;
import de.welterde.em.data.CounterName;
import de.welterde.em.data.TerrainGen;
import java.util.HashMap;
@ -28,7 +28,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
*
* @author welterde
*/
public class Dimension extends Entity {
public class Dimension extends EntityBase {
protected final ReadWriteLock structLock;
protected final Map<Integer, Area> areas;

View file

@ -16,10 +16,26 @@
*/
package de.welterde.em.w;
import de.welterde.em.EntityBase;
import de.welterde.em.EntityRef;
import de.welterde.em.e.Employee;
import java.util.ArrayList;
import java.util.List;
/**
* Organization
* @author welterde
*/
public class Org {
public class Org extends EntityBase {
protected String name;
protected EntityRef<Outpost> hqOutpost;
protected final List<EntityRef<Outpost>> outposts;
protected final List<EntityRef<Employee>> employees;
public Org(String name) {
this.name = name;
this.outposts = new ArrayList<>();
this.employees = new ArrayList<>();
}
}

View file

@ -16,16 +16,38 @@
*/
package de.welterde.em.w;
import de.welterde.em.EntityBase;
import de.welterde.em.EntityRef;
import de.welterde.em.EntityStorage;
import java.util.EnumSet;
/**
*
* @author welterde
*/
public class Outpost {
public class Outpost extends EntityBase {
protected final EnumSet<OutpostFlags> flags;
protected final OutpostLocationType locationType;
protected EntityRef<City> city;
public Outpost() {
public Outpost(EntityStorage ctx, int id, OutpostLocationType locationType) {
super(ctx, id);
this.flags = EnumSet.noneOf(OutpostFlags.class);
this.locationType = locationType;
}
public EnumSet<OutpostFlags> getFlags() {
return flags.clone();
}
public OutpostLocationType getLocationType() {
return locationType;
}
public City getCity() {
if(this.city != null)
return this.city.get();
else
return null;
}
}

View file

@ -16,7 +16,7 @@
*/
package de.welterde.em.w;
import de.welterde.em.Entity;
import de.welterde.em.EntityBase;
import de.welterde.em.EntityRef;
import de.welterde.em.EntityStorage;
import de.welterde.em.data.CounterName;
@ -25,6 +25,7 @@ import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@ -33,19 +34,27 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
* @author welterde
*/
public class World implements EntityStorage {
protected final ArrayList<Entity> entities;
protected final ArrayList<EntityBase> entities;
protected final EnumMap<CounterName, Integer> counters;
protected final ArrayList<EntityRef<Dimension>> dimensions;
protected final Map<Integer, EntityRef<Country>> countries;
protected final ArrayList<Dimension> dimensions;
protected final Map<Integer, Country> countries;
protected final Map<Integer, Org> orgs;
protected final Map<Integer, Outpost> outposts;
protected final ReadWriteLock structLock;
protected final AtomicReference<WorldState> state;
public World() {
this.counters = new EnumMap<>(CounterName.class);
this.dimensions = new ArrayList<>();
this.countries = new HashMap<>();
this.entities = new ArrayList<>();
this.orgs = new HashMap<>();
this.outposts = new HashMap<>();
this.structLock = new ReentrantReadWriteLock();
this.state = new AtomicReference<>(WorldState.INIT);
}
@ -81,7 +90,46 @@ public class World implements EntityStorage {
}
@Override
public Entity getEntity(int entityId) {
public EntityBase getEntity(int entityId) {
return this.entities.get(entityId);
}
public void addEntity(EntityBase e) {
if(e.isEntityInitialized())
throw new IllegalStateException("Entity already initialized");
int id;
this.structLock.writeLock().lock();
try {
id = this.entities.size();
e.initEntity(this, id);
this.entities.add(e);
} finally {
this.structLock.writeLock().unlock();
}
// TODO: Add to queue for new entity listeners?
this.handleNewEntity(e);
}
public void handleNewEntity(EntityBase e) {
switch(e) {
case Dimension d -> {
}
case Country c -> {
}
case Org o -> {
}
case Outpost o -> {
}
default -> {
// dont care..
}
}
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (C) 2026 welterde
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.welterde.em.w;
/**
*
* @author welterde
*/
public enum WorldState {
READY,
LOADING,
DUMPING,
INIT
}