All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.threerings.nexus.distrib.DMap Maven / Gradle / Ivy

The newest version!
//
// Nexus Core - a framework for developing distributed applications
// http://github.com/threerings/nexus/blob/master/LICENSE

package com.threerings.nexus.distrib;

import java.util.HashMap;
import java.util.Map;

import com.threerings.nexus.io.Streamable;

/**
 * A map attribute for a Nexus object. Contains a mapping from keys to values.
 */
public class DMap extends react.RMap
    implements DAttribute
{
    /**
     * Creates a distributed map that uses a {@link HashMap} as its underlying implementation.
     */
    public static  DMap create (NexusObject owner) {
        return create(owner, new HashMap());
    }

    /**
     * Creates a distributed map with the supplied underlying map implementation.
     */
    public static  DMap create (NexusObject owner, Map impl) {
        return new DMap(owner, impl);
    }

    @Override public void readContents (Streamable.Input in) {
        _impl = in.>readValue();
    }

    @Override public void writeContents (Streamable.Output out) {
        out.writeValue(_impl);
    }

    protected DMap (NexusObject owner, Map impl) {
        super(impl);
        _owner = owner;
        _index = owner.registerAttr(this);
    }

    @Override protected void emitPut (K key, V value, V oldValue) {
        // we don't call super as we defer notification until the event is dispatched
        PutEvent event = new PutEvent(_owner.getId(), _index, key, value);
        event.oldValue = oldValue;
        _owner.postEvent(event);
    }

    protected void applyPut (K key, V value, V oldValue) {
        if (oldValue == DistribUtil.sentinelValue()) {
            // we came in over the network: update our underlying map
            oldValue = _impl.put(key, value);
        }
        notifyPut(key, value, oldValue);
    }

    @Override protected void emitRemove (K key, V oldValue) {
        // we don't call super as we defer notification until the event is dispatched
        RemoveEvent event = new RemoveEvent(_owner.getId(), _index, key);
        event.oldValue = oldValue;
        _owner.postEvent(event);
    }

    protected void applyRemove (K key, V oldValue) {
        if (oldValue == DistribUtil.sentinelValue()) {
            // we came in over the network: update our underlying map
            oldValue = _impl.remove(key);
        }
        notifyRemove(key, oldValue);
    }

    /** An event emitted when a mapping is added or updated. */
    protected static class PutEvent extends DAttribute.Event {
        public V oldValue = DistribUtil.sentinelValue();

        public PutEvent (int targetId, short index, K key, V value) {
            super(targetId, index);
            _key = key;
            _value = value;
        }

        @Override public void applyTo (NexusObject target) {
            target.>getAttribute(this.index).applyPut(_key, _value, oldValue);
        }

        @Override protected void toString (StringBuilder buf) {
            super.toString(buf);
            buf.append(", key=").append(_key);
            buf.append(", value=").append(_value);
        }

        protected final K _key;
        protected final V _value;
    }

    /** An event emitted when a mapping is removed. */
    protected static class RemoveEvent extends DAttribute.Event {
        public V oldValue = DistribUtil.sentinelValue();

        public RemoveEvent (int targetId, short index, K key) {
            super(targetId, index);
            _key = key;
        }

        @Override public void applyTo (NexusObject target) {
            target.>getAttribute(this.index).applyRemove(_key, oldValue);
        }

        @Override protected void toString (StringBuilder buf) {
            super.toString(buf);
            buf.append(", key=").append(_key);
        }

        protected final K _key;
    }

    /** The object that owns this attribute. */
    protected final NexusObject _owner;

    /** The index of this attribute in its containing object. */
    protected final short _index;
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy