Skip to content
Jamie Mansfield edited this page Nov 6, 2015 · 15 revisions

The following page will try to explain what a manipulator is and how to use them.

Creation

A Manipulator is a standalone object, that can be manipulated. It is used for holding meta.

import uk.jamierocks.meta.api.manipulator.MetaManipulator;

public interface TimeMeta extends MetaManipulator {

    int time();
}

The above example has one value - time. The value can be manipulated by using the value functions provided.

meta.offer(Keys.TIME, 5);

The manipulator will now have time down as being 5, however this does NOT mean the holder will have been changed. To change the MetaHolder you will have to apply the manipulator to it.

You may notice the above example makes use of a 'Keys' class - these will be covered in another page.

holder.applyMeta(meta);

Implementing

To implement a manipulator you will need to implement the interface, and create two constructors.

import uk.jamierocks.meta.api.manipulator.MetaContainer;
import uk.jamierocks.meta.impl.manipulator.AbstractMeta;
import uk.jamierocks.meta.impl.LexMetaContainer;

public class ExampleTimeMeta extends AbstractMeta implements TimeMeta {

    private int time; // See how this is NOT final

    // This is the first constructor
    public ExampleTimeMeta(int time) {
        this.time = time;
        this.registerGettersAndSetters();
    }

    // Notice how this constructor takes no arguments
    // The constructor calls the first constructor with default values
    // You may want to consider creating a MetaConstants object, to store
    // all the default values.
    public ExampleTimeMeta() {
        this(5);
    }

    @Override
    public int time() {
        return this.time;
    }

    public void setTime(int time) {
        this.time = time;
    }

    @Override
    protected void registerGettersAndSetters() {
        this.registerGetter(Keys.TIME, ExampleTimeMeta.this::time);
        this.registerSetter(Keys.TIME, ExampleTimeMeta.this::setTime);
    }

    @Override
    public MetaContainer toContainer() {
        return new LexMetaContainer()
            .set(Keys.TIME, this.time);
    }
}

However for this type of meta (singular), there is an even simpler way to implement it.

import uk.jamierocks.meta.impl.manipulator.AbstractSingularMeta;

public class ExampleTimeMeta extends AbstractSingularMeta<Integer> implements TimeMeta {

    // We have to use Integer here, because int cannot be used within generics
    public ExampleTimeMeta(Integer time) {
        super(Keys.TIME, time);
    }

    // Same as above example
    public ExampleTimeMeta() {
        this(5);
    }

    @Override
    public int time() {
        // Here we use a method provided by AbstractSingularMeta.
        return this.getValue();
    }
}

Builders

Not only do manipulators require an implementation as seen above, they require a ManipulatorBuilder.

import uk.jamierocks.meta.api.builder.MetaManipulatorBuilder;

public class TimeMetaBuilder implements MetaManipulatorBuilder<TimeMeta> {

    @Override
    public TimeMeta create() {
        return new ExampleTimeMeta();
    }

    @Override
    public Class<TimeMeta> getType() {
        return TimeMeta.class;
    }
}

They need to be registered using:

import uk.jamierocks.meta.api.builder.Builders;

Builders.registerBuilder(new TimeMetaBuilder());

Builders are used for constructing manipulators filled with default data.

Clone this wiki locally