Composition Pattern Using Flyweight With Generics

I want to lean how to implement a Generic Composition pattern using Flyweight. I found lots of info on Composition and Flyweight but nothing this specific ( Generic Composition pattern using Flyweight)

Please any learning resources would be appreciated

Thank you

Please help so I dont have to go to stack-overflow, people on there will eat me alive lol

What is it you’re attempting to do?

Are you trying to have it where the various child components of a composited object are flyweights themselves?

Have a flyweight source, and when you add child components to the composited object, use the flyweights you get from the flyweight source.

Yes that is what I’m trying to learn but I need to see it to understand it.

Here is one that got my head around composition

//-------------------------------------------------------------------------------------
//    CompositeStructure.cs
//-------------------------------------------------------------------------------------

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class CompositeStructure : MonoBehaviour
{
    void Start ( )
    {
        // Create a tree structure
        Composite root = new Composite("root");
        root.Add(new Leaf("Leaf A"));
        root.Add(new Leaf("Leaf B"));

        Composite comp = new Composite("Composite X");
        comp.Add(new Leaf("Leaf XA"));
        comp.Add(new Leaf("Leaf XB"));

        root.Add(comp);
        root.Add(new Leaf("Leaf C"));

        // Add and remove a leaf
        Leaf leaf = new Leaf("Leaf D");
        root.Add(leaf);
        root.Remove(leaf);

        // Recursively display tree
        root.Display(1);

    }
}

/// <summary>
/// The 'Component' abstract class
/// </summary>
abstract class Component
{
    protected string name;

    // Constructor
    public Component(string name)
    {
        this.name = name;
    }

    public abstract void Add(Component c);
    public abstract void Remove(Component c);
    public abstract void Display(int depth);
}

/// <summary>
/// The 'Composite' class
/// </summary>
class Composite : Component
{
    private List<Component> _children = new List<Component>();

    // Constructor
    public Composite(string name)
      : base(name)
    {
    }

    public override void Add(Component component)
    {
        _children.Add(component);
    }

    public override void Remove(Component component)
    {
        _children.Remove(component);
    }

    public override void Display(int depth)
    {
        Debug.Log(new String('-', depth) + name);

        // Recursively display child nodes
        foreach (Component component in _children)
        {
            component.Display(depth + 2);
        }
    }
}

/// <summary>
/// The 'Leaf' class
/// </summary>
class Leaf : Component
{
    // Constructor
    public Leaf(string name)
      : base(name)
    {
    }

    public override void Add(Component c)
    {
        Debug.Log("Cannot add to a leaf");
    }

    public override void Remove(Component c)
    {
        Debug.Log("Cannot remove from a leaf");
    }

    public override void Display(int depth)
    {
        Debug.Log(new String('-', depth) + name);
    }
}

On a side note is ECS following a composition type structure. Is threr a structure template for ECO like the one above so I can understand how to structure for ECS

Thanks heaps

Very simple example:

//composition pattern example - a buff system

public class PlayerBuffComposite
{
 
    private List<IBuff> _buffs = new List<IBuff>();
 
    public void AddBuff(IBuff buff)
    {
        _buffs.Add(buff);
    }
 
    public void RemoveBuff(IBuff buff)
    {
        _buffs.Remove(buff);
    }
 
    public void ApplyBuffToAction(PlayerAction action)
    {
        foreach(var buff in _buffs)
        {
            _buffs.ApplyToAction(action);
        }
    }
 
}

public interface IBuff
{
 
    void ApplyToAction(PlayerAction action);
 
}

//flyweight pattern example

public class AttackBuff : IBuff
{
 
    public float Multiplier;
 
    public void ApplyToAction(PlayerAction action)
    {
        action.AttackStrength *= Multiplier;
    }

    //also implement general flyweight implementation if you deem it necessary like equality
 
}

public class DefenseBuff : IBuff
{
 
    public float Multiplier;
 
    public void ApplyToAction(PlayerAction action)
    {
        action.Defense *= Multiplier;
    }

    //also implement general flyweight implementation if you deem it necessary like equality
 
}

public static class BuffFlyweightSource
{
 
    public static readonly IBuff Level1AttackBuff = new AttackBuff() { Multiplier = 1.1f };
    public static readonly IBuff Level2AttackBuff = new AttackBuff() { Multiplier = 1.5f };
    public static readonly IBuff Level1DefenseBuff = new DefenseBuff() { Multiplier = 1.1f };

    //your flyweight source could be implemented any number of ways... I just did static readonly field.
    //you could have done a dictionary allowing for lookups, which would be nice since you could than use an enum/string to allow other scripts to have configurable buffs that they apply
    //of course... if I was actually doing this in my game, I'd probably use a ScriptableObject as my flyweight... actually, it IS what I do in my game.
 
}

//usage

public class DefenseBuffItem : MonoBehaviour
{
 
    //when the player intersects the item, add defense buff
    private void OnTriggerEnter(Collider other)
    {
        var player = Player.GetFromCollider(other);
        if(player == null) return; //wasn't the player
   
        //here we add a flyweight as the component of the PlayerBuffs composite
        player.PlayerBuffs.AddBuff(BuffFlyweightSource.Level1DefenseBuff);

        //we destroy the defense item when collected
        Destroy(this.gameObject);
    }
 
}
1 Like

Thanks lordofduck is is super helpful. Just wondering what design patten is ECS or simular to it