mirror of
https://bitbucket.org/projectswg/cucore.git
synced 2026-08-01 01:16:02 -04:00
Fixed concurrency issues in StaticService
This commit is contained in:
@@ -29,9 +29,14 @@ package services.spawn;
|
||||
|
||||
import intents.object.ObjectCreatedIntent;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import resources.Location;
|
||||
import resources.control.Intent;
|
||||
@@ -41,26 +46,26 @@ import resources.objects.building.BuildingObject;
|
||||
import resources.server_info.Log;
|
||||
import resources.server_info.RelationalServerData;
|
||||
import resources.server_info.RelationalServerFactory;
|
||||
import services.objects.ObjectManager;
|
||||
import services.objects.ObjectCreator;
|
||||
|
||||
public class StaticService extends Service {
|
||||
|
||||
private static final String GET_SUPPORTING_SQL = "SELECT spawns.* FROM spawns, types WHERE types.iff = ? AND spawns.iff_type = types.iff_type";
|
||||
|
||||
private final Object databaseMutex;
|
||||
private final ObjectManager objectManager;
|
||||
private final Map<String, SoftReference<List<SpawnedObject>>> spawnableObjects;
|
||||
private RelationalServerData spawnDatabase;
|
||||
private PreparedStatement getSupportingStatement;
|
||||
|
||||
public StaticService(ObjectManager objectManager) {
|
||||
public StaticService() {
|
||||
this.databaseMutex = new Object();
|
||||
this.objectManager = objectManager;
|
||||
|
||||
spawnDatabase = RelationalServerFactory.getServerData("static/spawns.db", "spawns", "types");
|
||||
if (spawnDatabase == null)
|
||||
throw new main.ProjectSWG.CoreException("Unable to load sdb files for StaticService");
|
||||
|
||||
getSupportingStatement = spawnDatabase.prepareStatement(GET_SUPPORTING_SQL);
|
||||
spawnableObjects = new HashMap<>();
|
||||
|
||||
registerForIntent(ObjectCreatedIntent.TYPE);
|
||||
}
|
||||
@@ -76,47 +81,88 @@ public class StaticService extends Service {
|
||||
}
|
||||
|
||||
private void createSupportingObjects(SWGObject object) {
|
||||
List<SpawnedObject> objects = null;
|
||||
synchronized (spawnableObjects) {
|
||||
SoftReference<List<SpawnedObject>> ref = spawnableObjects.get(object.getTemplate());
|
||||
if (ref != null)
|
||||
objects = ref.get();
|
||||
if (objects == null) {
|
||||
objects = fetchFromDatabase(object.getTemplate());
|
||||
spawnableObjects.put(object.getTemplate(), new SoftReference<List<SpawnedObject>>(objects));
|
||||
}
|
||||
}
|
||||
Location world = object.getWorldLocation();
|
||||
for (SpawnedObject spawn : objects) {
|
||||
spawn.createObject(object, world);
|
||||
}
|
||||
}
|
||||
|
||||
private List<SpawnedObject> fetchFromDatabase(String template) {
|
||||
List<SpawnedObject> objects = new ArrayList<>();
|
||||
synchronized (databaseMutex) {
|
||||
try {
|
||||
getSupportingStatement.setString(1, object.getTemplate());
|
||||
getSupportingStatement.setString(1, template);
|
||||
try (ResultSet set = getSupportingStatement.executeQuery()) {
|
||||
Location world = object.getWorldLocation();
|
||||
while (set.next()) {
|
||||
String iff = set.getString("child_iff");
|
||||
String cell = set.getString("cell");
|
||||
double x = set.getDouble("x");
|
||||
double y = set.getDouble("y");
|
||||
double z = set.getDouble("z");
|
||||
double heading = set.getDouble("heading");
|
||||
if (cell.isEmpty()) {
|
||||
createObject(iff, world, x, y, z, heading);
|
||||
} else if (object instanceof BuildingObject) {
|
||||
BuildingObject buio = (BuildingObject) object;
|
||||
createObject(iff, buio.getCellByName(cell), x, y, z, heading);
|
||||
} else {
|
||||
Log.e("StaticService", "Parent object with cell specified is not a BuildingObject!");
|
||||
}
|
||||
objects.add(new SpawnedObject(set));
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
|
||||
private SWGObject createObject(String iff, SWGObject parent, double x, double y, double z, double heading) {
|
||||
if (parent == null)
|
||||
return null;
|
||||
Location loc = new Location(x, y, z, parent.getTerrain());
|
||||
loc.setHeading(heading);
|
||||
return objectManager.createObject(parent, iff, loc, false);
|
||||
}
|
||||
|
||||
private SWGObject createObject(String iff, Location parentLoc, double x, double y, double z, double heading) {
|
||||
Location loc = new Location(x, y, z, parentLoc.getTerrain());
|
||||
loc.setHeading(heading);
|
||||
loc.translateLocation(parentLoc);
|
||||
return objectManager.createObject(iff, loc, false);
|
||||
private static class SpawnedObject {
|
||||
|
||||
private final String iff;
|
||||
private final String cell;
|
||||
private final double x;
|
||||
private final double y;
|
||||
private final double z;
|
||||
private final double heading;
|
||||
|
||||
public SpawnedObject(ResultSet set) throws SQLException {
|
||||
this.iff = set.getString("child_iff");
|
||||
this.cell = set.getString("cell");
|
||||
this.x = set.getDouble("x");
|
||||
this.y = set.getDouble("y");
|
||||
this.z = set.getDouble("z");
|
||||
this.heading = set.getDouble("heading");
|
||||
}
|
||||
|
||||
public void createObject(SWGObject building, Location parentLocation) {
|
||||
if (cell.isEmpty())
|
||||
createObject(parentLocation);
|
||||
else if (building instanceof BuildingObject)
|
||||
createObjectInParent(((BuildingObject) building).getCellByName(cell));
|
||||
else
|
||||
Log.e("StaticService", "Parent object with cell specified is not a BuildingObject!");
|
||||
}
|
||||
|
||||
private SWGObject createObjectInParent(SWGObject parent) {
|
||||
if (parent == null)
|
||||
return null;
|
||||
Location loc = new Location(x, y, z, parent.getTerrain());
|
||||
loc.setHeading(heading);
|
||||
SWGObject obj = ObjectCreator.createObjectFromTemplate(iff);
|
||||
obj.setParent(parent);
|
||||
obj.setLocation(loc);
|
||||
new ObjectCreatedIntent(obj).broadcast();
|
||||
return obj;
|
||||
}
|
||||
|
||||
private SWGObject createObject(Location parentLocation) {
|
||||
Location loc = new Location(x, y, z, parentLocation.getTerrain());
|
||||
loc.setHeading(heading);
|
||||
loc.translateLocation(parentLocation);
|
||||
SWGObject obj = ObjectCreator.createObjectFromTemplate(iff);
|
||||
obj.setLocation(loc);
|
||||
new ObjectCreatedIntent(obj).broadcast();
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user