ai manager work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-05-15 11:33:51 -04:00
parent 2cf14bcdd2
commit 329559bfd7
3 changed files with 39 additions and 2 deletions

View File

@ -1798,6 +1798,8 @@ Slowdown entity tests to prevent VSCode from exploding when running tests
Fix static state caching between tests in visual shader construction Fix static state caching between tests in visual shader construction
Safe executor service creation in non final static contexts Safe executor service creation in non final static contexts
Fix reloading client world repeatedly Fix reloading client world repeatedly
AI manager thread safeing
AI manager better error handling

View File

@ -141,6 +141,17 @@ public class Logger {
} }
} }
/**
* Logs an error message.
* This should be used every time we throw any kind of error in the engine
* @param e The exception to report
*/
public void ERROR(Throwable e){
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG || level == LogLevel.INFO || level == LogLevel.WARNING || level == LogLevel.ERROR){
e.printStackTrace();
}
}
/** /**
* Prints a message at the specified logging level * Prints a message at the specified logging level
* @param level The logging level * @param level The logging level

View File

@ -1,10 +1,12 @@
package electrosphere.server.ai; package electrosphere.server.ai;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;
import electrosphere.data.creature.ai.AITreeData; import electrosphere.data.creature.ai.AITreeData;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
@ -18,6 +20,11 @@ import electrosphere.server.ai.services.TimerService;
*/ */
public class AIManager { public class AIManager {
/**
* Lock for thread-safeing the manager
*/
ReentrantLock lock = new ReentrantLock();
/** /**
* The list of ais * The list of ais
*/ */
@ -69,15 +76,21 @@ public class AIManager {
* Simulates all AIs currently available * Simulates all AIs currently available
*/ */
public void simulate(){ public void simulate(){
lock.lock();
//exec the services //exec the services
this.execServices(); this.execServices();
//simulate each tree //simulate each tree
if(this.isActive()){ if(this.isActive()){
for(AI ai : aiList){ for(AI ai : aiList){
ai.simulate(); try {
ai.simulate();
} catch(Error|Exception e){
LoggerInterface.loggerAI.ERROR(e);
}
} }
} }
lock.unlock();
} }
/** /**
@ -85,6 +98,7 @@ public class AIManager {
* @param isActive true to simulate ai each frame, false otherwise * @param isActive true to simulate ai each frame, false otherwise
*/ */
public void setActive(boolean isActive){ public void setActive(boolean isActive){
lock.lock();
//turn off ai components if deactivating ai //turn off ai components if deactivating ai
if(this.active && !isActive){ if(this.active && !isActive){
for(AI ai : aiList){ for(AI ai : aiList){
@ -93,6 +107,7 @@ public class AIManager {
} }
//actually set //actually set
this.active = isActive; this.active = isActive;
lock.unlock();
} }
/** /**
@ -108,7 +123,10 @@ public class AIManager {
* @return The list of AIs * @return The list of AIs
*/ */
public List<AI> getAIList(){ public List<AI> getAIList(){
return this.aiList; lock.lock();
List<AI> rVal = Collections.unmodifiableList(this.aiList);
lock.unlock();
return rVal;
} }
/** /**
@ -120,11 +138,13 @@ public class AIManager {
if(entity == null){ if(entity == null){
LoggerInterface.loggerEngine.ERROR(new IllegalArgumentException("Entity provided is null!")); LoggerInterface.loggerEngine.ERROR(new IllegalArgumentException("Entity provided is null!"));
} }
lock.lock();
AI ai = AI.constructAI(entity, treeData); AI ai = AI.constructAI(entity, treeData);
aiList.add(ai); aiList.add(ai);
entityAIMap.put(entity,ai); entityAIMap.put(entity,ai);
aiEntityMap.put(ai,entity); aiEntityMap.put(ai,entity);
AI.setAI(entity, ai); AI.setAI(entity, ai);
lock.unlock();
} }
/** /**
@ -132,10 +152,12 @@ public class AIManager {
* @param entity The entity * @param entity The entity
*/ */
public void removeAI(Entity entity){ public void removeAI(Entity entity){
lock.lock();
AI targetAI = entityAIMap.get(entity); AI targetAI = entityAIMap.get(entity);
aiList.remove(targetAI); aiList.remove(targetAI);
aiEntityMap.remove(targetAI); aiEntityMap.remove(targetAI);
entityAIMap.remove(entity); entityAIMap.remove(entity);
lock.unlock();
} }
/** /**
@ -182,9 +204,11 @@ public class AIManager {
* Shuts down the ai manager * Shuts down the ai manager
*/ */
public void shutdown(){ public void shutdown(){
lock.lock();
this.pathfindingService.shutdown(); this.pathfindingService.shutdown();
this.nearbyEntityService.shutdown(); this.nearbyEntityService.shutdown();
this.timerService.shutdown(); this.timerService.shutdown();
lock.unlock();
} }
} }