diff --git a/event-loop/TODO b/event-loop/TODO
deleted file mode 100644
index 373999f..0000000
--- a/event-loop/TODO
+++ /dev/null
@@ -1,7 +0,0 @@
-- Система иерархических блокировок ресурсов (чанки в мире)
- - Нужно что-то делать с подгрузкой отсутсвующих чанков для таких блокировок
-- Возможность вызвать событие из EventHandler
-- Performance Monitor
-- Возможная проблема с переполнением очереди при спаме пакетами от игрока
-- Добавить поля с замками для ресурсов (Player, World, Chunk)
-- Time Scheduler
\ No newline at end of file
diff --git a/event-loop/build.gradle b/event-loop/build.gradle
deleted file mode 100644
index 0a1c7d0..0000000
--- a/event-loop/build.gradle
+++ /dev/null
@@ -1,15 +0,0 @@
-group 'mc'
-version '1.0-SNAPSHOT'
-
-dependencies {
- /* Core */
- compile_excludeCopy project(':core')
-
- testCompile group: 'org.slf4j', name: 'slf4j-simple', version: '1.6.1'
- testCompile group: 'com.carrotsearch', name: 'junit-benchmarks', version: '0.7.0'
-}
-
-
-test {
- exclude "ru/core/events/*Benchmark.class"
-}
\ No newline at end of file
diff --git a/event-loop/src/main/java/mc/core/events/EventPipelineTask.java b/event-loop/src/main/java/mc/core/events/EventPipelineTask.java
deleted file mode 100644
index f79634f..0000000
--- a/event-loop/src/main/java/mc/core/events/EventPipelineTask.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package mc.core.events;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-import mc.core.events.api.EventQueueOwner;
-import mc.core.events.api.LockableResource;
-import mc.core.events.runner.lock.LockObserveList;
-import mc.core.events.runner.ResourceAwareExecutorService;
-import mc.core.events.runner.ResourceAwareRunnable;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.List;
-
-/**
- * Holds processing pipeline for every event
- * that enters {@link FullAsyncEventLoop}.
- *
- * Ensures that EventHandlers will never be called in a wrong
- * order by feeding only one task at a time to the {@link ResourceAwareExecutorService}
- */
-@RequiredArgsConstructor
-@Getter
-@Slf4j
-public class EventPipelineTask {
- private final ResourceAwareExecutorService service;
- private final List handlers;
- private final FullAsyncEventLoop manager;
- private final Event event;
- private final EventQueueOwner owner;
- private int currentIndex = 0;
- @Setter
- private PipelineState state = PipelineState.IDLE;
-
- public void next() {
- if (updatePipelineState()) return;
-
- RegisteredEventHandler handler = handlers.get(currentIndex);
- // If event has been already cancelled and current handler
- // ignores cancelled events
- if (event.isCanceled() && handler.isIgnoreCancelled()) {
- // Just skip current event handler
- currentIndex++;
- next();
- } else {
- feedTask(handler);
- }
- }
-
- /**
- * Update current pipeline status
- *
- * @return true if pipeline has been completed
- */
- private boolean updatePipelineState() {
- if (state == PipelineState.IDLE) {
- state = PipelineState.WORKING;
- }
- if (currentIndex >= handlers.size() && state == PipelineState.WORKING) {
- state = PipelineState.FINISHED;
- manager.update(owner);
- return true;
- }
-
- if (state == PipelineState.FINISHED) {
- throw new IllegalStateException("Attempted to call next step on a FINISHED pipeline");
- }
- return false;
- }
-
- private void feedTask(RegisteredEventHandler handler) {
- LockObserveList locks = getLocks(handler);
- service.addTask(new ResourceAwareRunnable() {
- @Override
- public void run() {
- try {
- handler.getMethod().invoke(handler.getObject(), event);
- } catch (IllegalAccessException | InvocationTargetException e) {
- log.error("Unable to dispatch event " + event.getClass().getSimpleName() + " to handler " + event.getClass().getName(), e);
- }
- }
-
- @Override
- public void after() {
- currentIndex++;
- next();
- }
-
- @Override
- public LockObserveList getLocks() {
- return locks;
- }
- });
- }
-
- private LockObserveList getLocks(RegisteredEventHandler handler) {
- LockObserveList locks = new LockObserveList();
-
- if (handler.isPluginSynchronize())
- locks.add(manager.getResourceManager().getPluginLock(handler.getPlugin()));
-
- for (LockableResource resource : handler.getLock()) {
- locks.addAll(manager.getResourceManager().getAnnotationLocks(resource, event));
- }
-
- return locks;
- }
-
- public enum PipelineState {
- IDLE, WORKING, FINISHED
- }
-}
diff --git a/event-loop/src/main/java/mc/core/events/FullAsyncEventLoop.java b/event-loop/src/main/java/mc/core/events/FullAsyncEventLoop.java
deleted file mode 100644
index ec8fa85..0000000
--- a/event-loop/src/main/java/mc/core/events/FullAsyncEventLoop.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package mc.core.events;
-
-import lombok.Getter;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-import mc.core.events.api.EventHandler;
-import mc.core.events.api.EventQueueOwner;
-import mc.core.events.api.Plugin;
-import mc.core.events.runner.ResourceAwareExecutorService;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Event loop core. Manages event handler registration process,
- * maintains event queues.
- *
- * This event loop guarantees that events, assigned to the {@link EventQueueOwner}
- * will be handler in order of scheduling
- */
-@Slf4j
-public class FullAsyncEventLoop {
- // Item leaves this queue only when EventPipeline is fully executed
- private Map> eventQueue = new ConcurrentHashMap<>();
- private Map, List> registeredHandlers = new HashMap<>();
- @SuppressWarnings("SpringJavaAutowiredMembersInspection")
- @Autowired
- @Setter
- private ResourceAwareExecutorService resourceAwareExecutorService;
- @Getter
- private SharedResourceManager resourceManager = new SharedResourceManager();
-
- public void addEventHandler(Plugin plugin, Object object) {
- Map candidates = getEventHandlerCandidates(object);
-
- for (Map.Entry pair : candidates.entrySet()) {
- @SuppressWarnings("unchecked") Class extends Event> eventType = (Class extends Event>) pair.getKey().getParameterTypes()[0];
- List handlers = this.registeredHandlers.computeIfAbsent(eventType, e -> new ArrayList<>());
- handlers.add(new RegisteredEventHandler(plugin, object, pair.getKey(), pair.getValue().lock(), pair.getValue().pluginSynchronize(), pair.getValue().priority().getValue(), pair.getValue().ignoreCancelled()));
- handlers.sort(Comparator.comparingInt(RegisteredEventHandler::getPriority));
- }
- }
-
- public List getPipelineForEvent(Event event) {
- return registeredHandlers.get(event.getClass());
- }
-
- private Map getEventHandlerCandidates(Object object) {
- Map candidates;
- candidates = new HashMap<>();
- for (Method method : object.getClass().getDeclaredMethods()) {
- EventHandler annotation = method.getAnnotation(EventHandler.class);
- if (annotation == null)
- continue;
-
- if (!Modifier.isPublic(method.getModifiers())) {
- log.error("Unable to register {} as an EventHandler. Method must have a 'public' access modifier.", method.toString());
- continue;
-
- }
-
- if (method.getParameterCount() != 1) {
- log.error("Unable to register {} as an EventHandler. Method must have exactly one argument.", method.toString());
- continue;
- }
-
- Class> firstParamType = method.getParameterTypes()[0];
- if (!Event.class.isAssignableFrom(firstParamType)) {
- log.error("Unable to register {} as an EventHandler. First parameter type must implement 'Event' interface.", method.toString());
- continue;
- }
-
- method.setAccessible(true);
- candidates.put(method, annotation);
- }
- return candidates;
- }
-
- public void asyncFireEvent(EventQueueOwner owner, Event event) {
- List handlers = getPipelineForEvent(event);
- if (handlers == null)
- return;
-
- Queue queue = eventQueue.computeIfAbsent(owner, s -> new ArrayDeque<>());
- queue.add(new EventPipelineTask(resourceAwareExecutorService, handlers, this, event, owner));
- update(owner);
- }
-
- /**
- * Updates queue state for a given owner:
- *
- * - Removes first element of a queue if it is marked as FINISHED
- * - Starts executing first pipeline from the queue if it is marked with IDLE
- *
- * @param owner queue owner
- */
- public synchronized void update(EventQueueOwner owner) {
- if (!eventQueue.containsKey(owner)) {
- log.warn("Unable to update pipeline executor: unable to find queue");
- return;
- }
- Queue queue = eventQueue.get(owner);
- if (queue.isEmpty()) {
- log.warn("Unable to update pipeline executor: queue is empty");
- return;
- }
-
- if (queue.peek().getState() == EventPipelineTask.PipelineState.FINISHED) {
- queue.poll();
- }
-
- EventPipelineTask pipeline;
- if ((pipeline = queue.peek()) != null
- && pipeline.getState() == EventPipelineTask.PipelineState.IDLE) {
- pipeline.next();
- }
- }
-}
diff --git a/event-loop/src/main/java/mc/core/events/RegisteredEventHandler.java b/event-loop/src/main/java/mc/core/events/RegisteredEventHandler.java
deleted file mode 100644
index f0333f7..0000000
--- a/event-loop/src/main/java/mc/core/events/RegisteredEventHandler.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package mc.core.events;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import mc.core.events.api.LockableResource;
-import mc.core.events.api.Plugin;
-
-import java.lang.reflect.Method;
-
-/**
- * Holds all the information necessary to register an
- * event handler in an event loop
- */
-@RequiredArgsConstructor
-@Getter
-public class RegisteredEventHandler {
- private final Plugin plugin;
- private final Object object;
- private final Method method;
- private final LockableResource[] lock;
- private final boolean pluginSynchronize;
- private final int priority;
- private final boolean ignoreCancelled;
-}
diff --git a/event-loop/src/main/java/mc/core/events/SharedResourceManager.java b/event-loop/src/main/java/mc/core/events/SharedResourceManager.java
deleted file mode 100644
index ad9f55e..0000000
--- a/event-loop/src/main/java/mc/core/events/SharedResourceManager.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package mc.core.events;
-
-import lombok.extern.slf4j.Slf4j;
-import mc.core.Location;
-import mc.core.events.api.LockableResource;
-import mc.core.events.api.Plugin;
-import mc.core.events.api.interfaces.LocationProvidingEvent;
-import mc.core.events.api.interfaces.PlayerProvidingEvent;
-import mc.core.events.api.interfaces.WorldProvidingEvent;
-import mc.core.events.runner.lock.PoorMansLock;
-import mc.core.player.Player;
-import mc.core.world.World;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
-
-@Slf4j
-public class SharedResourceManager {
- private Map pluginLocks = new ConcurrentHashMap<>();
- // TODO: Memory leak HERE. Fix with introducing field to Player class
- private Map playerLocks = new ConcurrentHashMap<>();
- // TODO: Memory leak HERE. Fix with introducing field to World class
- private Map worldLocks = new ConcurrentHashMap<>();
-
- public PoorMansLock getPluginLock(Plugin plugin) {
- return pluginLocks.computeIfAbsent(plugin, s -> new PoorMansLock());
- }
-
- public PoorMansLock getPlayerLock(Player player) {
- return playerLocks.computeIfAbsent(player, s -> new PoorMansLock());
- }
-
- public PoorMansLock getWorldLock(World world) {
- return worldLocks.computeIfAbsent(world, s -> new PoorMansLock());
- }
-
- private T require(LockableResource resource, Event event, Class inter) {
- if (inter.isInstance(event)) {
- //noinspection unchecked
- return (T) event;
- } else
- throw new IllegalArgumentException("Unable to lock " + resource + " while attempting to process event. Event " + event.getClass().getSimpleName() + " must implement " + inter);
- }
-
- public Collection getAnnotationLocks(LockableResource resource, Event event) {
- switch (resource) {
- case PLAYER:
- return require(resource, event, PlayerProvidingEvent.class).getAssociatedPlayers().stream().map(this::getPlayerLock).collect(Collectors.toList());
- case PLAYER_WORLD:
- return require(resource, event, PlayerProvidingEvent.class).getAssociatedPlayers().stream().map(s -> s.getLocation().getWorld()).map(this::getWorldLock).collect(Collectors.toList());
- case EVENT_LOCATION_WORLD:
- return require(resource, event, LocationProvidingEvent.class).getAssociatedLocations().stream().map(Location::getWorld).map(this::getWorldLock).collect(Collectors.toList());
- case EVENT_WORLD:
- return require(resource, event, WorldProvidingEvent.class).getAssociatedWorlds().stream().map(this::getWorldLock).collect(Collectors.toList());
- default:
- log.warn("Unable to find action for " + resource + " resource definition.");
- return Collections.emptyList();
- }
- }
-
-}
diff --git a/event-loop/src/main/java/mc/core/events/api/EventHandler.java b/event-loop/src/main/java/mc/core/events/api/EventHandler.java
deleted file mode 100644
index dbf255d..0000000
--- a/event-loop/src/main/java/mc/core/events/api/EventHandler.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package mc.core.events.api;
-
-import java.lang.annotation.*;
-
-@Documented
-@Target(ElementType.METHOD)
-@Inherited
-@Retention(RetentionPolicy.RUNTIME)
-public @interface EventHandler {
- EventPriority priority() default EventPriority.NORMAL;
-
- boolean ignoreCancelled() default false;
-
- boolean pluginSynchronize() default true;
-
- LockableResource[] lock() default {};
-}
diff --git a/event-loop/src/main/java/mc/core/events/api/EventPriority.java b/event-loop/src/main/java/mc/core/events/api/EventPriority.java
deleted file mode 100644
index 0c6fdce..0000000
--- a/event-loop/src/main/java/mc/core/events/api/EventPriority.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package mc.core.events.api;
-
-import lombok.Getter;
-
-public enum EventPriority {
- LOWEST(0),
- LOW(1),
- NORMAL(2),
- HIGH(3),
- HIGHEST(4),
- MONITOR(5);
-
- @Getter
- private int value;
-
- EventPriority(int value) {
- this.value = value;
- }
-}
diff --git a/event-loop/src/main/java/mc/core/events/api/EventQueueOwner.java b/event-loop/src/main/java/mc/core/events/api/EventQueueOwner.java
deleted file mode 100644
index 49f4fd4..0000000
--- a/event-loop/src/main/java/mc/core/events/api/EventQueueOwner.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package mc.core.events.api;
-
-public interface EventQueueOwner {
-}
diff --git a/event-loop/src/main/java/mc/core/events/api/LockableResource.java b/event-loop/src/main/java/mc/core/events/api/LockableResource.java
deleted file mode 100644
index 5b86b0a..0000000
--- a/event-loop/src/main/java/mc/core/events/api/LockableResource.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package mc.core.events.api;
-
-public enum LockableResource {
- PLAYER,
- PLAYER_WORLD,
- EVENT_LOCATION_WORLD,
- EVENT_WORLD
-
- // TODO: Add entity-related constants
-}
diff --git a/event-loop/src/main/java/mc/core/events/api/Plugin.java b/event-loop/src/main/java/mc/core/events/api/Plugin.java
deleted file mode 100644
index 040ab60..0000000
--- a/event-loop/src/main/java/mc/core/events/api/Plugin.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package mc.core.events.api;
-
-public interface Plugin {
-}
diff --git a/event-loop/src/main/java/mc/core/events/api/interfaces/LocationProvidingEvent.java b/event-loop/src/main/java/mc/core/events/api/interfaces/LocationProvidingEvent.java
deleted file mode 100644
index bec7040..0000000
--- a/event-loop/src/main/java/mc/core/events/api/interfaces/LocationProvidingEvent.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package mc.core.events.api.interfaces;
-
-import mc.core.Location;
-
-import java.util.Collection;
-
-public interface LocationProvidingEvent {
- Collection getAssociatedLocations();
-}
diff --git a/event-loop/src/main/java/mc/core/events/api/interfaces/PlayerProvidingEvent.java b/event-loop/src/main/java/mc/core/events/api/interfaces/PlayerProvidingEvent.java
deleted file mode 100644
index d05af39..0000000
--- a/event-loop/src/main/java/mc/core/events/api/interfaces/PlayerProvidingEvent.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package mc.core.events.api.interfaces;
-
-import mc.core.Location;
-import mc.core.player.Player;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-public interface PlayerProvidingEvent extends LocationProvidingEvent {
- List getAssociatedPlayers();
-
- @Override
- default Collection getAssociatedLocations() {
- List players = getAssociatedPlayers();
- if (players.size() == 1)
- return Collections.singletonList(players.get(0).getLocation());
- else
- throw new RuntimeException("This method is not implemented.");
- }
-}
diff --git a/event-loop/src/main/java/mc/core/events/api/interfaces/WorldProvidingEvent.java b/event-loop/src/main/java/mc/core/events/api/interfaces/WorldProvidingEvent.java
deleted file mode 100644
index 9f561e5..0000000
--- a/event-loop/src/main/java/mc/core/events/api/interfaces/WorldProvidingEvent.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package mc.core.events.api.interfaces;
-
-import mc.core.world.World;
-
-import java.util.Collection;
-
-public interface WorldProvidingEvent {
- Collection getAssociatedWorlds();
-
-}
diff --git a/event-loop/src/main/java/mc/core/events/api/samples/BlockBreakEvent.java b/event-loop/src/main/java/mc/core/events/api/samples/BlockBreakEvent.java
deleted file mode 100644
index a515022..0000000
--- a/event-loop/src/main/java/mc/core/events/api/samples/BlockBreakEvent.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package mc.core.events.api.samples;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import mc.core.Location;
-import mc.core.events.EventBase;
-import mc.core.events.api.interfaces.LocationProvidingEvent;
-import mc.core.events.api.interfaces.PlayerProvidingEvent;
-import mc.core.player.Player;
-import mc.core.world.block.Block;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-@RequiredArgsConstructor
-@Getter
-public class BlockBreakEvent extends EventBase implements PlayerProvidingEvent, LocationProvidingEvent {
- private final Player player;
- private final Block block;
-
- @Override
- public List getAssociatedPlayers() {
- return Collections.singletonList(player);
- }
-
- @Override
- public Collection getAssociatedLocations() {
- return Collections.singletonList(block.getLocation());
- }
-}
diff --git a/event-loop/src/main/java/mc/core/events/runner/AllInScheduleStrategy.java b/event-loop/src/main/java/mc/core/events/runner/AllInScheduleStrategy.java
deleted file mode 100644
index ce275bd..0000000
--- a/event-loop/src/main/java/mc/core/events/runner/AllInScheduleStrategy.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package mc.core.events.runner;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * Simple scheduling strategy.
- *
- * We wait until the first task in a queue will be able to acquire all
- * the necessary resources and then we schedule it for execution
- */
-public class AllInScheduleStrategy implements ScheduleStrategy {
- private BlockingQueue globalQueue;
- private ResourceAwareExecutorService resourceAwareExecutorService;
-
- public AllInScheduleStrategy(ResourceAwareExecutorService resourceAwareExecutorService) {
- this.globalQueue = resourceAwareExecutorService.queue;
- this.resourceAwareExecutorService = resourceAwareExecutorService;
- }
-
-
- @Override
- public synchronized ResourceAwareRunnable getTask() throws InterruptedException {
- waitForResourceLockComplete();
-
- // Wait for new task in queue
- ResourceAwareRunnable runnable = globalQueue.take();
- while (!runnable.getLocks().isReady()) {
- CountDownLatch latch = new CountDownLatch(1);
- runnable.getLocks().setCallback(latch::countDown);
- // Prevent situations where dependencies were resolved
- // while we were setting up the callback
- if (runnable.getLocks().isReady())
- continue;
- latch.await();
- }
-
- // Lock execution for the next thread
- // (wait until resources for previous task will be blocked)
- resourceAwareExecutorService.waitForLock.set(true);
- return runnable;
- }
-
- /**
- * Waits until the last scheduled task will lock all the necessary resources.
- *
- * It is required to avoid race-condition when an execution candidate task (first task in a queue)
- * skips lock-await procedure due to the last scheduled task not having locked necessary resources yet.
- *
- * @throws InterruptedException if current thread is interrupted
- */
- private void waitForResourceLockComplete() throws InterruptedException {
- synchronized (resourceAwareExecutorService.waitForLock) {
- while (resourceAwareExecutorService.waitForLock.get()) {
- resourceAwareExecutorService.wait();
- }
- }
- }
-}
diff --git a/event-loop/src/main/java/mc/core/events/runner/ExecutorWorkerThread.java b/event-loop/src/main/java/mc/core/events/runner/ExecutorWorkerThread.java
deleted file mode 100644
index e1e5f7b..0000000
--- a/event-loop/src/main/java/mc/core/events/runner/ExecutorWorkerThread.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package mc.core.events.runner;
-
-/**
- * Worker thread for {@link ResourceAwareExecutorService}.
- *
- * - Awaits for tasks from {@link ScheduleStrategy}
- * - Locks up resources for this task
- * - Notifies {@link ScheduleStrategy} when resource-locking procedure is complete
- * - Executes the runnable in this thread
- * - Unlocks all the resources
- * - Calls {@link ResourceAwareRunnable#after()} callback
- */
-public class ExecutorWorkerThread extends Thread {
- private ResourceAwareExecutorService service;
-
- public ExecutorWorkerThread(String name, ResourceAwareExecutorService service) {
- super(name);
- this.service = service;
- }
-
- @Override
- public void run() {
- while (!isInterrupted() && isAlive()) {
- ResourceAwareRunnable runnable;
- try {
- runnable = service.getStrategy().getTask();
- } catch (InterruptedException e) {
- return;
- }
-
- executeTask(runnable);
- }
- }
-
- void executeTask(ResourceAwareRunnable runnable) {
- runnable.getLocks().lockAll();
- notifyLockingDone();
- try {
- runnable.run();
- } finally {
- runnable.getLocks().unlockAll();
- runnable.getLocks().release();
- }
- runnable.after();
- }
-
- private void notifyLockingDone() {
- synchronized (service.waitForLock) {
- if (service.waitForLock.get()) {
- service.waitForLock.set(false);
- service.waitForLock.notifyAll();
- }
- }
- }
-}
diff --git a/event-loop/src/main/java/mc/core/events/runner/ResourceAwareExecutorService.java b/event-loop/src/main/java/mc/core/events/runner/ResourceAwareExecutorService.java
deleted file mode 100644
index 0ec99ca..0000000
--- a/event-loop/src/main/java/mc/core/events/runner/ResourceAwareExecutorService.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package mc.core.events.runner;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-
-/**
- * Custom implementation of an ExecutorService.
- *
- * Holds a queue of {@link ResourceAwareRunnable} and executes them in a thread pool.
- *
- * Warning! This class doesn't guarantee, that tasks will be executed in any specific order.
- * In fact, it's up to {@link ScheduleStrategy} to decide which task will be scheduled for
- * execution next.
- */
-public class ResourceAwareExecutorService {
- private static final boolean WORKER_INSTANT_EXECUTE = false;
- BlockingQueue queue = new ArrayBlockingQueue<>(100);
- // A synchronize aid, that prevents ScheduleStrategy from returning
- // wrong tasks when executor is late in blocking resources
- final AtomicBoolean waitForLock = new AtomicBoolean(false);
- private ScheduleStrategy strategy = new AllInScheduleStrategy(this);
- private Set executorThreads = new HashSet<>();
- private int threadCount;
-
- public ResourceAwareExecutorService(int threadCount) {
- this.threadCount = threadCount;
- }
-
- public void start() {
- if (executorThreads.size() > 0)
- throw new RuntimeException("This executor service was already started.");
-
- for (int i = 0; i < threadCount; i++) {
- Thread thread = new ExecutorWorkerThread("Event Loop #" + i, this);
- executorThreads.add(thread);
- thread.start();
- }
- }
-
- public void stop() {
- if (executorThreads.size() == 0)
- throw new RuntimeException("This executor service was not initialized yet.");
-
- Iterator iterator = executorThreads.iterator();
- while (iterator.hasNext()) {
- Thread thread = iterator.next();
- thread.interrupt();
- iterator.remove();
- }
- }
-
- public void addTask(ResourceAwareRunnable task) {
- if (WORKER_INSTANT_EXECUTE && Thread.currentThread() instanceof ExecutorWorkerThread) {
- ((ExecutorWorkerThread) Thread.currentThread()).executeTask(task);
- } else
- queue.offer(task);
- }
-
-
- public ScheduleStrategy getStrategy() {
- return strategy;
- }
-
- private class DefaultScheduleStrategy implements ScheduleStrategy {
- public ResourceAwareRunnable getTask() throws InterruptedException {
- return queue.take();
- }
- }
-}
diff --git a/event-loop/src/main/java/mc/core/events/runner/ResourceAwareRunnable.java b/event-loop/src/main/java/mc/core/events/runner/ResourceAwareRunnable.java
deleted file mode 100644
index 6f88476..0000000
--- a/event-loop/src/main/java/mc/core/events/runner/ResourceAwareRunnable.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package mc.core.events.runner;
-
-import mc.core.events.runner.lock.LockObserveList;
-
-public interface ResourceAwareRunnable extends Runnable {
- default LockObserveList getLocks() {
- return LockObserveList.EMPTY_LIST;
- }
-
- default void after() {
-
- }
-}
diff --git a/event-loop/src/main/java/mc/core/events/runner/ScheduleStrategy.java b/event-loop/src/main/java/mc/core/events/runner/ScheduleStrategy.java
deleted file mode 100644
index 10cee55..0000000
--- a/event-loop/src/main/java/mc/core/events/runner/ScheduleStrategy.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package mc.core.events.runner;
-
-public interface ScheduleStrategy {
- ResourceAwareRunnable getTask() throws InterruptedException;
-}
diff --git a/event-loop/src/main/java/mc/core/events/runner/lock/LockObserveList.java b/event-loop/src/main/java/mc/core/events/runner/lock/LockObserveList.java
deleted file mode 100644
index 157d325..0000000
--- a/event-loop/src/main/java/mc/core/events/runner/lock/LockObserveList.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package mc.core.events.runner.lock;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Consumer;
-
-public class LockObserveList implements Consumer {
- public static LockObserveList EMPTY_LIST = new LockObserveList();
- private List locks = new ArrayList<>();
- private Runnable callback;
-
- public void setCallback(Runnable callback) {
- this.callback = callback;
- }
-
- public void add(PoorMansLock lock) {
- locks.add(lock);
- lock.addCallback(this);
- }
-
- public void addAll(Iterable locks) {
- for (PoorMansLock lock : locks)
- add(lock);
- }
-
- public void release() {
- callback = null;
- for (PoorMansLock lock : locks) {
- lock.removeCallback(this);
- }
- locks.clear();
- }
-
- public boolean isReady() {
- for (PoorMansLock lock : locks) {
- if (lock.isLocked())
- return false;
- }
- return true;
- }
-
- public void lockAll() {
- for (PoorMansLock lock : locks)
- lock.lock();
- }
-
- public void unlockAll() {
- for (PoorMansLock lock : locks)
- lock.unlock();
- }
-
- @Override
- public void accept(PoorMansLock lock) {
- if (!lock.isLocked()) {
- if (isReady()) {
- if (callback != null)
- callback.run();
- }
- }
- }
-}
diff --git a/event-loop/src/main/java/mc/core/events/runner/lock/PoorMansLock.java b/event-loop/src/main/java/mc/core/events/runner/lock/PoorMansLock.java
deleted file mode 100644
index ace2edc..0000000
--- a/event-loop/src/main/java/mc/core/events/runner/lock/PoorMansLock.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package mc.core.events.runner.lock;
-
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.function.Consumer;
-
-public class PoorMansLock {
- private Thread owner = null;
- private Set> callbacks = new CopyOnWriteArraySet<>();
-
- public void addCallback(Consumer callback) {
- callbacks.add(callback);
- }
-
- public void removeCallback(Consumer callback) {
- callbacks.remove(callback);
- }
-
-
- public boolean isLocked() {
- return owner != null;
- }
-
- private void triggerUpdate() {
- for (Consumer consumer : callbacks)
- consumer.accept(this);
- }
-
- public synchronized void lock() {
- if(owner == Thread.currentThread())
- return;
-
- if (owner != null) {
- throw new RuntimeException("Unable to lock this resource: already in use");
- }
-
- owner = Thread.currentThread();
- triggerUpdate();
- }
-
- public synchronized void unlock() {
- if (owner == null)
- return;
-
- if (owner != Thread.currentThread()) {
- throw new RuntimeException("Attempt to unlock resource from non-owning thread");
- }
-
- owner = null;
- triggerUpdate();
- }
-}
diff --git a/event-loop/src/main/java/mc/core/timings/ThreadTimings.java b/event-loop/src/main/java/mc/core/timings/ThreadTimings.java
deleted file mode 100644
index 408842b..0000000
--- a/event-loop/src/main/java/mc/core/timings/ThreadTimings.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package mc.core.timings;
-
-import java.util.Stack;
-import java.util.concurrent.atomic.AtomicInteger;
-
-public class ThreadTimings {
- private static AtomicInteger IDS = new AtomicInteger();
- private int threadId;
- private Stack stack = new Stack<>();
-
- public ThreadTimings() {
- this.threadId = IDS.getAndIncrement();
- }
-
- public Stack getStack() {
- return stack;
- }
-
- public int getThreadId() {
- return threadId;
- }
-
- public Timings start() {
- Timings timings = new Timings(this, stack.size());
- getTimingsManager().waitForTimingsInitialize();
- stack.push(timings);
- getTimingsManager().notifyTimings(this, timings, true);
- return timings;
- }
-
- private TimingsManager getTimingsManager() {
- return Timings.getTimingsManager();
- }
-
- public void end(Timings finished) {
- Timings timings = null;
- while (!stack.isEmpty() && timings != finished) {
- getTimingsManager().waitForTimingsInitialize();
- timings = stack.pop();
- if (!timings.hasFinished())
- timings.finish();
- getTimingsManager().notifyTimings(this, timings, false);
- }
- }
-}
diff --git a/event-loop/src/main/java/mc/core/timings/Timings.java b/event-loop/src/main/java/mc/core/timings/Timings.java
deleted file mode 100644
index b9d1252..0000000
--- a/event-loop/src/main/java/mc/core/timings/Timings.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package mc.core.timings;
-
-public class Timings implements AutoCloseable {
- private ThreadTimings threadTimings;
- private long acquireTime;
- @SuppressWarnings("FieldCanBeLocal")
- private long endTime = -1;
- private int id;
-
- public Timings(ThreadTimings threadTimings, int id) {
- this.id = id;
- this.threadTimings = threadTimings;
- this.acquireTime = System.nanoTime();
- }
-
- public static Timings start() {
- return TimingsStaticAccessor.getTimingsManager().getCurrentThreadTimings().start();
- }
-
- public static TimingsManager getTimingsManager() {
- return TimingsStaticAccessor.getTimingsManager();
- }
-
- public int getId() {
- return id;
- }
-
- public long getEndTime() {
- return endTime;
- }
-
- public long getAcquireTime() {
- return acquireTime;
- }
-
- public boolean hasFinished() {
- return endTime != -1;
- }
-
- public void finish() {
- if (hasFinished())
- throw new IllegalStateException("This timing was already finished");
- this.endTime = System.nanoTime();
- }
-
- @Override
- public void close() {
- finish();
- this.threadTimings.end(this);
- }
-}
diff --git a/event-loop/src/main/java/mc/core/timings/TimingsEventType.java b/event-loop/src/main/java/mc/core/timings/TimingsEventType.java
deleted file mode 100644
index 181643a..0000000
--- a/event-loop/src/main/java/mc/core/timings/TimingsEventType.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package mc.core.timings;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-
-@RequiredArgsConstructor
-public enum TimingsEventType {
- TIMINGS_START((short) 0),
- TIMINGS_END((short) 1),
- TIMINGS_FILE_INITIALIZING((short) 2),
- TIMINGS_FILE_INITIALIZED((short) 3),
- TIMINGS_CHANGE_THREAD_OPTIONS((short) 4),
- TIMINGS_FILE_END((short) 5);
-
- @Getter
- private final short id;
-}
\ No newline at end of file
diff --git a/event-loop/src/main/java/mc/core/timings/TimingsManager.java b/event-loop/src/main/java/mc/core/timings/TimingsManager.java
deleted file mode 100644
index 3e8ea66..0000000
--- a/event-loop/src/main/java/mc/core/timings/TimingsManager.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package mc.core.timings;
-
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-import mc.core.timings.io.DefaultWriterFactory;
-import mc.core.timings.io.TimingsWriter;
-import mc.core.timings.io.TimingsWriterFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Map;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.locks.ReentrantLock;
-
-@Slf4j
-public class TimingsManager {
- private final Map threadTimings = new ConcurrentHashMap<>();
- // These variables are essential in Timings thread synchronization
- private final AtomicBoolean waitForFile = new AtomicBoolean(false);
- private TimingsWriter writer;
- private Thread timingsIoThread;
- private CountDownLatch ioThreadStopMutex;
- private BlockingQueue queue;
- private ReentrantLock queueAccessLock = new ReentrantLock();
- // For modularity purposes
- @Autowired
- @Setter
- private TimingsWriterFactory writerFactory = new DefaultWriterFactory();
-
- public TimingsManager() {
- TimingsStaticAccessor.TIMINGS_MANAGER = this;
- }
-
- public void startRecording(File file) {
- synchronized (waitForFile) {
- waitForFile.set(true);
- }
- try {
- writer = writerFactory.newInstance(file);
- writer.writeEvent(0, 0, System.nanoTime(), TimingsEventType.TIMINGS_FILE_INITIALIZING);
- // Synchronize current thread state
- for (Map.Entry pair : threadTimings.entrySet()) {
- writer.writeEvent(pair.getValue().getThreadId(), 0, System.nanoTime(), TimingsEventType.TIMINGS_CHANGE_THREAD_OPTIONS, "name: " + pair.getKey().getName());
- for (Timings timings : pair.getValue().getStack()) {
- writer.writeEvent(pair.getValue().getThreadId(), timings.getId(), timings.getAcquireTime(), TimingsEventType.TIMINGS_START);
- }
- }
- writer.writeEvent(0, 0, System.nanoTime(), TimingsEventType.TIMINGS_FILE_INITIALIZED);
- queue = new ArrayBlockingQueue<>(200);
- ioThreadStopMutex = new CountDownLatch(1);
- timingsIoThread = new Thread() {
- @Override
- public void run() {
- try {
- while (!isInterrupted() && isAlive()) {
- TimingsRecord record;
- try {
- if (queue == null)
- return;
- record = queue.take();
- } catch (InterruptedException e) {
- return;
- }
- record.writeToFile(writer);
- }
- } finally {
- ioThreadStopMutex.countDown();
- }
- }
- };
- timingsIoThread.setName("Timings IO thread");
- timingsIoThread.start();
- } catch (Exception e) {
- log.error("Unable to start timings recording", e);
- }
- synchronized (waitForFile) {
- waitForFile.set(false);
- waitForFile.notifyAll();
- }
- }
-
- public void stopRecording() {
- // Disable write queue
- queueAccessLock.lock();
- queue = null;
- queueAccessLock.unlock();
- // Interrupt thread and wait until in finished writing the last task
- timingsIoThread.interrupt();
- try {
- ioThreadStopMutex.await();
- } catch (InterruptedException e) {
- log.error("Unable to wait until last record would be written to file", e);
- }
- // Write EOF event
- writer.writeEvent(0, 0, System.nanoTime(), TimingsEventType.TIMINGS_FILE_END);
- // Unload file
- try {
- writer.close();
- } catch (IOException e) {
- log.error("Unable to close timings file", e);
- }
- writer = null;
- }
-
- void notifyTimings(ThreadTimings thread, Timings timings, boolean start) {
- if (queue == null)
- return;
- queueAccessLock.lock();
- try {
- if (queue != null)
- queue.offer(
- new TimingsRecord(thread.getThreadId(),
- timings.getId(),
- start ? timings.getAcquireTime() : timings.getEndTime(),
- start ? TimingsEventType.TIMINGS_START : TimingsEventType.TIMINGS_END
- )
- );
- } finally {
- queueAccessLock.unlock();
- }
- }
-
- void waitForTimingsInitialize() {
- synchronized (waitForFile) {
- while (waitForFile.get()) {
- try {
- waitForFile.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
-
- }
-
- public ThreadTimings getCurrentThreadTimings() {
-
- synchronized (this.threadTimings) {
- if (this.threadTimings.containsKey(Thread.currentThread())) {
- return this.threadTimings.get(Thread.currentThread());
- } else {
- ThreadTimings timings = new ThreadTimings();
- this.threadTimings.put(Thread.currentThread(), timings);
- if (queue != null) {
- try {
- writer.writeEvent(timings.getThreadId(), 0, System.nanoTime(), TimingsEventType.TIMINGS_CHANGE_THREAD_OPTIONS, "name: " + Thread.currentThread().getName());
- } catch (NullPointerException ignored) {
- // It means that there the file recording was stopped
- // we don't actually care about it
- }
- }
- return timings;
- }
- }
- }
-}
diff --git a/event-loop/src/main/java/mc/core/timings/TimingsRecord.java b/event-loop/src/main/java/mc/core/timings/TimingsRecord.java
deleted file mode 100644
index 3d3e3f6..0000000
--- a/event-loop/src/main/java/mc/core/timings/TimingsRecord.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package mc.core.timings;
-
-import mc.core.timings.io.TimingsWriter;
-
-class TimingsRecord {
- private int threadId;
- private int stackId;
- private long time;
- private TimingsEventType eventType;
- private String data;
-
- public TimingsRecord(int threadId, int stackId, long time, TimingsEventType eventType) {
- this.threadId = threadId;
- this.stackId = stackId;
- this.time = time;
- this.eventType = eventType;
- }
-
- public TimingsRecord(int threadId, int stackId, long time, TimingsEventType eventType, String data) {
- this.threadId = threadId;
- this.stackId = stackId;
- this.time = time;
- this.eventType = eventType;
- this.data = data;
- }
-
- public void writeToFile(TimingsWriter fileWriter) {
- if (data == null)
- fileWriter.writeEvent(threadId, stackId, time, eventType);
- else
- fileWriter.writeEvent(threadId, stackId, time, eventType, data);
- }
-}
diff --git a/event-loop/src/main/java/mc/core/timings/TimingsStaticAccessor.java b/event-loop/src/main/java/mc/core/timings/TimingsStaticAccessor.java
deleted file mode 100644
index 35d0ed4..0000000
--- a/event-loop/src/main/java/mc/core/timings/TimingsStaticAccessor.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package mc.core.timings;
-
-public class TimingsStaticAccessor {
- static TimingsManager TIMINGS_MANAGER;
-
- public static TimingsManager getTimingsManager() {
- return TIMINGS_MANAGER != null ? TIMINGS_MANAGER : (TIMINGS_MANAGER = new TimingsManager());
- }
-}
diff --git a/event-loop/src/main/java/mc/core/timings/io/DefaultWriterFactory.java b/event-loop/src/main/java/mc/core/timings/io/DefaultWriterFactory.java
deleted file mode 100644
index 192ee03..0000000
--- a/event-loop/src/main/java/mc/core/timings/io/DefaultWriterFactory.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package mc.core.timings.io;
-
-import java.io.File;
-import java.io.IOException;
-
-public class DefaultWriterFactory implements TimingsWriterFactory {
- @Override
- public TimingsWriter newInstance(File file) throws IOException {
- return new TimingsFileWriter(file);
- }
-}
diff --git a/event-loop/src/main/java/mc/core/timings/io/TimingsFileWriter.java b/event-loop/src/main/java/mc/core/timings/io/TimingsFileWriter.java
deleted file mode 100644
index e2b593c..0000000
--- a/event-loop/src/main/java/mc/core/timings/io/TimingsFileWriter.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package mc.core.timings.io;
-
-
-import lombok.extern.slf4j.Slf4j;
-import mc.core.timings.TimingsEventType;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.util.concurrent.locks.ReentrantLock;
-
-@SuppressWarnings("Duplicates")
-@Slf4j
-public class TimingsFileWriter implements TimingsWriter {
- private FileOutputStream fileOutputStream;
- private ObjectOutputStream writer;
- private ReentrantLock lock = new ReentrantLock();
-
- public TimingsFileWriter(File saveFile) throws IOException {
- fileOutputStream = new FileOutputStream(saveFile);
- writer = new ObjectOutputStream(fileOutputStream);
- }
-
- @Override
- public void writeEvent(int threadId, int stackId, long time, TimingsEventType type) {
- lock.lock();
- try {
- writer.writeInt(threadId);
- writer.writeInt(stackId);
- writer.writeLong(time);
- writer.writeShort(type.getId());
- writer.writeBoolean(false);
- } catch (IOException e) {
- log.error("Unable to write timings record", e);
- } finally {
- lock.unlock();
- }
- }
-
- @Override
- public void writeEvent(int threadId, int stackId, long time, TimingsEventType type, String data) {
- lock.lock();
- try {
- writer.writeInt(threadId);
- writer.writeInt(stackId);
- writer.writeLong(time);
- writer.writeShort(type.getId());
- writer.writeBoolean(true);
- writer.writeUTF(data);
- } catch (IOException e) {
- log.error("Unable to write timings record", e);
- } finally {
- lock.unlock();
- }
- }
-
- @Override
- public void close() throws IOException {
- writer.close();
- fileOutputStream.close();
- }
-}
diff --git a/event-loop/src/main/java/mc/core/timings/io/TimingsLogWriter.java b/event-loop/src/main/java/mc/core/timings/io/TimingsLogWriter.java
deleted file mode 100644
index 0fa5fa3..0000000
--- a/event-loop/src/main/java/mc/core/timings/io/TimingsLogWriter.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package mc.core.timings.io;
-
-import lombok.extern.slf4j.Slf4j;
-import mc.core.timings.TimingsEventType;
-
-import java.io.IOException;
-
-@Slf4j
-public class TimingsLogWriter implements TimingsWriter {
- @Override
- public void writeEvent(int threadId, int stackId, long time, TimingsEventType type) {
- log.info("[{}] Thread #{}, Stack #{}: {}", time, threadId, stackId, type.toString());
- }
-
- @Override
- public void writeEvent(int threadId, int stackId, long time, TimingsEventType type, String data) {
- log.info("[{}] Thread #{}, Stack #{}: {} ({})", time, threadId, stackId, type.toString(), data);
- }
-
- @Override
- public void close() throws IOException {
-
- }
-}
diff --git a/event-loop/src/main/java/mc/core/timings/io/TimingsWriter.java b/event-loop/src/main/java/mc/core/timings/io/TimingsWriter.java
deleted file mode 100644
index 640bdd5..0000000
--- a/event-loop/src/main/java/mc/core/timings/io/TimingsWriter.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package mc.core.timings.io;
-
-import mc.core.timings.TimingsEventType;
-
-import java.io.IOException;
-
-public interface TimingsWriter {
- void writeEvent(int threadId, int stackId, long time, TimingsEventType type);
-
- void writeEvent(int threadId, int stackId, long time, TimingsEventType type, String data);
-
- void close() throws IOException;
-}
diff --git a/event-loop/src/main/java/mc/core/timings/io/TimingsWriterFactory.java b/event-loop/src/main/java/mc/core/timings/io/TimingsWriterFactory.java
deleted file mode 100644
index db12e6a..0000000
--- a/event-loop/src/main/java/mc/core/timings/io/TimingsWriterFactory.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package mc.core.timings.io;
-
-import java.io.File;
-import java.io.IOException;
-
-public interface TimingsWriterFactory {
- TimingsWriter newInstance(File file) throws IOException;
-}
diff --git a/event-loop/src/test/java/mc/core/events/EventExecutorTest.java b/event-loop/src/test/java/mc/core/events/EventExecutorTest.java
deleted file mode 100644
index a6c6c14..0000000
--- a/event-loop/src/test/java/mc/core/events/EventExecutorTest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package mc.core.events;
-
-import mc.core.events.runner.ResourceAwareExecutorService;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class EventExecutorTest {
-
- @Test
- public void basicTest() throws InterruptedException {
- AtomicBoolean testVariable = new AtomicBoolean(false);
- CountDownLatch latch = new CountDownLatch(1);
- ResourceAwareExecutorService service = new ResourceAwareExecutorService(1);
- service.start();
- service.addTask(() -> {
- testVariable.set(true);
- latch.countDown();
- });
-
- latch.await(1, TimeUnit.SECONDS);
- service.stop();
- Assert.assertTrue("Scheduled task was not executed", testVariable.get());
-
- }
-}
diff --git a/event-loop/src/test/java/mc/core/events/EventLoopTest.java b/event-loop/src/test/java/mc/core/events/EventLoopTest.java
deleted file mode 100644
index a92e738..0000000
--- a/event-loop/src/test/java/mc/core/events/EventLoopTest.java
+++ /dev/null
@@ -1,169 +0,0 @@
-package mc.core.events;
-
-import mc.core.events.api.EventHandler;
-import mc.core.events.api.EventPriority;
-import mc.core.events.api.EventQueueOwner;
-import mc.core.events.api.Plugin;
-import mc.core.events.runner.ResourceAwareExecutorService;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-@SuppressWarnings("Duplicates")
-public class EventLoopTest {
-
- @Test
- public void basicTest() throws InterruptedException {
- Plugin plugin = new Plugin() {
- };
-
- EventQueueOwner queueOwner = new EventQueueOwner() {
- };
-
-
- CountDownLatch latch = new CountDownLatch(1);
- FullAsyncEventLoop eventLoop = new FullAsyncEventLoop();
- eventLoop.addEventHandler(plugin, new Object() {
- @EventHandler
- public void onLoginEvent(LoginEvent event) {
-
- latch.countDown();
- }
- });
-
- ResourceAwareExecutorService service = new ResourceAwareExecutorService(1);
- service.start();
-
- eventLoop.setResourceAwareExecutorService(service);
- eventLoop.asyncFireEvent(queueOwner, new LoginEvent(null));
-
- latch.await(1, TimeUnit.SECONDS);
- Assert.assertEquals("Event was not called", 0, latch.getCount());
- }
-
- @Test
- public void consecutiveExecutionTest() throws InterruptedException {
- Plugin plugin = new Plugin() {
- };
-
- EventQueueOwner queueOwner = new EventQueueOwner() {
- };
-
-
- CountDownLatch latch = new CountDownLatch(2);
- FullAsyncEventLoop eventLoop = new FullAsyncEventLoop();
- eventLoop.addEventHandler(plugin, new Object() {
- @EventHandler
- public void onLoginEvent(LoginEvent event) {
-
- latch.countDown();
- }
- });
-
- ResourceAwareExecutorService service = new ResourceAwareExecutorService(1);
- service.start();
-
- eventLoop.setResourceAwareExecutorService(service);
-
- eventLoop.asyncFireEvent(queueOwner, new LoginEvent(null));
- eventLoop.asyncFireEvent(queueOwner, new LoginEvent(null));
-
- latch.await(1, TimeUnit.SECONDS);
- Assert.assertEquals("Event was not called", 0, latch.getCount());
- }
-
- @Test
- public void prioritySystemTest() throws InterruptedException {
- Plugin plugin = new Plugin() {
- };
-
- EventQueueOwner queueOwner = new EventQueueOwner() {
- };
-
-
- CountDownLatch latch = new CountDownLatch(3);
- FullAsyncEventLoop eventLoop = new FullAsyncEventLoop();
- List priorities = new ArrayList<>(3);
-
- eventLoop.addEventHandler(plugin, new Object() {
- @EventHandler(priority = EventPriority.NORMAL)
- public void login1(LoginEvent event) {
- priorities.add(0);
- latch.countDown();
- }
-
- @EventHandler(priority = EventPriority.HIGHEST)
- public void login2(LoginEvent event) {
- priorities.add(1);
- latch.countDown();
- }
-
- @EventHandler(priority = EventPriority.LOWEST)
- public void login3(LoginEvent event) {
- priorities.add(2);
- latch.countDown();
- }
- });
-
- ResourceAwareExecutorService service = new ResourceAwareExecutorService(1);
- service.start();
-
- eventLoop.setResourceAwareExecutorService(service);
-
- eventLoop.asyncFireEvent(queueOwner, new LoginEvent(null));
-
- latch.await(1, TimeUnit.SECONDS);
- Assert.assertEquals("Incorrect call sequence", "[2, 0, 1]", priorities.toString());
- }
-
- @Test
- public void ignoreCancelledTest() throws InterruptedException {
- Plugin plugin = new Plugin() {
- };
-
- EventQueueOwner queueOwner = new EventQueueOwner() {
- };
-
-
- CountDownLatch latch = new CountDownLatch(1);
- FullAsyncEventLoop eventLoop = new FullAsyncEventLoop();
- List priorities = new ArrayList<>(2);
-
- eventLoop.addEventHandler(plugin, new Object() {
- @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
- public void login1(LoginEvent event) {
- priorities.add(0);
- event.setCanceled(true);
- }
-
- @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
- public void login2(LoginEvent event) {
- priorities.add(1);
- }
-
- @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
- public void login3(LoginEvent event) {
- priorities.add(2);
- }
-
- @EventHandler(priority = EventPriority.MONITOR)
- public void monitor(LoginEvent event) {
- latch.countDown();
- }
- });
-
- ResourceAwareExecutorService service = new ResourceAwareExecutorService(1);
- service.start();
-
- eventLoop.setResourceAwareExecutorService(service);
-
- eventLoop.asyncFireEvent(queueOwner, new LoginEvent(null));
-
- latch.await(1, TimeUnit.SECONDS);
- Assert.assertEquals("Incorrect call sequence", "[2, 0]", priorities.toString());
- }
-}
diff --git a/event-loop/src/test/java/mc/core/events/LockTest.java b/event-loop/src/test/java/mc/core/events/LockTest.java
deleted file mode 100644
index e1e65a2..0000000
--- a/event-loop/src/test/java/mc/core/events/LockTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package mc.core.events;
-
-import mc.core.events.runner.lock.LockObserveList;
-import mc.core.events.runner.lock.PoorMansLock;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class LockTest {
- @Test
- public void basicTest() throws InterruptedException {
- AtomicBoolean engageCallbackCalled = new AtomicBoolean(false);
- AtomicBoolean disengageCallbackCalled = new AtomicBoolean(false);
-
- PoorMansLock lock = new PoorMansLock();
- lock.addCallback(lock1 -> {
- if (lock1.isLocked())
- engageCallbackCalled.set(true);
- else
- disengageCallbackCalled.set(true);
- });
- lock.lock();
- Assert.assertTrue("Lock is not locked", lock.isLocked());
- Assert.assertTrue("Engage callback was not called", engageCallbackCalled.get());
-
- engageCallbackCalled.set(false);
- try {
- lock.lock();
- Assert.assertFalse("Engage callback was called from attempt to block from the same thread", engageCallbackCalled.get());
- } catch (Exception ex) {
- Assert.fail("Exception fired while attempting to lock from the same thread");
- return;
- }
-
- Assert.assertFalse("Disengage callback was called while not actually disengaging [x1]", disengageCallbackCalled.get());
-
- AtomicBoolean lockExceptionFired = new AtomicBoolean(false);
- AtomicBoolean unlockExceptionFired = new AtomicBoolean(false);
- CountDownLatch latch = new CountDownLatch(1);
- new Thread(() -> {
- try {
- lock.lock();
- } catch (Exception ex) {
- lockExceptionFired.set(true);
- }
- try {
- lock.unlock();
- } catch (Exception ex) {
- unlockExceptionFired.set(true);
- }
- latch.countDown();
- }).start();
-
- latch.await();
- Assert.assertTrue("Exception was not fired on concurrent lock attempt", lockExceptionFired.get());
- Assert.assertTrue("Exception was not fired on non-owner unlock attempt", unlockExceptionFired.get());
- Assert.assertFalse("Disengage callback was called while not actually disengaging [x2]", disengageCallbackCalled.get());
-
- lock.unlock();
- Assert.assertTrue("Disengage callback was on called on lock disengage", disengageCallbackCalled.get());
- }
-
- @Test
- public void observeListTest() {
- PoorMansLock lock1 = new PoorMansLock();
- PoorMansLock lock2 = new PoorMansLock();
-
- LockObserveList list = new LockObserveList();
- list.add(lock1);
- list.add(lock2);
-
- Assert.assertTrue("LockObserveList was no able to correctly identify lock states for unlocked locks", list.isReady());
- lock1.lock();
- Assert.assertFalse("LockObserveList was no able to correctly identify lock states for list with one locked lock", list.isReady());
-
-
- AtomicBoolean listReadyCallbackCalled = new AtomicBoolean(false);
- list.setCallback(() -> listReadyCallbackCalled.set(true));
- lock2.lock();
-
- Assert.assertFalse("Callback was called when another lock got engaged", listReadyCallbackCalled.get());
- lock1.unlock();
- Assert.assertFalse("Callback was called while one lock is still locked", listReadyCallbackCalled.get());
- lock2.unlock();
- Assert.assertTrue("Callback was not called when both locks are actually free", listReadyCallbackCalled.get());
-
- }
-}
diff --git a/event-loop/src/test/java/mc/core/timings/TimingsTest.java b/event-loop/src/test/java/mc/core/timings/TimingsTest.java
deleted file mode 100644
index a3e6200..0000000
--- a/event-loop/src/test/java/mc/core/timings/TimingsTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package mc.core.timings;
-
-import org.junit.Test;
-
-import java.io.File;
-import java.io.IOException;
-
-public class TimingsTest {
- @Test
- public void basicTest() {
- try (Timings timings = Timings.start()) {
- System.out.println("Test code");
- }
- }
-
- @Test
- public void brokenTimingTest() {
- try (Timings timings = Timings.start()) {
- Timings t1 = Timings.start();
- Timings.start();
- System.out.println("Pre Close t1");
- t1.close();
- System.out.println("Finished");
- }
- }
-
- @Test
- public void fileRecording() throws IOException {
- Timings.getTimingsManager().startRecording(new File("test.timings"));
-
- try (Timings t1 = Timings.start()) {
- try {
- Thread.sleep(20);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- try (Timings t2 = Timings.start()) {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- Thread.sleep(5);
-
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
-
- Timings.getTimingsManager().stopRecording();
- }
-}
diff --git a/generated_world/README.MD b/generated_world/README.MD
deleted file mode 100644
index f49eaf7..0000000
--- a/generated_world/README.MD
+++ /dev/null
@@ -1,3 +0,0 @@
-### System properties:
-
-* `worlds.folder` -- folder where worlds will be located
\ No newline at end of file
diff --git a/generated_world/build.gradle b/generated_world/build.gradle
deleted file mode 100644
index 5c7cdc7..0000000
--- a/generated_world/build.gradle
+++ /dev/null
@@ -1,7 +0,0 @@
-group 'mc'
-version '1.0-SNAPSHOT'
-
-dependencies {
- compile_excludeCopy project(':core')
- testCompile group: 'junit', name: 'junit', version: '4.12'
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/WorldConstants.java b/generated_world/src/main/java/mc/world/generated_world/WorldConstants.java
deleted file mode 100644
index cd33fde..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/WorldConstants.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package mc.world.generated_world;
-
-public final class WorldConstants {
-
- public static final boolean DEBUG_ENABLED = true;
-
- public static final String CHUNK_FILE_NAME_TEMPLATE = "chunk_{0}_{1}_{2}.dat";
- public static final String BIOME_FILE_NAME_TEMPLATE = "biomes.dat";
- public static final String WORLD_INFO_FILE_NAME_TEMPLATE = "world.dat";
- public static final String REGION_FILE_NAME_TEMPLATE = "r.{0}.{1}";
-
- public static final int WORLD_MAX_HEIGHT = 256;
- public static final int WORLD_SEA_LEVEL = 64;
- public static final int WORLD_MIN_GENERATION_HEIGHT = 36;
- public static final int WORLD_MAX_GENERATION_HEIGHT = 128;
- public static final int WORLD_REGION_SIZE = 256;
- public static final int WORLD_CHUNK_SIZE = 16;
- public static final int WORLD_MAX_TEMPERATURE = 100;
- public static final int WORLD_MAX_WETNESS = 100;
- public static final int WORLD_BASE_WETNESS = 80;
-
- public static final double WORLD_LAND_SIZE = 63.03;
- public static final double WORLD_LAKE_SIZE = 9.3;
- public static final double WORLD_WET_SEA_PERCENT = 0.8;
- public static final double WORLD_TEMPERATURE_SIZE = 41.0;
- public static final double WORLD_TEMPERATURE_ZONE_SIZE = 2.99;
- public static final double WORLD_TEMPERATURE_HEIGHT_GRAD_SIZE = 1.1;
-
- public static final int LANDFILL_GRASS_SURFACE_THIN = 5;
- public static final double WORLD_ROUGHNESS = 0.35;
-
- private WorldConstants () {}
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkImpl.java b/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkImpl.java
deleted file mode 100644
index 27baadc..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkImpl.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package mc.world.generated_world.chunk;
-
-import lombok.Getter;
-import mc.core.exception.ResourceUnloadedException;
-import mc.core.world.chunk.ChunkSection;
-import mc.core.world.Region;
-import mc.core.world.World;
-import mc.core.world.chunk.Chunk;
-
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-
-import static mc.world.generated_world.WorldConstants.WORLD_CHUNK_SIZE;
-
-public class ChunkImpl implements Chunk {
- @Getter
- private final int x;
- @Getter
- private final int z;
- private Reference regionReference;
- private ChunkSection[] sections = new ChunkSection[WORLD_CHUNK_SIZE];
-
- public ChunkImpl (int x, int z, Region region) {
- this.x = x;
- this.z = z;
- this.regionReference = new WeakReference<>(region);
- }
-
- @Override
- public World getWorld() {
- Region region = getRegion();
- if (region == null) {
- throw new ResourceUnloadedException("Region is unloaded");
- }
- return region.getWorld();
- }
-
- @Override
- public ChunkSection getChunkSection(int height) {
- return sections[height];
- }
-
- @Override
- public ChunkSection setChunkSection(int height, ChunkSection chunkSection) {
- sections[height] = chunkSection;
- return chunkSection;
- }
-
- @Override
- public Region getRegion() {
- if (regionReference == null) {
- return null;
- }
-
- if (regionReference.get() == null) {
- throw new ResourceUnloadedException("Region is unloaded");
- }
-
- return regionReference.get();
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkSectionImpl.java b/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkSectionImpl.java
deleted file mode 100644
index ab10c71..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkSectionImpl.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package mc.world.generated_world.chunk;
-
-import lombok.Getter;
-import mc.core.exception.ResourceUnloadedException;
-import mc.core.world.Biome;
-import mc.core.world.chunk.ChunkSection;
-import mc.core.world.Region;
-import mc.core.world.World;
-import mc.core.world.block.Block;
-import mc.core.world.block.BlockFactory;
-import mc.core.world.block.BlockType;
-
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-
-import static mc.world.generated_world.WorldConstants.WORLD_CHUNK_SIZE;
-
-public class ChunkSectionImpl implements ChunkSection {
- @Getter
- private final int x;
- @Getter
- private final int y;
- @Getter
- private final int z;
- private final Block[][][] blocks = new Block[WORLD_CHUNK_SIZE][WORLD_CHUNK_SIZE][WORLD_CHUNK_SIZE];
- private final transient Reference region;
- private BlockFactory blockFactory = new BlockFactory();
-
- public ChunkSectionImpl(int x, int y, int z, Region region) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.region = new WeakReference<>(region);
- }
-
- @Override
- public int getSkyLight(int x, int y, int z) {
- return 15;
- }
-
- @Override
- public void setSkyLight(int x, int y, int z, int lightLevel) {
-
- }
-
- @Override
- public int getAddition(int x, int y, int z) {
- return 0;
- }
-
- @Override
- public void setAddition(int x, int y, int z, int value) {
-
- }
-
- @Override
- public Biome getBiome(int x, int z) {
- return getRegion().getBiomeAt(x + this.x * WORLD_CHUNK_SIZE,z + this.z * WORLD_CHUNK_SIZE);
- }
-
- @Override
- public void setBiome(int x, int z, Biome biome) {
- getRegion().setBiome(x + this.x * WORLD_CHUNK_SIZE,z + this.z * WORLD_CHUNK_SIZE, biome);
- }
-
- @Override
- public void setBlock(Block block) {
- if (block.getBlockType() == BlockType.AIR) {
- blocks[block.getLocation().getBlockX()][block.getLocation().getBlockY()][block.getLocation().getBlockZ()] = null;
- return;
- }
- blocks[block.getLocation().getBlockX()][block.getLocation().getBlockY()][block.getLocation().getBlockZ()] = block;
- }
-
- @Override
- public Block getBlock(int x, int y, int z) {
- Block block = blocks[x][y][z];
- if (block == null) {
- return blockFactory.create(BlockType.AIR, 0, x, y, z);
- }
- return blocks[x][y][z];
- }
-
- @Override
- public Region getRegion() {
- if (region == null) {
- return null;
- }
- if (region.get() == null) {
- throw new ResourceUnloadedException("Region is unloaded");
- }
- return region.get();
- }
-
- @Override
- public World getWorld() {
- return getRegion().getWorld();
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkSectionProxy.java b/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkSectionProxy.java
deleted file mode 100644
index 0aa6513..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkSectionProxy.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package mc.world.generated_world.chunk;
-
-import mc.core.world.chunk.ChunkSection;
-import mc.core.world.Region;
-import mc.core.world.World;
-import mc.core.world.block.Block;
-import mc.core.world.Biome;
-
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-public class ChunkSectionProxy implements ChunkSection {
- private final ChunkSection chunk;
- private volatile transient long lastUsage = System.currentTimeMillis();
- private final transient ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
-
- public ChunkSectionProxy(ChunkSection chunk) {
- this.chunk = chunk;
- }
-
- public long getLastUsage() {
- synchronized (chunk) {
- return lastUsage;
- }
- }
-
- private final void use () {
- synchronized (chunk) {
- lastUsage = System.currentTimeMillis();
- }
- }
-
- @Override
- public Block getBlock(int x, int y, int z) {
- use();
- return chunk.getBlock(x, y, z);
- }
-
- @Override
- public Region getRegion() {
- return chunk.getRegion();
- }
-
- @Override
- public World getWorld() {
- return chunk.getWorld();
- }
-
- @Override
- public void setBlock(Block block) {
- use();
- chunk.setBlock(block);
- }
-
- @Override
- public int getSkyLight(int x, int y, int z) {
- use();
- return chunk.getSkyLight(x, y, z);
- }
-
- @Override
- public void setSkyLight(int x, int y, int z, int lightLevel) {
- use();
- chunk.setSkyLight(x, y, z, lightLevel);
- }
-
- @Override
- public int getAddition(int x, int y, int z) {
- use();
- return chunk.getAddition(x, y, z);
- }
-
- @Override
- public void setAddition(int x, int y, int z, int value) {
- use();
- chunk.setAddition(x, y, z, value);
- }
-
- @Override
- public Biome getBiome(int x, int z) {
- use();
- return chunk.getBiome(x, z);
- }
-
- @Override
- public void setBiome(int x, int z, Biome biome) {
- use();
- chunk.setBiome(x, z, biome);
- }
-
- @Override
- public int getX() {
- use();
- return chunk.getX();
- }
-
- @Override
- public int getY() {
- use();
- return chunk.getY();
- }
-
- @Override
- public int getZ() {
- use();
- return chunk.getZ();
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/chunk/InMemoryCacheChunkLoader.java b/generated_world/src/main/java/mc/world/generated_world/chunk/InMemoryCacheChunkLoader.java
deleted file mode 100644
index ac6d323..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/chunk/InMemoryCacheChunkLoader.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package mc.world.generated_world.chunk;
-
-import lombok.extern.slf4j.Slf4j;
-import mc.core.serialization.Serializer;
-import mc.core.world.*;
-import mc.core.world.chunk.ChunkLoader;
-import mc.core.world.chunk.ChunkSection;
-import mc.world.generated_world.serialization.ChunkReader;
-import mc.world.generated_world.serialization.RegionReaderWriter;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.Optional;
-
-import static mc.world.generated_world.WorldConstants.*;
-
-@Slf4j
-public class InMemoryCacheChunkLoader implements ChunkLoader {
-
- private final World world;
- private File worldFolder;
- @Autowired
- private WorldGenerator worldGenerator;
- @Autowired
- private ChunkReader chunkReader;
- @Autowired
- private Serializer chunkSerializer;
- @Autowired
- private RegionReaderWriter regionReaderWritter;
-
- public InMemoryCacheChunkLoader(World world) {
- this.world = world;
- String worldPath = System.getProperty("worlds.folder", "worlds");
- worldFolder = new File(worldPath, world.getWorldId().toString());
- if (!worldFolder.exists()) {
- log.info("Created folder for world with uuid '{}'", world.getWorldId());
- worldFolder.mkdirs();
- }
- }
-
- private File getChuckFile(int x, int y, int z) {
- return new File(worldFolder, MessageFormat.format(CHUNK_FILE_NAME_TEMPLATE, x, y, z));
- }
-
- @Override
- public Optional loadChunk(int x, int y, int z) {
- File file = getChuckFile(x, y, z);
- if (!file.exists()) {
- return Optional.empty();
- } else {
- try {
- ChunkSection chunkSection = chunkReader.read(world.getRegion(x / WORLD_CHUNK_SIZE, z / WORLD_CHUNK_SIZE), x, y, z);
- return Optional.of(chunkSection);
- } catch (IOException e) {
- log.error("Error occurred while reading chunk file: " + file.getAbsolutePath(), e);
- return Optional.empty();
- }
- }
- }
-
- @Override
- public ChunkSection loadOrGenerateChunk(int x, int y, int z) {
- int regX = x / WORLD_CHUNK_SIZE;
- int regZ = z / WORLD_CHUNK_SIZE;
- File regionFile = new File(worldFolder, MessageFormat.format(REGION_FILE_NAME_TEMPLATE, regX, regZ));
- Region region;
- ChunkSection chunkSection;
- if (!regionFile.exists()) {
- log.debug("Region [{}, {}] not found. Generating!", regX, regZ);
- regionFile.mkdirs();
- region = worldGenerator.generateRegion(regX, regZ, world);
- try {
- regionReaderWritter.write(region);
- } catch (IOException e) {
- log.error("Error occurred while writting biome file", e);
- }
- saveRegion(region);
- chunkSection = region.getChunkAt(x % WORLD_CHUNK_SIZE, y % WORLD_CHUNK_SIZE, z % WORLD_CHUNK_SIZE);
- } else {
- try {
- region = regionReaderWritter.read(regX, regZ, world);
- chunkSection = chunkReader.read(region, x, y, z);
- } catch (IOException e) {
- log.error("Error occurred while reading chunkSection file", e);
- return null;
- }
- }
- return chunkSection;
- }
-
- private void saveRegion (Region region) {
- File file = new File(worldFolder, MessageFormat.format(REGION_FILE_NAME_TEMPLATE, region.getX(), region.getZ()));
- for (int x = 0; x < WORLD_REGION_SIZE / WORLD_CHUNK_SIZE; x ++) {
- for (int y = 0; y < WORLD_REGION_SIZE / WORLD_CHUNK_SIZE; y ++) {
- for (int z = 0; z < WORLD_REGION_SIZE / WORLD_CHUNK_SIZE; z ++) {
- byte[] chunkBytes = chunkSerializer.serialize(region.getChunkAt(x, y, z));
- File chunkFile = new File(file, MessageFormat.format(CHUNK_FILE_NAME_TEMPLATE, x, y, z));
- try (FileOutputStream writer = new FileOutputStream(chunkFile)) {
- writer.write(chunkBytes);
- } catch (IOException e) {
- log.error("Error occurred while writting chunk to file", e);
- }
- }
- }
- }
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/generator/NoiseGenerator.java b/generated_world/src/main/java/mc/world/generated_world/generator/NoiseGenerator.java
deleted file mode 100644
index b3c84c7..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/generator/NoiseGenerator.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package mc.world.generated_world.generator;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-import static mc.world.generated_world.WorldConstants.WORLD_REGION_SIZE;
-
-@Slf4j
-@RequiredArgsConstructor
-public class NoiseGenerator {
- private int[] perm = new int[WORLD_REGION_SIZE];
- private double[] gradsX = new double[WORLD_REGION_SIZE];
- private double[] gradsY = new double[WORLD_REGION_SIZE];
- private final int seed;
-
- void init() {
- for (int i = 0; i < WORLD_REGION_SIZE; ++i) {
- int other = rand(i) % (i + 1);
- if (i > other)
- perm[i] = perm[other];
- perm[other] = i;
- gradsX[i] = Math.cos(2.0f * Math.PI * i / WORLD_REGION_SIZE);
- gradsY[i] = Math.sin(2.0f * Math.PI * i / WORLD_REGION_SIZE);
- }
- log.debug("Noise generator is initialized");
- }
-
- double f(double t) {
- t = Math.abs(t);
- return t >= 1.0f ? 0.0f : 1.0f -
- (3.0f - 2.0f * t) * t * t;
- }
-
- private double surflet(double x, double y, double gradX, double gradY) {
- return f(x) * f(y) * (gradX * x + gradY * y);
- }
-
- double noise(double x, double y) {
- float result = 0.0f;
- int cellX = (int)(x);
- int cellY = (int)(y);
- int mask = WORLD_REGION_SIZE - 1;
- for (int gridY = cellY; gridY <= cellY + 1; ++gridY)
- for (int gridX = cellX; gridX <= cellX + 1; ++gridX) {
- int hash = perm[(perm[gridX & mask] + gridY) & mask];
- result += surflet(x - gridX, y - gridY,
- gradsX[hash], gradsY[hash]);
- }
- return (result + 1) / 2;
- }
-
- private int rand(int i) {
- int x = (i * i) % WORLD_REGION_SIZE;
- int y = (i + i * x) % WORLD_REGION_SIZE;
- return (int) (Integer.MAX_VALUE * SeedRandomGenerator.random(x, y, seed));
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/generator/SeedBasedWorldGenerator.java b/generated_world/src/main/java/mc/world/generated_world/generator/SeedBasedWorldGenerator.java
deleted file mode 100644
index 5da096f..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/generator/SeedBasedWorldGenerator.java
+++ /dev/null
@@ -1,392 +0,0 @@
-package mc.world.generated_world.generator;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import mc.core.world.block.BlockFactory;
-import mc.core.world.block.BlockType;
-import mc.core.world.*;
-import mc.core.world.chunk.ChunkSection;
-import mc.world.generated_world.region.RegionImpl;
-import mc.world.generated_world.world.CubicWorld;
-import mc.world.generated_world.world.Temperature;
-import mc.world.generated_world.world.Wetness;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.IOException;
-import java.util.UUID;
-
-import static mc.world.generated_world.WorldConstants.*;
-
-@Slf4j
-public class SeedBasedWorldGenerator implements WorldGenerator {
-
- public static void main(String[] args) throws Exception{
- WorldGenerator worldGenerator = new SeedBasedWorldGenerator();
- World world = new CubicWorld(UUID.fromString("00000000-0000-0000-C000-000000000046"), 2626949);
- /*Region region = worldGenerator.generateRegion(0, 0, world);
- region.save(new ChunkSerializer(), new RegionReaderWriter(new File("worlds", world.getWorldId().toString())));
- new WorldReaderWriter(new File("worlds")).writeWorldInfo(world);*/
-
- createBigImage(worldGenerator, world);
- }
-
- private static void createBigImage (WorldGenerator worldGenerator, World world) throws IOException {
- BufferedImage image = new BufferedImage(3 * 256, 3 * 256, BufferedImage.TYPE_INT_RGB);
- for (int x = 0; x <= 2; x ++) {
- for (int z = 0; z <= 2; z ++) {
- worldGenerator.generateRegion(x - 1, z - 1, world);
- addToBigImage(x, z, image);
- }
- }
- ImageIO.write(image, "png", new File("out", "merged.png"));
- }
-
- private static void addToBigImage (int shiftX, int shiftY, BufferedImage image) throws IOException{
- BufferedImage currentImage = ImageIO.read(new File("out/" + (shiftX - 1) + "." + (shiftY - 1), "biomeMap.png"));
- for (int x = 0; x < 256; x ++){
- for (int y = 0; y < 256; y ++){
- int tx = 256 * shiftX + x;
- int ty = 256 * shiftY + y;
- image.setRGB(tx, ty, currentImage.getRGB(x, y));
- }
- }
- }
-
- @Override
- public Region generateRegion(int x, int z, World world) {
- log.info("Generating region [{},{}]...", x, z);
- Region region = new RegionImpl(x, z, world);
- RegionGenerator regionGenerator = new RegionGenerator(world, region);
- regionGenerator.generate();
- log.info("Region [{},{}] is generated", x, z);
- return region;
- }
-
- @RequiredArgsConstructor
- private class RegionGenerator {
- private final World world;
- private final Region region;
- private NoiseGenerator noiseGenerator;
- private BlockFactory blockFactory = new BlockFactory();
-
- private double sigmoid (double x) {
- x -= 0.5;
- x *= 15;
- return 1.0 / (1.0 + Math.exp(-x));
- }
-
- private int convert (int x) {
- return 40960 + x;
- }
-
- private void generate() {
- log.debug("Starting generating region [{}, {}] for world '{}' with seed '{}'", region.getX(), region.getZ(), world.getWorldId(), world.getSeed());
-
- noiseGenerator = new NoiseGenerator(world.getSeed());
- noiseGenerator.init();
-
- int[][] heightMap = new int[WORLD_REGION_SIZE][WORLD_REGION_SIZE];
- int[][] grassMap = new int[WORLD_REGION_SIZE][WORLD_REGION_SIZE];
- int[][] temperatureMap = new int[WORLD_REGION_SIZE][WORLD_REGION_SIZE];
- int[][] wetMap = new int[WORLD_REGION_SIZE][WORLD_REGION_SIZE];
- Biome[][] biomes = new Biome[WORLD_REGION_SIZE][WORLD_REGION_SIZE];
-
- for (int x = 0; x < WORLD_REGION_SIZE; x ++) {
- for (int z = 0; z < WORLD_REGION_SIZE; z ++) {
- int tx = convert(x + region.getX() * WORLD_REGION_SIZE);
- int tz = convert(z + region.getZ() * WORLD_REGION_SIZE);
- double p = sigmoid(noiseGenerator.noise(tx / WORLD_LAND_SIZE, tz / WORLD_LAND_SIZE));
- double r = Math.sqrt(noiseGenerator.noise(tx / WORLD_LAKE_SIZE, tz / WORLD_LAKE_SIZE));
- double h = (WORLD_MAX_GENERATION_HEIGHT - WORLD_MIN_GENERATION_HEIGHT) * Math.min(p * r, 1);
- h = Math.min(WORLD_MAX_GENERATION_HEIGHT, h + WORLD_MIN_GENERATION_HEIGHT);
- heightMap[x][z] = (int)(h);
- grassMap[x][z] = (int) (1 + SeedRandomGenerator.random(tx, tz, world.getSeed()) * (LANDFILL_GRASS_SURFACE_THIN - 1));
- double k = Math.sqrt(noiseGenerator.noise(tx * WORLD_TEMPERATURE_ZONE_SIZE, tz * WORLD_TEMPERATURE_ZONE_SIZE));
- double q = Math.sqrt(noiseGenerator.noise(tx / WORLD_TEMPERATURE_SIZE, tz / WORLD_TEMPERATURE_SIZE));
- temperatureMap[x][z] = (int) (WORLD_MAX_TEMPERATURE * Math.min((k * k + q * q + k * q) * k * q, 0.99));
- if (heightMap[x][z] < WORLD_SEA_LEVEL) {
- biomes[x][z] = Biome.OCEAN;
- wetMap[x][z] = (int) (WORLD_MAX_WETNESS * WORLD_WET_SEA_PERCENT *noiseGenerator.noise(tx, tz));
- } else {
- int th = heightMap[x][z] - WORLD_SEA_LEVEL;
- th = (int) (th * (1 + 1.25 * th / (WORLD_MAX_GENERATION_HEIGHT - WORLD_SEA_LEVEL)));
- heightMap[x][z] = Math.min(WORLD_SEA_LEVEL + th, WORLD_MAX_GENERATION_HEIGHT);
- }
- }
- }
-
- for (int x = 1; x < WORLD_REGION_SIZE - 1; x ++) {
- for (int z = 1; z < WORLD_REGION_SIZE - 1; z++) {
- int mid = 0;
- for (int tx = x - 1; tx <= x + 1; tx ++) {
- for (int tz = z - 1; tz <= z + 1; tz ++) {
- mid += wetMap[tx][tz];
- }
- }
- wetMap[x][z] = mid / 9;
- }
- }
- for (int z = 1; z < WORLD_REGION_SIZE - 1; z++) {
- for (int x = 1; x < WORLD_REGION_SIZE - 1; x ++) {
- int mid = 0;
- for (int tx = x - 1; tx <= x + 1; tx ++) {
- for (int tz = z - 1; tz <= z + 1; tz ++) {
- mid += wetMap[tx][tz];
- }
- }
- wetMap[x][z] = (int) (mid / 9 * (1 + 0.4 * SeedRandomGenerator.random(x, z, world.getSeed())));
- temperatureMap[x][z] = (int) Math.min(Math.max(temperatureMap[x][z] - WORLD_TEMPERATURE_HEIGHT_GRAD_SIZE * SeedRandomGenerator.random(x, z, world.getSeed()) * (heightMap[x][z] - WORLD_SEA_LEVEL), 0), WORLD_MAX_TEMPERATURE);
- }
- }
-
- for (int z = 1; z < WORLD_REGION_SIZE - 1; z++) {
- for (int x = 1; x < WORLD_REGION_SIZE - 1; x ++) {
- wetMap[x][z] = (int) Math.min(WORLD_MAX_WETNESS, WORLD_BASE_WETNESS * noiseGenerator.noise(x / 31d, z / 31d) + wetMap[x][z] * (1 + 0.2 * (SeedRandomGenerator.random(x, z, world.getSeed()))));
- }
- }
-
- smooth(grassMap);
- smooth(temperatureMap);
- smooth(wetMap);
- //smooth(heightMap);
-
- // ================================ DEBUG =======================================
- if (DEBUG_ENABLED) {
- log.debug("Creating debug images");
- File outFile;
- outFile = new File("out", region.getX() + "." + region.getZ());
- outFile.mkdirs();
- BufferedImage tempImg = new BufferedImage(WORLD_REGION_SIZE, WORLD_REGION_SIZE, BufferedImage.TYPE_INT_RGB);
- BufferedImage wetImg = new BufferedImage(WORLD_REGION_SIZE, WORLD_REGION_SIZE, BufferedImage.TYPE_INT_RGB);
- for (int x = 0; x < WORLD_REGION_SIZE; x ++) {
- for (int z = 0; z < WORLD_REGION_SIZE; z ++) {
- Temperature temperature = Temperature.values()[Temperature.values().length * temperatureMap[x][z] / WORLD_MAX_TEMPERATURE];
- Wetness wetness = Wetness.values()[ Wetness.values().length * (Math.min(wetMap[x][z], WORLD_MAX_WETNESS) - 1) / WORLD_MAX_WETNESS];
- biomes[x][z] = selectBiome(temperature, wetness, heightMap[x][z]);
- tempImg.setRGB(x, z, temperature.ordinal() * 0xff / Temperature.values().length);
- wetImg.setRGB(x, z, wetness.ordinal() * 0xff / Wetness.values().length);
- }
- }
-
- try {
- ImageIO.write(tempImg, "png", new File(outFile, "temp_img.png"));
- ImageIO.write(wetImg, "png", new File(outFile, "wet_img.png"));
-
- BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
- BufferedImage subImage = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
- for (int x = 0; x < 256; x++) {
- for (int z = 0; z < 256; z++) {
- int h = heightMap[x][z];
- h = h << 16 | h << 8 | h;
- image.setRGB(x, z, h);
- }
- }
- ImageIO.write(image, "png", new File(outFile, "heightmap.png"));
- image = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
- for (int x = 0; x < 256; x++) {
- for (int z = 0; z < 256; z++) {
- int temp = 0xff * temperatureMap[x][z] / 100;
- temp = temp << 16;
- image.setRGB(x, z, temp);
- subImage.setRGB(x, z, (0xff * (int) (temperatureMap[x][z] / 20) / 5) << 16);
- }
- }
- ImageIO.write(image, "png", new File(outFile, "temperatureMap.png"));
- ImageIO.write(subImage, "png", new File(outFile, "reg_temperatureMap.png"));
- subImage = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
- image = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
- for (int x = 0; x < 256; x++) {
- for (int z = 0; z < 256; z++) {
- int wet = 0xff * wetMap[x][z] / 100;
- image.setRGB(x, z, wet);
- subImage.setRGB(x, z, 0xff * (int) (Wetness.values().length * wetMap[x][z] / (WORLD_MAX_WETNESS)));
- }
- }
- ImageIO.write(image, "png", new File(outFile, "wetMap.png"));
- ImageIO.write(subImage, "png", new File(outFile, "reg_wetMap.png"));
- image = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
- for (int x = 0; x < 256; x++) {
- for (int z = 0; z < 256; z++) {
- image.setRGB(x, z, biomes[x][z].getColor());
- }
- }
- ImageIO.write(image, "png", new File(outFile, "biomeMap.png"));
- } catch (Exception e) {
- log.error("Error occurred while creating debug images", e);
- }
- }
- // ================================ DEBUG FINISH =======================================
-
- log.debug("Creating chunks...");
-
- for (int x = 0; x < WORLD_REGION_SIZE; x ++) {
- for (int z = 0; z < WORLD_REGION_SIZE; z ++) {
- region.setBiome(x, z, biomes[x][z]);
- if (heightMap[x][z] < WORLD_SEA_LEVEL) {
- for (int y = 0; y < WORLD_SEA_LEVEL; y ++) {
- ChunkSection chunk = region.getChunkAt(x / 16, y / 16, z / 16);
- if (y == 0) {
- chunk.setBlock(blockFactory.create(BlockType.BEDROCK, 0, x % 16, y % 16, z % 16));
- continue;
- }
- if (y < heightMap[x][z]) {
- if (y < heightMap[x][z] - grassMap[x][z]) {
- chunk.setBlock(blockFactory.create(BlockType.STONE, 0, x % 16, y % 16, z % 16));
- } else {
- chunk.setBlock(blockFactory.create(BlockType.SAND, 0, x % 16, y % 16, z % 16));
- }
- } else {
- chunk.setBlock(blockFactory.create(BlockType.WATER, 0, x % 16, y % 16, z % 16));
- }
- }
- } else {
- for (int y = 0; y < heightMap[x][z]; y++) {
- ChunkSection chunk = region.getChunkAt(x / 16, y / 16, z / 16);
- if (y == 0) {
- chunk.setBlock(blockFactory.create(BlockType.BEDROCK, 0, x % 16, y % 16, z % 16));
- continue;
- }
- if (y < heightMap[x][z] - grassMap[x][z]) {
- chunk.setBlock(blockFactory.create(BlockType.STONE, 0, x % 16, y % 16, z % 16));
- } else {
- if (biomes[x][z] == Biome.DESERT || biomes[x][z] == Biome.DESERT_HILLS) {
- chunk.setBlock(blockFactory.create(BlockType.SAND, 0, x % 16, y % 16, z % 16));
- } else if (biomes[x][z] == Biome.TAIGA || biomes[x][z] == Biome.TAIGA_HILLS) {
- chunk.setBlock(blockFactory.create(BlockType.DIRT, 0, x % 16, y % 16, z % 16));
- } else {
- chunk.setBlock(blockFactory.create(BlockType.GRASS, 0, x % 16, y % 16, z % 16));
- }
- }
- }
- }
- }
- }
-
- /* TODO
- log.debug("Creating rivers...");
- log.debug("Creating caves...");
- log.debug("Generating ores...");
- log.debug("Creating structures...");
- log.debug("Planting trees...");
- log.debug("Spawning animals...");
- */
- }
-
- private Biome selectBiome (Temperature temperature, Wetness wetness, int height) {
-
- if (wetness == Wetness.WATER || height < WORLD_SEA_LEVEL) {
- if (temperature == Temperature.FROST) {
- if (height < WORLD_SEA_LEVEL) {
- return Biome.FROZEN_OCEAN;
- } else {
- return Biome.ICE_PLAINS;
- }
- } else {
- if (height < WORLD_SEA_LEVEL) {
- if (height < WORLD_MIN_GENERATION_HEIGHT + (WORLD_SEA_LEVEL - WORLD_MIN_GENERATION_HEIGHT) / 2) {
- return Biome.DEEP_OCEAN;
- } else {
- return Biome.OCEAN;
- }
- } else {
- return Biome.SWAMPLAND;
- }
- }
- }
-
- final int HILLS_HEIGHT = WORLD_SEA_LEVEL + (WORLD_MAX_GENERATION_HEIGHT - WORLD_SEA_LEVEL) / 3;
-
- if (temperature == Temperature.FROST) {
- if (wetness == Wetness.DRIEST || wetness == Wetness.DRY) {
- return Biome.COLD_TAIGA;
- } else {
- if (height > HILLS_HEIGHT) {
- return Biome.ICE_MOUNTAINS;
- } else {
- return Biome.ICE_PLAINS;
- }
- }
- }
-
- if (wetness == Wetness.DRIEST) {
- if (temperature == Temperature.COLD || temperature == Temperature.WARM) {
- return Biome.PLAINS;
- } else {
- if (height > HILLS_HEIGHT) {
- return Biome.DESERT_HILLS;
- } else {
- return Biome.DESERT;
- }
- }
- }
-
- if (temperature == Temperature.COLD) {
- if (wetness == Wetness.DRY || wetness == Wetness.WET) {
- if (height > HILLS_HEIGHT) {
- return Biome.TAIGA_HILLS;
- } else {
- return Biome.TAIGA;
- }
- } else {
- return Biome.SWAMPLAND;
- }
- }
-
- if (wetness == Wetness.WETTEST) {
- if (temperature == Temperature.WARM) {
- return Biome.SWAMPLAND;
- } else {
- if (height > HILLS_HEIGHT) {
- return Biome.JUNGLE_HILLS;
- } else {
- return Biome.JUNGLE;
- }
- }
- }
-
- if (wetness == Wetness.WETTER) {
- if (temperature == Temperature.WARM) {
- if (height > HILLS_HEIGHT) {
- return Biome.FOREST_HILLS;
- } else {
- return Biome.FOREST;
- }
- } else {
- return Biome.SAVANNA_PLATO;
- }
- }
-
- if (temperature == Temperature.HOTTEST) {
- return Biome.SAVANNA;
- }
-
- if (wetness == Wetness.WET) {
- if (height > HILLS_HEIGHT) {
- return Biome.FOREST_HILLS;
- } else {
- return Biome.FOREST;
- }
- }
-
- return Biome.PLAINS;
- }
-
- private void smooth (int [][] map) {
- final int[][] original = map.clone();
- for (int y = 1; y < map.length - 1; y ++) {
- for (int x = 1; x < map[0].length - 1; x ++) {
- int mid = 0;
- for (int tx = x - 1; tx <= x + 1; tx ++) {
- for (int ty = y - 1; ty <= y + 1; ty ++) {
- mid += original[tx][ty];
- }
- }
- map[x][y] = mid / 9;
- }
- }
- }
- }
-
-}
\ No newline at end of file
diff --git a/generated_world/src/main/java/mc/world/generated_world/generator/SeedRandomGenerator.java b/generated_world/src/main/java/mc/world/generated_world/generator/SeedRandomGenerator.java
deleted file mode 100644
index c2ff8e7..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/generator/SeedRandomGenerator.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package mc.world.generated_world.generator;
-
-public final class SeedRandomGenerator {
-
- public static double random (int x, int y, int seed) {
- x = Math.abs(x - y) + 1;
- y = Math.abs(y - x) + 1;
- for (int i = 0; i < 20; i ++) {
- int a1 = x % 13;
- int a2 = x % 31;
- int a3 = x % 89;
- int a4 = y % 359;
- int a5 = y % 7;
- int a6 = y % 313;
- int a7 = y % 8461;
- int a8 = y % 105467;
- int a9 = x % 105943;
- y = x + seed;
- x += a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
- }
- return ((x + y) % 100000) / 100000d;
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/region/RegionImpl.java b/generated_world/src/main/java/mc/world/generated_world/region/RegionImpl.java
deleted file mode 100644
index 09c98ea..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/region/RegionImpl.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package mc.world.generated_world.region;
-
-import lombok.Getter;
-import lombok.extern.slf4j.Slf4j;
-import mc.core.exception.ResourceUnloadedException;
-import mc.core.serialization.IRegionReaderWriter;
-import mc.core.serialization.Serializer;
-import mc.core.world.*;
-import mc.core.world.chunk.Chunk;
-import mc.core.world.chunk.ChunkLoader;
-import mc.core.world.chunk.ChunkSection;
-import mc.world.generated_world.chunk.ChunkSectionProxy;
-import mc.world.generated_world.chunk.InMemoryCacheChunkLoader;
-import mc.world.generated_world.chunk.ChunkImpl;
-import mc.world.generated_world.chunk.ChunkSectionImpl;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-import java.text.MessageFormat;
-
-import static mc.world.generated_world.WorldConstants.*;
-
-@Slf4j
-public class RegionImpl implements Region{
- @Getter
- private final int x;
- @Getter
- private final int z;
- private final ChunkSection[][][] chunkSectionProxies = new ChunkSectionProxy[WORLD_REGION_SIZE/WORLD_CHUNK_SIZE][WORLD_REGION_SIZE/WORLD_CHUNK_SIZE][WORLD_REGION_SIZE/WORLD_CHUNK_SIZE];
- private final Biome[][] biomes = new Biome[WORLD_REGION_SIZE][WORLD_REGION_SIZE];
- private final transient Reference world;
- private final Chunk[][] chunks = new Chunk[WORLD_REGION_SIZE/WORLD_CHUNK_SIZE][WORLD_REGION_SIZE/WORLD_CHUNK_SIZE];
- @Autowired
- private ChunkLoader chunkLoader;
-
- public RegionImpl (int x, int z, World world) {
- this.x = x;
- this.z = z;
- this.world = new WeakReference<>(world);
- }
-
- @Override
- public Chunk getChunk(int x, int z) {
- if (x < 0 || z < 0 || x >= 16 || z >= 16) {
- throw new RuntimeException(MessageFormat.format("Invalid chunk coordinates [{0} {1}]", x, z));
- }
-
- Chunk chunk = chunks[x][z];
- if (chunk == null) {
- chunk = new ChunkImpl(x, z, this);
- for (int y = 0; y < WORLD_CHUNK_SIZE; y ++) {
- chunk.setChunkSection(y, getChunkAt(x, y, z));
- }
- }
- return chunk;
- }
-
- @Override
- public void setChunk(int x, int z, Chunk chunk) {
- chunks[x][z] = chunk;
- }
-
- @Override
- public ChunkSection getChunkAt(int x, int y, int z) {
- if (x < 0 || y < 0 || z < 0 || x >= 16 || y >= 16 || z >= 16) {
- throw new RuntimeException(MessageFormat.format("Invalid chunkSection coordinates [{0} {1} {2}]", x, y, z));
- }
- if (chunkLoader == null) {
- chunkLoader = new InMemoryCacheChunkLoader(getWorld());
- }
- ChunkSection chunkSection = chunkSectionProxies[x][y][z];
- if (chunkSection == null) {
- chunkSection = chunkLoader.loadChunk(x + this.x * WORLD_REGION_SIZE, y, this.z * WORLD_REGION_SIZE).orElse(new ChunkSectionImpl(x, y, z, this));
- chunkSectionProxies[x][y][z] = new ChunkSectionProxy(chunkSection);
- }
- return chunkSection;
- }
-
- @Override
- public void setChunk(int x, int y, int z, ChunkSection chunkSection) {
- if (x < 0 || y < 0 || z < 0 || x >= 16 || y >= 16 || z >= 16) {
- throw new RuntimeException(MessageFormat.format("Invalid chunkSection coordinates [{0} {1} {2}]", x, y, z));
- }
- chunkSectionProxies[x][y][z] = new ChunkSectionProxy(chunkSection);
- }
-
- @Override
- public Biome getBiomeAt(int x, int z) {
- if (x < 0 || z < 0 || x >= 256 || z >= 256) {
- throw new RuntimeException(MessageFormat.format("Invalid biome coordinates [{0} {1}]", x, z));
- }
- return biomes[x][z];
- }
-
- @Override
- public void setBiome(int x, int z, Biome biome) {
- if (x < 0 || z < 0 || x >= 256 || z >= 256) {
- throw new RuntimeException(MessageFormat.format("Invalid biome coordinates [{0} {1}]", x, z));
- }
- biomes[x][z] = biome;
- }
-
- @Override
- public World getWorld() {
- if (world == null) {
- return null;
- }
- if (world.get() == null) {
- throw new ResourceUnloadedException("World is unloaded");
- }
- return world.get();
- }
-
- @Override
- public void save(Serializer chunkSerializer, IRegionReaderWriter regionReaderWriter) throws IOException {
- String worldPath = System.getProperty("worlds.folder", "worlds");
- File worldFile = new File(worldPath, getWorld().getWorldId().toString());
- File regionFile = new File(worldFile, MessageFormat.format(REGION_FILE_NAME_TEMPLATE, this.getX(), this.getZ()));
- if (!regionFile.exists()) {
- regionFile.mkdirs();
- }
- regionReaderWriter.write(this);
- for (int x = 0; x < WORLD_CHUNK_SIZE; x ++) {
- for (int z = 0; z < WORLD_CHUNK_SIZE; z ++) {
- for (int y = 0; y < WORLD_CHUNK_SIZE; y++) {
- ChunkSection chunkSection = this.getChunkAt(x, y, z);
- byte[] chunkBytes = chunkSerializer.serialize(chunkSection);
- if (chunkBytes.length > 0) {
- File chunkFile = new File(regionFile, MessageFormat.format(CHUNK_FILE_NAME_TEMPLATE, x, y, z));
- try (FileOutputStream fileOutputStream = new FileOutputStream(chunkFile)) {
- fileOutputStream.write(chunkBytes);
- }
- }
- }
- }
- }
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/serialization/BlockSerializerDeserializer.java b/generated_world/src/main/java/mc/world/generated_world/serialization/BlockSerializerDeserializer.java
deleted file mode 100644
index 8d05e93..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/serialization/BlockSerializerDeserializer.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package mc.world.generated_world.serialization;
-
-import mc.core.world.block.Block;
-import mc.core.world.block.BlockFactory;
-import mc.core.world.block.BlockType;
-import mc.core.serialization.Deserializer;
-import mc.core.serialization.Serializer;
-import mc.core.world.chunk.ChunkSection;
-
-/**
- * Prototype
- */
-public class BlockSerializerDeserializer implements Serializer, Deserializer {
-
- private BlockFactory blockFactory;
- private ChunkSection chunkSection;
-
- public BlockSerializerDeserializer(BlockFactory blockFactory, ChunkSection chunkSection) {
- this.blockFactory = blockFactory;
- this.chunkSection = chunkSection;
- }
-
- @Override
- public Block deserialize(byte[] bytes) {
- int id = bytes[0] + 128;
- int meta = bytes[1] >> 4;
- int x = (bytes[1] & 0xf) + chunkSection.getX() * 16;
- int y = bytes[2] >> 4 + chunkSection.getY() * 16;
- int z = (bytes[2] & 0xf) + chunkSection.getZ() * 16;
- BlockType type = BlockType.values()[id];
- Block block = blockFactory.create(type, meta);
- block.getLocation().setX(x);
- block.getLocation().setY(y);
- block.getLocation().setZ(z);
- return block;
- }
-
- @Override
- public byte[] serialize(Block block) {
- byte[] bytes = new byte[3];
- bytes[0] = (byte) ((block.getId() - 128) & 0xff);
- bytes[1] = (byte) ((block.getMeta() << 4) | (block.getLocation().getBlockX() % 16));
- bytes[2] = (byte) (((block.getLocation().getBlockZ() % 16) << 4) | (block.getLocation().getBlockZ() % 16));
- return bytes;
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/serialization/ChunkReader.java b/generated_world/src/main/java/mc/world/generated_world/serialization/ChunkReader.java
deleted file mode 100644
index 4672954..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/serialization/ChunkReader.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package mc.world.generated_world.serialization;
-
-import mc.core.world.block.Block;
-import mc.core.serialization.Deserializer;
-import mc.core.serialization.IChunkReader;
-import mc.core.world.chunk.ChunkSection;
-import mc.core.world.Region;
-import mc.world.generated_world.chunk.ChunkSectionImpl;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.text.MessageFormat;
-
-import static mc.world.generated_world.WorldConstants.*;
-
-public class ChunkReader implements IChunkReader{
- private final File worldFolder;
- @Autowired
- private Deserializer blockDeserializer;
-
- public ChunkReader (File worldFolder) {
- this.worldFolder = worldFolder;
- }
-
- @Override
- public ChunkSection read (Region region, int x, int y, int z) throws IOException {
- x %= WORLD_REGION_SIZE;
- y %= WORLD_REGION_SIZE;
- z %= WORLD_REGION_SIZE;
- File chunkFile = new File(new File(worldFolder, MessageFormat.format(REGION_FILE_NAME_TEMPLATE, region.getX(), region.getZ())), MessageFormat.format(CHUNK_FILE_NAME_TEMPLATE, x, y, z));
- byte[] chunkBytes = Files.readAllBytes(Paths.get(chunkFile.toURI()));
- int blocks = (chunkBytes.length) / 3;
- ChunkSection chunkSection = new ChunkSectionImpl(x, y, z, region);
- for (int i = 0; i < blocks; i ++) {
- byte[] blockBytes = new byte[3];
- blockBytes[0] = chunkBytes[3 * i];
- blockBytes[1] = chunkBytes[1 + 3 * i];
- blockBytes[2] = chunkBytes[2 + 3 * i];
- Block block = blockDeserializer.deserialize(blockBytes);
- chunkSection.setBlock(block);
- }
- return chunkSection;
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/serialization/ChunkSerializer.java b/generated_world/src/main/java/mc/world/generated_world/serialization/ChunkSerializer.java
deleted file mode 100644
index c636a5a..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/serialization/ChunkSerializer.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package mc.world.generated_world.serialization;
-
-import lombok.extern.slf4j.Slf4j;
-import mc.core.world.block.Block;
-import mc.core.world.block.BlockFactory;
-import mc.core.world.block.BlockType;
-import mc.core.serialization.Serializer;
-import mc.core.world.chunk.ChunkSection;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-import static mc.world.generated_world.WorldConstants.WORLD_CHUNK_SIZE;
-
-@Slf4j
-public class ChunkSerializer implements Serializer {
-
- @Autowired
- private Serializer blockSerializer;
-
- @Override
- public byte[] serialize(ChunkSection chunkSection) {
- Serializer blockSerializer = new BlockSerializerDeserializer(new BlockFactory(), chunkSection);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- Block current;
- for (int x = 0; x < WORLD_CHUNK_SIZE; x ++) {
- for (int y = 0; y < WORLD_CHUNK_SIZE; y ++) {
- for (int z = 0; z < WORLD_CHUNK_SIZE; z ++) {
- current = chunkSection.getBlock(x, y, z);
- if (current != null && current.getBlockType() != BlockType.AIR) {
- try {
- baos.write(blockSerializer.serialize(current));
- } catch (IOException e) {
- log.error("Error occurred while writing serialized block to byte array", e);
- }
- }
- }
- }
- }
- return baos.toByteArray();
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/serialization/RegionReaderWriter.java b/generated_world/src/main/java/mc/world/generated_world/serialization/RegionReaderWriter.java
deleted file mode 100644
index 20595a4..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/serialization/RegionReaderWriter.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package mc.world.generated_world.serialization;
-
-import mc.core.serialization.IRegionReaderWriter;
-import mc.core.world.Biome;
-import mc.core.world.Region;
-import mc.core.world.World;
-import mc.world.generated_world.region.RegionImpl;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.text.MessageFormat;
-
-import static mc.world.generated_world.WorldConstants.*;
-
-public class RegionReaderWriter implements IRegionReaderWriter {
- private final File worldFolder;
-
- public RegionReaderWriter(File worldFolder) {
- this.worldFolder = worldFolder;
- }
-
- @Override
- public Region read (int x, int z, World world) throws IOException{
- File regionFolder = new File(worldFolder, MessageFormat.format(REGION_FILE_NAME_TEMPLATE, x, z));
- File biomesFile = new File(regionFolder, BIOME_FILE_NAME_TEMPLATE);
- byte[] biomesBytes = Files.readAllBytes(Paths.get(biomesFile.toURI()));
- Region region = new RegionImpl(x, z, world);
- for (int tx = 0; tx < WORLD_REGION_SIZE; tx ++) {
- for (int tz = 0; tz < WORLD_REGION_SIZE; tz ++) {
- region.setBiome(tx, tz, Biome.getById(biomesBytes[tx * WORLD_REGION_SIZE + tz]));
- }
- }
- return region;
- }
-
- @Override
- public void write (Region region) throws IOException{
- File regionFolder = new File(worldFolder, MessageFormat.format(REGION_FILE_NAME_TEMPLATE, region.getX(), region.getZ()));
- if (!regionFolder.exists()) {
- regionFolder.mkdirs();
- }
- File biomesFile = new File(regionFolder, BIOME_FILE_NAME_TEMPLATE);
- byte[] biomesBytes = new byte[WORLD_REGION_SIZE * WORLD_REGION_SIZE];
- for (int x = 0; x < WORLD_REGION_SIZE; x ++) {
- for (int z = 0; z < WORLD_REGION_SIZE; z ++) {
- biomesBytes[x * WORLD_REGION_SIZE + z] = (byte) region.getBiomeAt(x, z).getId();
- }
- }
- try (FileOutputStream fos = new FileOutputStream(biomesFile)) {
- fos.write(biomesBytes);
- }
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/serialization/WorldReaderWriter.java b/generated_world/src/main/java/mc/world/generated_world/serialization/WorldReaderWriter.java
deleted file mode 100644
index 9aa127e..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/serialization/WorldReaderWriter.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package mc.world.generated_world.serialization;
-
-import lombok.Data;
-import lombok.extern.slf4j.Slf4j;
-import mc.core.EntityLocation;
-import mc.core.world.World;
-import mc.world.generated_world.world.CubicWorld;
-
-import java.io.*;
-import java.util.UUID;
-
-import static mc.world.generated_world.WorldConstants.WORLD_INFO_FILE_NAME_TEMPLATE;
-
-@Slf4j
-public class WorldReaderWriter {
- private final File worldsFolder;
-
- public WorldReaderWriter(File worldsFolder) {
- this.worldsFolder = worldsFolder;
- }
-
- public World readWorld (UUID uuid) throws IOException {
- World world = null;
- File worldFolder = new File(worldsFolder, uuid.toString());
- if (!worldFolder.exists()) {
- throw new FileNotFoundException("World folder is not exist");
- }
- File worldInfoFile = new File(worldFolder, WORLD_INFO_FILE_NAME_TEMPLATE);
- WorldInfo worldInfo;
- try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(worldInfoFile))) {
- worldInfo = (WorldInfo) ois.readObject();
- } catch (ClassNotFoundException e) {
- log.error("Error occurred while reading world info file", e);
- return null;
- }
- world = new CubicWorld(uuid, worldInfo.getSeed());
- world.setSpawn(worldInfo.getSpawn());
- world.setName(worldInfo.getName());
- return world;
- }
-
- public void writeWorldInfo (World world) throws IOException {
- File worldFolder = new File(worldsFolder, world.getWorldId().toString());
- worldFolder.mkdirs();
- File worldInfoFile = new File(worldFolder, WORLD_INFO_FILE_NAME_TEMPLATE);
- WorldInfo worldInfo = new WorldInfo();
- worldInfo.setName(world.getName());
- worldInfo.setSeed(world.getSeed());
- worldInfo.setSpawn(world.getSpawn());
- try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(worldInfoFile))) {
- oos.writeObject(worldInfo);
- oos.flush();
- }
- }
-
- @Data
- public static class WorldInfo implements Serializable {
- private EntityLocation spawn;
- private String name;
- private int seed;
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/world/CubicWorld.java b/generated_world/src/main/java/mc/world/generated_world/world/CubicWorld.java
deleted file mode 100644
index f33eade..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/world/CubicWorld.java
+++ /dev/null
@@ -1,225 +0,0 @@
-package mc.world.generated_world.world;
-
-import com.flowpowered.nbt.Tag;
-import lombok.Getter;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-import mc.core.Direction;
-import mc.core.EntityLocation;
-import mc.core.world.*;
-import mc.core.world.chunk.ChunkSection;
-import mc.world.generated_world.serialization.RegionReaderWriter;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.io.File;
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.stream.Stream;
-
-import static mc.world.generated_world.WorldConstants.REGION_FILE_NAME_TEMPLATE;
-
-/*
- * NORTH
- *
- * EAST WEST
- *
- * SOUTH
- *
- * + ----> X
- * |
- * |
- * |
- * V Z
- */
-
-@Slf4j
-public class CubicWorld implements World {
- private int pointX = -1;
- private int pointZ = -1;
- private int sizeX = 2;
- private int sizeZ = 2;
- private Region[][] regions = new Region[sizeX][sizeZ];
- private final Lock regionSaveLock = new ReentrantLock();
- @Autowired
- private RegionReaderWriter regionReaderWriter;
- @Autowired
- private WorldGenerator worldGenerator;
- @Setter
- private boolean autoSaveRegionAfterGenerating = true;
- @Getter
- private final UUID worldId;
- private final int seed;
- private volatile EntityLocation spawn;
- private final transient Object spawnLocationLock = new Object();
- private final Map> nbtTagMap = new HashMap<>();
- @Getter@Setter
- private String name;
-
- public CubicWorld(UUID worldId, int seed) {
- this.worldId = worldId;
- this.seed = seed;
- }
-
- public CubicWorld(int seed) {
- this.worldId = UUID.randomUUID();
- this.seed = seed;
- }
-
- public CubicWorld(UUID worldId) {
- this.worldId = worldId;
- this.seed = 0;
- }
-
- public CubicWorld () {
- this.worldId = UUID.randomUUID();
- this.seed = 0;
- }
-
- @Override
- public IWorldType getWorldType() {
- return null; //FIXME
- }
-
- @Override
- public EntityLocation getSpawn() {
- /* FIXME */
- if (spawn == null) {
- log.warn("Spawn is not defined! Set default spawn: [8, 128, 8]");
- setSpawn(new EntityLocation(8d, 128d, 8d, 0f, 0f, this));
- }
- return spawn;
- }
-
- @Override
- public void setSpawn(EntityLocation entityLocation) {
- synchronized (spawnLocationLock) {
- entityLocation.setWorld(this);
- this.spawn = entityLocation;
- }
- }
-
- @Override
- public ChunkSection getChunk(int x, int y, int z) {
- Region region = getRegion(x / 16, z / 16);
- return region.getChunkAt(x % 16, y % 16, z % 16);
- }
-
- @Override
- public void setChunk(int x, int y, int z, ChunkSection chunkSection) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Region getRegion(int x, int z) {
- checkCoordsInCache(x, z);
- Region region;
- if (regions[x - pointX][z - pointZ] == null) {
- File file = new File(new File("worlds", this.getWorldId().toString()), MessageFormat.format(REGION_FILE_NAME_TEMPLATE, x, z));
- if (!file.exists()) {
- region = worldGenerator.generateRegion(x, z, this);
- if (autoSaveRegionAfterGenerating) {
- try {
- regionReaderWriter.write(region);
- } catch (IOException e) {
- log.error("Error occurred while saving region data");
- }
- }
- } else {
- try {
- region = regionReaderWriter.read(x, z, this);
- } catch (IOException e) {
- log.error("Error occurred while loading region");
- region = null;
- }
- }
- setRegion(region.getX(), region.getZ(), region);
- } else {
- region = regions[x - pointX][z - pointZ];
- }
- return region;
- }
-
- @Override
- public void setRegion(int x, int z, Region region) {
- try {
- regionSaveLock.lock();
- regions[x - pointX][z - pointZ] = region;
- } finally {
- regionSaveLock.unlock();
- }
- }
-
- @Override
- public int getSeed() {
- return seed;
- }
-
- @Override
- public Tag> getTag(String name) {
- return nbtTagMap.get(name);
- }
-
- @Override
- public void setTag(Tag> tag) {
- nbtTagMap.put(tag.getName(), tag);
- }
-
- @Override
- public Stream> tagStream() {
- return nbtTagMap.values().stream();
- }
-
- private void checkCoordsInCache (int x, int z) {
- if (x < pointX) {
- addLines(Direction.EAST, pointX - x);
- } else if (x > pointX + sizeX) {
- addLines(Direction.WEST, x - (pointX + sizeX));
- } else if (z < pointZ) {
- addLines(Direction.NORTH, pointZ - z);
- } else if (z > pointZ + sizeZ) {
- addLines(Direction.SOUTH, z - (pointZ + sizeZ));
- }
- }
-
- private void addLines (Direction direction, int amount) {
- int addBeforeX = 0;
- int addAfterX = 0;
- int addBeforeZ = 0;
- int addAfterZ = 0;
- switch (direction) {
- case NORTH:
- addBeforeZ = amount;
- break;
- case EAST:
- addBeforeX = amount;
- break;
- case WEST:
- addAfterX = amount;
- break;
- case SOUTH:
- addAfterZ = amount;
- break;
- }
- try {
- regionSaveLock.lock();
- int tempSizeX = sizeX + addAfterX + addBeforeX;
- int tempSizeZ = sizeZ + addAfterZ + addBeforeZ;
- Region[][] temp = new Region[tempSizeX][tempSizeZ];
- for (int x = 0; x < sizeX; x ++) {
- System.arraycopy(regions[x], 0, temp[x + addBeforeX], addBeforeZ, sizeZ);
- }
-
- this.sizeX = tempSizeX;
- this.sizeZ = tempSizeZ;
- this.pointX = pointX - addBeforeX;
- this.pointZ = pointZ - addBeforeZ;
- } finally {
- regionSaveLock.unlock();
- }
- }
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/world/Temperature.java b/generated_world/src/main/java/mc/world/generated_world/world/Temperature.java
deleted file mode 100644
index 52b48c3..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/world/Temperature.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package mc.world.generated_world.world;
-
-public enum Temperature {
- FROST,
- COLD,
- WARM,
- HOT,
- HOTTEST
-}
diff --git a/generated_world/src/main/java/mc/world/generated_world/world/Wetness.java b/generated_world/src/main/java/mc/world/generated_world/world/Wetness.java
deleted file mode 100644
index a1ed1ce..0000000
--- a/generated_world/src/main/java/mc/world/generated_world/world/Wetness.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package mc.world.generated_world.world;
-
-public enum Wetness {
- DRIEST,
- DRY,
- WET,
- WETTER,
- WETTEST,
- WATER
-}
diff --git a/generated_world/src/main/resources/log4j2.xml b/generated_world/src/main/resources/log4j2.xml
deleted file mode 100644
index 0ea354b..0000000
--- a/generated_world/src/main/resources/log4j2.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/generated_world/src/test/java/mc/world/generated_world/SeedRandomGeneratorTest.java b/generated_world/src/test/java/mc/world/generated_world/SeedRandomGeneratorTest.java
deleted file mode 100644
index 6c5fbe4..0000000
--- a/generated_world/src/test/java/mc/world/generated_world/SeedRandomGeneratorTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package mc.world.generated_world;
-
-import mc.world.generated_world.generator.SeedRandomGenerator;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.io.File;
-
-import static org.junit.Assert.*;
-
-@Ignore
-public class SeedRandomGeneratorTest {
-
- @Test
- public void randomGenSpeed () {
- SeedRandomGenerator.random(0, 0, 0);
- long avg = 0;
- long min = -1;
- long max = 0;
- for (int i = 0; i < 500; i ++) {
- int x = (int) (Math.random() * 10000);
- int y = (int) (Math.random() * 10000);
- int seed = (int) (Math.random() * 10000);
- long time = System.nanoTime();
- SeedRandomGenerator.random(x, y, seed);
- time = System.nanoTime() - time;
- System.out.printf("[%s] \t%.3fms\n", i+1, time/1000d);
- avg += time;
- if (min == -1) {
- min = time;
- } else if (min > time) {
- min = time;
- }
- if (max < time) {
- max = time;
- }
- }
- System.out.println();
- System.out.printf("Average time: %.3fms\n", avg/500000d);
- System.out.printf("Minimum time: %.3fms\n", min/1000d);
- System.out.printf("Maximum time: %.3fms\n", max/1000d);
- assertTrue(avg/500 < 5000);
- }
-
- @Test
- public void randomTest() throws Exception {
- double maxDiff = 0;
- double maxDisp = 0;
- for (int i = 0; i < 100; i ++) {
- double mid = 0;
- double disp = 0;
- int seed = (int) (Math.random() * Integer.MAX_VALUE);
- for (int x = -1000; x < 1000; x++) {
- for (int y = -1000; y < 1000; y++) {
- double rnd = SeedRandomGenerator.random(x, y, seed);
- mid += rnd;
- disp += (rnd - 0.5) * (rnd - 0.5);
- }
- }
- mid = mid/4000000;
- disp = Math.sqrt(disp)/4000000;
- if (maxDiff < Math.abs(mid - 0.5)) {
- maxDiff = Math.abs(mid - 0.5);
- }
- if (maxDisp < disp) {
- maxDisp = disp;
- }
- System.out.printf("Iteration %d.\t mid: %.3f, \tdisp %.6f\n", i + 1, mid, disp);
- assertTrue(Math.abs(mid - 0.5) < 0.15);
- }
- System.out.printf("Max diff: %.3f\n", maxDiff);
- System.out.printf("Max disp: %.6f\n", maxDisp);
-
-
- assertTrue(maxDiff > 0);
- }
-
- @Test
- public void generateImage () throws Exception {
- int h = 500;
- int w = 500;
- BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
-
- int seed = (int) (Math.random() * Integer.MAX_VALUE) / 1024;
- for (int x = 0; x < w; x ++) {
- for (int y = 0; y < h; y ++) {
- image.setRGB(x, y, (int) (0xffffff * SeedRandomGenerator.random(x, y, seed)));
- }
- }
- ImageIO.write(image, "bmp", new File("out", "seed_random.png"));
- }
-
-}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index bc4f7bf..52ad5e4 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -5,5 +5,3 @@ include('flat_world')
include('vanilla_commands')
include('proto_1.12.2') // Protocol 1.12.2
include('proto_1.12.2_netty') // Protocol 1.12.2 (Netty impl.)
-include('generated_world')
-include('event-loop')
\ No newline at end of file