/* * Copyright 2013 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terasology.world.time; import java.util.concurrent.atomic.AtomicLong; import org.terasology.engine.Time; import org.terasology.entitySystem.entity.EntityManager; import org.terasology.entitySystem.entity.EntityRef; import org.terasology.entitySystem.systems.BaseComponentSystem; import org.terasology.entitySystem.systems.UpdateSubscriberSystem; import org.terasology.registry.In; import org.terasology.world.WorldComponent; /** */ public class WorldTimeImpl extends BaseComponentSystem implements WorldTime, UpdateSubscriberSystem { private static final float WORLD_TIME_MULTIPLIER = 48f; private AtomicLong worldTime = new AtomicLong(0); @In private Time time; @In private EntityManager entityManager; @Override public long getMilliseconds() { return worldTime.get(); } @Override public float getSeconds() { return worldTime.get() / 1000f; } @Override public float getDays() { return worldTime.get() / (float) DAY_LENGTH; } @Override public float getTimeRate() { return WORLD_TIME_MULTIPLIER; } @Override public void setMilliseconds(long newWorldTime) { // TODO: Send network event to update this.worldTime.getAndSet(newWorldTime); } @Override public void setDays(float timeInDays) { setMilliseconds((long) ((double) timeInDays * DAY_LENGTH)); } @Override public void update(float delta) { long deltaMs = time.getGameDeltaInMs(); if (deltaMs > 0) { deltaMs = (long) (deltaMs * WORLD_TIME_MULTIPLIER); long startTime = worldTime.getAndAdd(deltaMs); long endTime = startTime + deltaMs; long startTick = startTime / TICK_EVENT_RATE; long endTick = endTime / TICK_EVENT_RATE; if (startTick != endTick) { long tick = endTime - endTime % TICK_EVENT_RATE; getWorldEntity().send(new WorldTimeEvent(tick)); } // TODO: consider sending a DailyTick (independent from solar events such as midnight) } } private EntityRef getWorldEntity() { for (EntityRef entity : entityManager.getEntitiesWith(WorldComponent.class)) { return entity; } return EntityRef.NULL; } }