Added FilterServerContext and DefaultServerContextLogic

- Added DefaultServerContextLogic
  - A standard implementation of ServerTileContext.Logic that delegates
all methods to a ServerTileContext instance
  - Now used by DefaultServerContextImpl
- Added FilterServerContext
  - A base for creating context wrappers
This commit is contained in:
OLEGSHA 2021-08-08 12:19:31 +03:00
parent 0f909039fe
commit 020802a89c
Signed by: OLEGSHA
GPG Key ID: E57A4B08D64AFF7A
4 changed files with 405 additions and 195 deletions

View File

@ -18,12 +18,12 @@
package ru.windcorp.progressia.server.world.context.impl;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.common.world.generic.TileGenericReferenceRO;
import ru.windcorp.progressia.common.world.generic.TileGenericStackRO;
import ru.windcorp.progressia.common.world.rels.BlockFace;
import ru.windcorp.progressia.common.world.rels.RelFace;
import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.world.WorldLogic;
public interface DefaultServerContextBuilders {
@ -31,10 +31,10 @@ public interface DefaultServerContextBuilders {
public interface Empty /* does not extend RSCB */ {
WithWorld in(Server server, WorldLogic world);
WithWorld in(Server server, WorldData world);
default WithWorld inRealWorldOf(Server server) {
return in(server, server.getWorld());
return in(server, server.getWorld().getData());
}
}

View File

@ -33,11 +33,6 @@ import ru.windcorp.progressia.common.world.rels.BlockFace;
import ru.windcorp.progressia.common.world.rels.RelFace;
import ru.windcorp.progressia.common.world.tile.TileData;
import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.world.TileLogicStack;
import ru.windcorp.progressia.server.world.WorldLogic;
import ru.windcorp.progressia.server.world.block.BlockLogic;
import ru.windcorp.progressia.server.world.context.ServerTileContext;
import ru.windcorp.progressia.server.world.tile.TileLogic;
class DefaultServerContextImpl extends DefaultServerContext
implements DefaultServerContextBuilders.Empty, DefaultServerContextBuilders.WithWorld,
@ -58,16 +53,10 @@ class DefaultServerContextImpl extends DefaultServerContext
protected Server server;
/**
* The relevant {@link WorldLogic} instance. If this is {@code null}, the
* The relevant {@link WorldData} instance. If this is {@code null}, the
* role is {@link Role#NONE}.
*/
protected WorldLogic worldLogic;
/**
* The {@link WorldData} accessible through {@link #worldLogic}. This field
* is kept always in sync with {@link #worldLogic}.
*/
protected WorldData worldData;
protected WorldData world;
/**
* The {@link Random} instance exposed with {@link #getRandom()}.
@ -89,7 +78,7 @@ class DefaultServerContextImpl extends DefaultServerContext
/**
* The Logic view returned by {@link #logic()}.
*/
protected final DefaultServerContextImpl.Logic logic = new Logic();
protected final DefaultServerContextImpl.Logic logic = new DefaultServerContextLogic(this);
/**
* Returns the Role currently assumed by this object.
@ -199,8 +188,8 @@ class DefaultServerContextImpl extends DefaultServerContext
public Empty reuse() {
server = null;
worldLogic = null;
worldData = null;
// worldLogic = null;
world = null;
while (isSubcontexting()) {
pop();
@ -228,11 +217,10 @@ class DefaultServerContextImpl extends DefaultServerContext
*/
@Override
public WithWorld in(Server server, WorldLogic world) {
public WithWorld in(Server server, WorldData world) {
requireBuilderRole(Role.NONE);
this.server = server;
this.worldLogic = world;
this.worldData = world.getData();
this.world = world;
return this;
}
@ -261,7 +249,7 @@ class DefaultServerContextImpl extends DefaultServerContext
@Override
public WithTileStack on(BlockFace side) {
requireBuilderRole(Role.LOCATION);
frame.face = side.relativize(worldLogic.getData().getUp(frame.location));
frame.face = side.relativize(world.getUp(frame.location));
return this;
}
@ -329,31 +317,31 @@ class DefaultServerContextImpl extends DefaultServerContext
@Override
public BlockData getBlock(Vec3i location) {
assert requireContextRole(Role.WORLD);
return worldData.getBlock(location);
return world.getBlock(location);
}
@Override
public boolean isLocationLoaded(Vec3i location) {
assert requireContextRole(Role.WORLD);
return worldData.isLocationLoaded(location);
return world.isLocationLoaded(location);
}
@Override
public TileData getTile(Vec3i location, BlockFace face, int layer) {
assert requireContextRole(Role.WORLD);
return worldData.getTile(location, face, layer);
return world.getTile(location, face, layer);
}
@Override
public boolean hasTile(Vec3i location, BlockFace face, int layer) {
assert requireContextRole(Role.WORLD);
return worldData.hasTile(location, face, layer);
return world.hasTile(location, face, layer);
}
@Override
public TileData getTileByTag(Vec3i location, BlockFace face, int tag) {
assert requireContextRole(Role.WORLD);
TileDataStack stack = worldData.getTilesOrNull(location, face);
TileDataStack stack = world.getTilesOrNull(location, face);
if (stack == null)
return null;
int layer = stack.getIndexByTag(tag);
@ -365,7 +353,7 @@ class DefaultServerContextImpl extends DefaultServerContext
@Override
public boolean isTagValid(Vec3i location, BlockFace face, int tag) {
assert requireContextRole(Role.WORLD);
TileDataStack stack = worldData.getTilesOrNull(location, face);
TileDataStack stack = world.getTilesOrNull(location, face);
if (stack == null)
return false;
return stack.getIndexByTag(tag) != -1;
@ -374,7 +362,7 @@ class DefaultServerContextImpl extends DefaultServerContext
@Override
public int getTag() {
assert requireContextRole(Role.TILE);
TileDataStack stack = worldData.getTilesOrNull(frame.location, frame.face);
TileDataStack stack = world.getTilesOrNull(frame.location, frame.face);
if (stack == null)
return -1;
return stack.getTagByIndex(frame.layer);
@ -383,7 +371,7 @@ class DefaultServerContextImpl extends DefaultServerContext
@Override
public int getTileCount(Vec3i location, BlockFace face) {
assert requireContextRole(Role.TILE_STACK);
TileDataStack stack = worldData.getTilesOrNull(frame.location, frame.face);
TileDataStack stack = world.getTilesOrNull(frame.location, frame.face);
if (stack == null)
return 0;
return stack.size();
@ -392,25 +380,25 @@ class DefaultServerContextImpl extends DefaultServerContext
@Override
public Collection<EntityData> getEntities() {
assert requireContextRole(Role.WORLD);
return worldData.getEntities();
return world.getEntities();
}
@Override
public EntityData getEntity(long entityId) {
assert requireContextRole(Role.WORLD);
return worldData.getEntity(entityId);
return world.getEntity(entityId);
}
@Override
public GravityModel getGravityModel() {
assert requireContextRole(Role.WORLD);
return worldData.getGravityModel();
return world.getGravityModel();
}
@Override
public float getTime() {
assert requireContextRole(Role.WORLD);
return worldData.getTime();
return world.getTime();
}
/*
@ -426,19 +414,19 @@ class DefaultServerContextImpl extends DefaultServerContext
@Override
public void setBlock(Vec3i blockInWorld, BlockData block) {
assert requireContextRole(Role.WORLD);
worldData.setBlock(blockInWorld, block, true);
world.setBlock(blockInWorld, block, true);
}
@Override
public void addTile(Vec3i location, BlockFace face, TileData tile) {
assert requireContextRole(Role.WORLD);
worldData.getTiles(location, face).addFarthest(tile);
world.getTiles(location, face).addFarthest(tile);
}
@Override
public void removeTile(Vec3i location, BlockFace face, int tag) {
assert requireContextRole(Role.WORLD);
TileDataStack stack = worldData.getTilesOrNull(location, face);
TileDataStack stack = world.getTilesOrNull(location, face);
if (stack == null)
return;
int layer = stack.getIndexByTag(tag);
@ -450,184 +438,31 @@ class DefaultServerContextImpl extends DefaultServerContext
@Override
public void addEntity(EntityData entity) {
assert requireContextRole(Role.WORLD);
worldData.addEntity(entity);
world.addEntity(entity);
}
@Override
public void removeEntity(long entityId) {
assert requireContextRole(Role.WORLD);
worldData.removeEntity(entityId);
world.removeEntity(entityId);
}
@Override
public <SE extends StatefulObject & EntityGeneric> void changeEntity(SE entity, StateChange<SE> change) {
assert requireContextRole(Role.WORLD);
worldData.changeEntity(entity, change);
world.changeEntity(entity, change);
}
@Override
public void advanceTime(float change) {
assert requireContextRole(Role.WORLD);
worldData.advanceTime(change);
world.advanceTime(change);
}
/*
* ServerWorldContext.Logic STUFF
*/
private class Logic implements ServerTileContext.Logic {
/*
* LOCATION GETTERS
*/
@Override
public Server getServer() {
return server;
}
@Override
public Vec3i getLocation() {
return frame.location;
}
@Override
public RelFace getFace() {
return frame.face;
}
@Override
public int getLayer() {
return frame.layer;
}
/*
* RO CONTEXT INTERFACE
*/
@Override
public boolean isReal() {
return true;
}
@Override
public Random getRandom() {
return random;
}
@Override
public double getTickLength() {
return server.getTickLength();
}
@Override
public BlockLogic getBlock(Vec3i location) {
assert requireContextRole(Role.WORLD);
return worldLogic.getBlock(location);
}
@Override
public boolean isLocationLoaded(Vec3i location) {
return worldData.isLocationLoaded(location);
}
@Override
public boolean hasTile(Vec3i location, BlockFace face, int layer) {
return worldData.hasTile(location, face, layer);
}
@Override
public boolean isTagValid(Vec3i location, BlockFace face, int tag) {
return DefaultServerContextImpl.this.isTagValid(location, face, tag);
}
@Override
public TileLogic getTile(Vec3i location, BlockFace face, int layer) {
assert requireContextRole(Role.WORLD);
return worldLogic.getTile(location, face, layer);
}
@Override
public TileLogic getTileByTag(Vec3i location, BlockFace face, int tag) {
assert requireContextRole(Role.WORLD);
TileLogicStack stack = worldLogic.getTilesOrNull(location, face);
if (stack == null) {
return null;
}
int layer = stack.getIndexByTag(tag);
if (layer == -1) {
return null;
}
return stack.get(layer);
}
@Override
public int getTileCount(Vec3i location, BlockFace face) {
assert requireContextRole(Role.WORLD);
TileLogicStack stack = worldLogic.getTilesOrNull(location, face);
if (stack == null) {
return 0;
}
return stack.size();
}
@Override
public int getTag() {
return DefaultServerContextImpl.this.getTag();
}
@Override
public Collection<EntityData> getEntities() {
return worldLogic.getEntities();
}
@Override
public EntityData getEntity(long entityId) {
return worldLogic.getEntity(entityId);
}
/*
* Subcontexting
*/
@Override
public Logic push(Vec3i location) {
DefaultServerContextImpl.this.push(location);
return this;
}
@Override
public Logic push(Vec3i location, RelFace face) {
DefaultServerContextImpl.this.push(location, face);
return this;
}
@Override
public Logic push(Vec3i location, RelFace face, int layer) {
DefaultServerContextImpl.this.push(location, face, layer);
return this;
}
@Override
public void pop() {
DefaultServerContextImpl.this.pop();
}
/*
* MISC
*/
@Override
public DefaultServerContext data() {
return DefaultServerContextImpl.this;
}
@Override
public String toString() {
return DefaultServerContextImpl.this + ".Logic";
}
}
@Override
public Logic logic() {
assert requireContextRole(Role.WORLD);

View File

@ -0,0 +1,165 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* 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 <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.server.world.context.impl;
import java.util.Collection;
import java.util.Random;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.world.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.rels.BlockFace;
import ru.windcorp.progressia.common.world.rels.RelFace;
import ru.windcorp.progressia.common.world.tile.TileData;
import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.world.block.BlockLogic;
import ru.windcorp.progressia.server.world.block.BlockLogicRegistry;
import ru.windcorp.progressia.server.world.context.ServerTileContext;
import ru.windcorp.progressia.server.world.tile.TileLogic;
import ru.windcorp.progressia.server.world.tile.TileLogicRegistry;
public class DefaultServerContextLogic implements ServerTileContext.Logic {
private final ServerTileContext parent;
public DefaultServerContextLogic(ServerTileContext parent) {
this.parent = parent;
}
@Override
public ServerTileContext data() {
return parent;
}
@Override
public Server getServer() {
return parent.getServer();
}
@Override
public Random getRandom() {
return parent.getRandom();
}
@Override
public BlockLogic getBlock(Vec3i location) {
BlockData data = parent.getBlock(location);
return data == null ? null : BlockLogicRegistry.getInstance().get(data.getId());
}
@Override
public boolean isLocationLoaded(Vec3i location) {
return parent.isLocationLoaded(location);
}
@Override
public ServerTileContext.Logic push(Vec3i location) {
parent.push(location);
return this;
}
@Override
public ServerTileContext.Logic push(Vec3i location, RelFace face) {
parent.push(location, face);
return this;
}
@Override
public ServerTileContext.Logic push(Vec3i location, RelFace face, int layer) {
parent.push(location, face, layer);
return this;
}
@Override
public double getTickLength() {
return parent.getTickLength();
}
@Override
public TileLogic getTile(Vec3i location, BlockFace face, int layer) {
TileData data = parent.getTile(location, face, layer);
return data == null ? null : TileLogicRegistry.getInstance().get(data.getId());
}
@Override
public TileLogic getTileByTag(Vec3i location, BlockFace face, int tag) {
TileData data = parent.getTileByTag(location, face, tag);
return data == null ? null : TileLogicRegistry.getInstance().get(data.getId());
}
@Override
public Vec3i getLocation() {
return parent.getLocation();
}
@Override
public boolean hasTile(Vec3i location, BlockFace face, int layer) {
return parent.hasTile(location, face, layer);
}
@Override
public boolean isTagValid(Vec3i location, BlockFace face, int tag) {
return parent.isTagValid(location, face, tag);
}
@Override
public boolean isReal() {
return parent.isReal();
}
@Override
public int getTileCount(Vec3i location, BlockFace face) {
return parent.getTileCount(location, face);
}
@Override
public Collection<EntityData> getEntities() {
return parent.getEntities();
}
@Override
public EntityData getEntity(long entityId) {
return parent.getEntity(entityId);
}
@Override
public void pop() {
parent.pop();
}
@Override
public RelFace getFace() {
return parent.getFace();
}
@Override
public int getLayer() {
return parent.getLayer();
}
@Override
public int getTag() {
return parent.getTag();
}
@Override
public String toString() {
return parent + ".Logic";
}
}

View File

@ -0,0 +1,210 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* 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 <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.server.world.context.impl;
import java.util.Collection;
import java.util.Random;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.state.StateChange;
import ru.windcorp.progressia.common.state.StatefulObject;
import ru.windcorp.progressia.common.world.GravityModel;
import ru.windcorp.progressia.common.world.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.EntityGeneric;
import ru.windcorp.progressia.common.world.rels.BlockFace;
import ru.windcorp.progressia.common.world.rels.RelFace;
import ru.windcorp.progressia.common.world.tile.TileData;
import ru.windcorp.progressia.server.Server;
import ru.windcorp.progressia.server.world.context.ServerBlockContext;
import ru.windcorp.progressia.server.world.context.ServerTileContext;
import ru.windcorp.progressia.server.world.context.ServerTileStackContext;
/**
* This is an implementation of the server context tree that delegates all calls
* to a provided instance of {@link ServerTileContext}.
*/
public abstract class FilterServerContext implements ServerTileContext {
protected final ServerTileContext parent;
protected final DefaultServerContextLogic logic = new DefaultServerContextLogic(this);
public FilterServerContext(ServerTileContext parent) {
this.parent = parent;
}
public ServerTileContext getParent() {
return parent;
}
@Override
public int getLayer() {
return parent.getLayer();
}
@Override
public int getTag() {
return parent.getTag();
}
@Override
public RelFace getFace() {
return parent.getFace();
}
@Override
public Vec3i getLocation() {
return parent.getLocation();
}
@Override
public boolean isReal() {
return parent.isReal();
}
@Override
public void pop() {
parent.pop();
}
@Override
public boolean isImmediate() {
return parent.isImmediate();
}
@Override
public void addTile(Vec3i location, BlockFace face, TileData tile) {
parent.addTile(location, face, tile);
}
@Override
public void removeTile(Vec3i location, BlockFace face, int tag) {
parent.removeTile(location, face, tag);
}
@Override
public void addEntity(EntityData entity) {
parent.addEntity(entity);
}
@Override
public void removeEntity(long entityId) {
parent.removeEntity(entityId);
}
@Override
public <SE extends StatefulObject & EntityGeneric> void changeEntity(SE entity, StateChange<SE> change) {
parent.changeEntity(entity, change);
}
@Override
public void advanceTime(float change) {
parent.advanceTime(change);
}
@Override
public float getTime() {
return parent.getTime();
}
@Override
public GravityModel getGravityModel() {
return parent.getGravityModel();
}
@Override
public BlockData getBlock(Vec3i location) {
return parent.getBlock(location);
}
@Override
public boolean isLocationLoaded(Vec3i location) {
return parent.isLocationLoaded(location);
}
@Override
public TileData getTile(Vec3i location, BlockFace face, int layer) {
return parent.getTile(location, face, layer);
}
@Override
public TileData getTileByTag(Vec3i location, BlockFace face, int tag) {
return parent.getTileByTag(location, face, tag);
}
@Override
public boolean hasTile(Vec3i location, BlockFace face, int layer) {
return parent.hasTile(location, face, layer);
}
@Override
public boolean isTagValid(Vec3i location, BlockFace face, int tag) {
return parent.isTagValid(location, face, tag);
}
@Override
public int getTileCount(Vec3i location, BlockFace face) {
return parent.getTileCount(location, face);
}
@Override
public Collection<EntityData> getEntities() {
return parent.getEntities();
}
@Override
public EntityData getEntity(long entityId) {
return parent.getEntity(entityId);
}
@Override
public ServerBlockContext push(Vec3i location) {
return parent.push(location);
}
@Override
public ServerTileStackContext push(Vec3i location, RelFace face) {
return parent.push(location, face);
}
@Override
public ServerTileContext push(Vec3i location, RelFace face, int layer) {
return parent.push(location, face, layer);
}
@Override
public Server getServer() {
return parent.getServer();
}
@Override
public Random getRandom() {
return parent.getRandom();
}
@Override
public double getTickLength() {
return parent.getTickLength();
}
@Override
public ServerTileContext.Logic logic() {
return logic;
}
}