/* * Item.java * * Copyright (C) 2008 Pei Wang * * This file is part of Open-NARS. * * Open-NARS is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * Open-NARS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Open-NARS. If not, see <http://www.gnu.org/licenses/>. */ package nars.entity; import java.util.Comparator; import nars.storage.Memory; /** * An item is an object that can be put into a Bag, * to participate in the resource competition of the system. * <p> * It has a key and a budget. Cannot be cloned */ public abstract class Item<K> { public static class ItemPriorityComparator<E extends Item> implements Comparator<E> { @Override public int compare(final E a, final E b) { float ap = a.getPriority(); float bp = b.getPriority(); if ((a == b) || (a.name().equals(b.name())) || (ap==bp)) return a.hashCode() - b.hashCode(); else if (ap < bp) return 1; else return -1; } } /** The budget of the Item, consisting of 3 numbers */ public final BudgetValue budget; public Item() { //items that do not need budget this.budget = null; //Todo get rid of these console classes such as Reboot completely } //instead process them on parsing immediately!! /** * Constructor with initial budget * @param key The key value * @param budget The initial budget */ protected Item(final BudgetValue budget) { if (budget!=null) this.budget = budget.clone(); // clone, not assignment else this.budget = null; } /** * Get the current key * @return Current key value */ abstract public K name(); /** * Get priority value * @return Current priority value */ public float getPriority() { return budget.getPriority(); } /** * Set priority value * @param v Set a new priority value */ public void setPriority(final float v) { budget.setPriority(v); } /** * Increase priority value * @param v The amount of increase */ public void incPriority(final float v) { budget.incPriority(v); } /** * Decrease priority value * @param v The amount of decrease */ public void decPriority(final float v) { budget.decPriority(v); } /** * Get durability value * @return Current durability value */ public float getDurability() { return budget.getDurability(); } /** * Set durability value * @param v The new durability value */ public void setDurability(final float v) { budget.setDurability(v); } /** * Increase durability value * @param v The amount of increase */ public void incDurability(final float v) { budget.incDurability(v); } /** * Decrease durability value * @param v The amount of decrease */ public void decDurability(final float v) { budget.decDurability(v); } /** called when the item has been discarded */ public void end() { } /** * Get quality value * @return The quality value */ public float getQuality() { return budget.getQuality(); } /** * Set quality value * @param v The new quality value */ public void setQuality(final float v) { budget.setQuality(v); } /** * Merge with another Item with identical key * @param that The Item to be merged * @return the resulting Item: this or that */ public Item merge(final Item that) { budget.merge(that.budget); return this; } /** * Return a String representation of the Item * @return The String representation of the full content */ @Override public String toString() { //return budget + " " + key ; String budgetStr = budget!=null ? budget.toString() : ""; String n = name().toString(); return new StringBuilder(budgetStr.length()+n.length()+1).append(budgetStr).append(' ').append(n).toString(); } /** * Return a String representation of the Item after simplification * @return A simplified String representation of the content */ public String toStringExternal() { final String briefBudget = budget.toStringExternal(); String n = name().toString(); return new StringBuilder(briefBudget.length()+n.length()+1).append(briefBudget).append(' ').append(n).toString(); } /** similar to toStringExternal but includes budget afterward */ public String toStringExternal2() { final String briefBudget = budget.toStringExternal(); String n = name().toString(); return new StringBuilder(briefBudget.length()+n.length()+1).append(n).append(' ').append(briefBudget).toString(); } public String toStringLong() { return toString(); } /*//default: @Override public int compareTo(final Object o) { //return System.identityHashCode(this) - System.identityHashCode(o); return hashCode() - o.hashCode(); }*/ @Override public int hashCode() { return name().hashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) return true; if (obj instanceof Item) { return ((Item)obj).name().equals(name()); } return false; } abstract public static class StringKeyItem extends Item<CharSequence> { public StringKeyItem(final BudgetValue budget) { super(budget); } @Override public int hashCode() { return name().hashCode(); } @Override public boolean equals(final Object obj) { if (obj == this) return true; if (obj instanceof Item) { return ((Item)obj).name().equals(name()); } return false; } } public static float getPrioritySum(Iterable<? extends Item> c) { float totalPriority = 0; for (Item i : c) totalPriority+=i.getPriority(); return totalPriority; } /** randomly selects an item from a collection, weighted by priority */ public static <E extends Item> E selectRandomByPriority(Iterable<E> c) { float totalPriority = getPrioritySum(c); if (totalPriority == 0) return null; float r = Memory.randomNumber.nextFloat() * totalPriority; E s = null; for (E i : c) { s = i; r -= s.getPriority(); if (r < 0) return s; } return s; } public BudgetValue getBudget() { return budget; } }