001/*
002 * Trident - A Multithreaded Server Alternative
003 * Copyright 2014 The TridentSDK Team
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package net.tridentsdk.world;
018
019import net.tridentsdk.base.Position;
020import net.tridentsdk.base.Substance;
021
022import javax.annotation.concurrent.NotThreadSafe;
023
024/**
025 * Change large amounts of blocks at one time
026 *
027 * <p>Don't forget to call {@link #commitChanges()} to finish the operation</p>
028 *
029 * <p>An instance of this class can be acquired using
030 * {@link net.tridentsdk.registry.Factory#newMassChange(net.tridentsdk.world.World)}</p>
031 *
032 * <p>Normally, block changes cause changes to immediately be sent to the client
033 * which can be expensive with large amounts of changes being sent at once near a lot of players</p>
034 */
035@NotThreadSafe
036public interface MassChange {
037    /**
038     * Add a change to make at when this change is committed
039     *
040     * @param x  the x of the block to set
041     * @param y  the y of the block to set
042     * @param z  the z of the block to set
043     * @param id the block id to change the block to
044     * @throws java.lang.IllegalStateException if this change has already been committed
045     */
046    void setBlock(int x, int y, int z, int id) throws IllegalStateException;
047
048    /**
049     * Add a change to make at when this change is committed
050     *
051     * @param x         the x of the block to set
052     * @param y         the y of the block to set
053     * @param z         the z of the block to set
054     * @param substance the substance to change the block to
055     * @throws java.lang.IllegalStateException if this change has already been committed
056     */
057    void setBlock(int x, int y, int z, Substance substance) throws IllegalStateException;
058
059    /**
060     * Add a change to make at when this change is committed
061     *
062     * @param x    the x of the block to set
063     * @param y    the y of the block to set
064     * @param z    the z of the block to set
065     * @param id   the block id to change the block to
066     * @param data the data value to give the new block
067     * @throws java.lang.IllegalStateException if this change has already been committed
068     */
069    void setBlock(int x, int y, int z, int id, byte data) throws IllegalStateException;
070
071    /**
072     * Add a change to make at when this change is committed
073     *
074     * @param x         the x of the block to set
075     * @param y         the y of the block to set
076     * @param z         the z of the block to set
077     * @param substance the substance to change the block to
078     * @param data      the data value to give the new block
079     * @throws IllegalStateException
080     */
081    void setBlock(int x, int y, int z, Substance substance, byte data)
082            throws IllegalStateException;
083
084    /**
085     * Add a change to make at when this change is committed
086     *
087     * @param coords the position to set, values will be rounded
088     * @param id     the id to change the block to
089     * @throws IllegalArgumentException if coords are not from the same world as this change
090     * @throws IllegalStateException    if this change has already been committed
091     */
092    void setBlock(Position coords, int id)
093            throws IllegalArgumentException, IllegalStateException;
094
095    /**
096     * Add a change to make at when this change is committed
097     *
098     * @param coords the position to set, values will be rounded
099     * @param id     the id to change the block to
100     * @param data   the data value to change the block to
101     * @throws IllegalArgumentException if coords are not from the same world as this change
102     * @throws IllegalStateException    if this change has already been committed
103     */
104    void setBlock(Position coords, int id, byte data)
105            throws IllegalArgumentException, IllegalStateException;
106
107    /**
108     * Add a change to make at when this change is committed
109     *
110     * @param coords    the position to set, values will be rounded
111     * @param substance the substance to change the block to
112     * @throws IllegalArgumentException if coords are not from the same world as this change
113     * @throws IllegalStateException    if this change has already been committed
114     */
115    void setBlock(Position coords, Substance substance)
116            throws IllegalArgumentException, IllegalStateException;
117
118    /**
119     * Add a change to make at when this change is committed
120     *
121     * @param coords    the position to set, values will be rounded
122     * @param substance the id to change the block to
123     * @param data      the data value to change the block to
124     * @throws IllegalArgumentException if coords are not from the same world as this change
125     * @throws IllegalStateException    if this change has already been committed
126     */
127    void setBlock(Position coords, Substance substance, byte data)
128            throws IllegalArgumentException, IllegalStateException;
129
130    /**
131     * Sends the block changes to the clients and does lighting recalculations
132     *
133     * <p>This instance of MassChange will be rendered useless after this method is called, and should be discarded</p>
134     *
135     * @return Whether or not the changes were successful.
136     * @throws java.lang.IllegalStateException if this change has already been committed
137     */
138    boolean commitChanges() throws IllegalStateException;
139}