MVC shop project for software architecture, in Unity.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

88 lines
3.6 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.U2D;
/// <summary>
/// This class is applied to a button that represents an Item in the View. It is a visual representation of the item
/// when it is visible in the store. The class holds a link to the original Item, it sets the icon of the button to
/// the one specified in the Item data, and it enables or disables the infoPanel to indicate if the item is selected
/// and display the details of the item. The original implementation was hardcoded for the grid view. We use patterns to
/// make this one a little more universally useful
/// </summary>
public abstract class ViewItemContainer : MonoBehaviour, IItemContainer, IShopModelObserver<Item>
{
public Item Item => item;//Public getter for the item, required by IItemContainer interface.
// IItemContainer interface requires to know whether an item is selected visually or not. This implementation determines that by checking the info panel
public virtual bool IsSelected {
get { return highLight.gameObject.activeSelf; }
set { highLight.SetActive(value);}
}
//Link to the highlight image (set in prefab)
[SerializeField]
protected GameObject highLight;
[SerializeField]
protected Image icon;
//Link to the atlas of all the item icons, use to retrieve sprites for items. For more information of the API check:
// https://docs.unity3d.com/2019.3/Documentation/Manual/class-SpriteAtlas.html
[SerializeField]
protected SpriteAtlas iconAtlas;
//link to the original item (set in Initialize)
protected Item item;
private IDisposable unsubscriber; // If this item manages its own lifetime, this will not be null
//------------------------------------------------------------------------------------------------------------------------
// Initialize()
//------------------------------------------------------------------------------------------------------------------------
public void Initialize(Item item, IDisposable unsubscriber = null){ // pass unsubscriber to this object to make it manage its own lifetime
//Stores the item
this.item = item;
this.unsubscriber = unsubscriber;
// Clones the first Sprite in the icon atlas that matches the iconName and uses it as the sprite of the icon image.
Sprite sprite = iconAtlas.GetSprite(item.iconName);
if (sprite != null) {
icon.sprite = sprite;
}
IsSelected = false;
OnInitialize(item);
}
protected abstract void OnInitialize(Item item);
// When the observable fires, check if we're the view corresponding to the selected item. Select if we are!
public void OnSelected(Item item)
{
IsSelected = this.item == item;
}
public void OnRemoved(Item item)
{
if (item != Item) return; // Well we only want this if the item removed from the model is actually ours!
IsSelected = false; // Kind of pointless, but won't hurt
Destroy(gameObject);
}
public void OnAdded(Item item)
{
throw new NotImplementedException();
}
// The reason we do this in OnDestroy() is so we don't have a memory leak when this gets removed externally somehow
private void OnDestroy()
{
unsubscriber?.Dispose(); // Careful! If we don't make this thing aware that it manages itself, and we forget to manage it, we have a memory leak
}
}