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.meta.block;
018
019import net.tridentsdk.meta.component.Meta;
020
021import javax.annotation.concurrent.ThreadSafe;
022
023/**
024 * Represents a {@link Meta} object which is possessed by blocks
025 *
026 * @author The TridentSDK Team
027 * @since 0.4-alpha
028 */
029@ThreadSafe
030public interface BlockMeta<T> extends Meta<T> {
031    /**
032     * In BlockMeta, the data always has 8 elements laid out like so:
033     * <ul>
034     *     <li>0-1: Player yaw * 10</li>
035     *     <li>2: Block direction</li>
036     *     <li>3: Cursor x</li>
037     *     <li>4: Cursor y</li>
038     *     <li>5: Cursor z</li>
039     *     <li>6-7: item damage</li>
040     * </ul>
041     *
042     * @param instance the data owner which the value will be applied upon
043     * @param data     the data
044     * @return the new meta instance
045     */
046    @Override
047    default Meta<T> decodeMeta(T instance, byte[] data) {
048        return decode(instance, ByteArray.readShort(data[0], data[1]) / 10F, data[2], data[3], data[4], data[5],
049                ByteArray.readShort(data[6], data[7]));
050    }
051
052    /**
053     * In blocks, only one meta field byte is needed
054     */
055    @Override
056    default byte[] encodeMeta() {
057        return new byte[]{encode()};
058    }
059
060    /**
061     * Used by the metadata compiler to order the specific metadata value before this one
062     * to preserve bit order
063     *
064     * @return the classes to have dependencies on
065     */
066    default Class[] dependencies() {
067        return new Class[0];
068    }
069
070    /**
071     * Encodes the block metadata into a single byte, which is then combined with the rest of the metadata
072     *
073     * @return the byte data
074     */
075    byte encode();
076
077    /**
078     * Decodes the block meta
079     *
080     * @param instance    the block instance
081     * @param yaw         the player yaw
082     * @param direction   the block direction
083     * @param cx          the cursor x
084     * @param cy          the cursor y
085     * @param cz          the cursor z
086     * @param damageValue the item damage
087     * @return the new meta instance
088     */
089    Meta<T> decode(T instance, float yaw, byte direction, byte cx, byte cy, byte cz, short damageValue);
090}