RFTools

RFTools

74M Downloads

Abstraction of Dimlets

Ivorforce opened this issue ยท 1 comments

commented

The Idea

Abstraction of dimlets to a separate class, encapsulation of functionality into modules (similar to the current DimletType) handled by Dimlet instances, introduction of DimletStack storing dimlet-specific data.

Pros

  • Dimlet class: Model (Dimlet class instances) is separated from Controller (DimletType), in the style of MVC
  • DimletStack: Abstraction of data, so that not every block needs a specific dimlet subtype, making the system far more accessible and easily expandable
    • Also, separation of creation layer (crafting / finding dimlets) from actual funcitonality layer - this would mean a player would be capable of spawning in specific block / biome dimlets in creative mode, which were not specifically added in your code.
  • DimletType modularity: Possibility for mixed dimlets, providing functionality across multiple DimletTypes at once ('chaotic' dimlets, so to say, which mix up the style a bit)
  • Far, far, far less dimlet IDs used up
    • IDs are a lot more inherently self-explanatory

Cons

  • Initial implementation time
  • More backwards compatibility code

Proposal 1: Item /Block style

This is pretty much the approach that Mojang uses for their Items / ItemStacks. It's simple, and easy to expand, but requires the owning mod to supervise each method call (e.g. you can't add new dimlet effects without modifying the Dimlet class itself, which is not always good). Unless each method specifically returns arrays (BlockState[], BiomeGenBase[] etc.) on each call, a single dimlet can't also have multiple effects in the same category.

// Added as a simple 1.8-style encapsulation of a placed block
class BlockState { Block block; int metadata; }

public class DimletStack
{
    public Dimlet dimlet;
    public NBTTagCompound tagCompound;

    public void writeToNBT(NBTTagCompound compound) { .... }
    public static DimletStack loadFromNBT(NBTTagCompound compound) { .... }
}

public class Dimlet
{
    public BlockState getSurfaceBlock(DimletStack stack) {}
    public BlockState getTendrilBlock(DimletStack stack) {}
    public BiomeGenBase getMainBiome(DimletStack stack) {}
}

// Further expandability can be handled with interfaces, like they are used with items sometimes

public interface TendrilDimlet 
{
    BlockState getTendrilBlock(DimletStack stack) {}
} 

Proposal 2: Item /Block style

A more abstract implementation that also allows you to keep the current DimletType things, for the most part (just convert enum to specific subclasses). Each DimletType would contain information about a specific effect of a dimlet on a dimension.
I utilize this approach in Recurrent Complex myself, i.e. https://github.com/Ivorforce/RecurrentComplex/blob/master/src/main/java/ivorius/reccomplex/structures/StructureInfo.java#L26
and the registry
https://github.com/Ivorforce/RecurrentComplex/blob/master/src/main/java/ivorius/reccomplex/structures/StructureRegistry.java#L156-L179

// Added as a simple 1.8-style encapsulation of a placed block
class BlockState { Block block; int metadata; }

public class DimletStack
{
    public Dimlet dimlet;
    public NBTTagCompound tagCompound;

    public void writeToNBT(NBTTagCompound compound) { .... }
    public static DimletStack loadFromNBT(NBTTagCompound compound) { .... }
}

public class Dimlet
{
    /** Returns all DimletType instances for a specific class dimlet **/
    public Set<DimletType> getDimletTypes(Class<? extends DimletType> clazz, DimletStack dimletStack) {}

    // --- Or this approach, which wouldn't modify the current grammar:

    /** Returns the DimletType instance **/
    public DimletType getDimletType(DimletStack dimletStack) {}
}
commented

Doing this gradually. Latest RFTools already has a refactoring where I introduced an IDimletType interface. The old DimletType enum is still there but now delegates most stuff to a type specific implementation of the interface. Dimension construction and other features have now also moved into type specific implementations so it is almost possible to easily add custom dimlet types that have more and specialized effects. Still work in progress.