Jump to content

Script attributes


Recommended Posts

Posted (edited)

I started writing my own extension API alongside OSBots which contains helper methods that are typically used in most scripts, this is one of the classes:

 

package org.milkcouch.script;
 
import java.util.HashMap;
import java.util.Map;
 
/**
 * Represents attributes that a script uses.
 * 
 * <a>
 *  Example: for skill calculators I see a bunch of people adding a multitude of
 *  variables to represent the initial experience before starting a script.
 *  With this you could create constant fields:
 *  <code>
 *  final class MyScriptsAttributes {
 *  private static final ScriptAttributes attributes = ScriptAttributes.getInstance();
 * 
 *  public static final boolean USE_FOOD = attributes.contains("USE_FOOD");
 *  ... and so on ...
 *  }
 *  </code>
 * 
 *  This makes your code much more readable and you do not have
 *  A cluster fuck of random variables everywhere representing various attributes.
 *  This can also be used for setting the current state of your bot, I see people
 *  All the time having a static <code>String</code> and setting it each time a state is updated.
 *  
 *  <code>
 *  vars.status = "antiban";
 *  </code>
 * 
 *  That is very unappealing and ignores any convention.
 * 
 *  Instead we could do this:
 * 
 *  <code>
 *  ScriptAttributes.getInstance().updateStatus("Antiban");
 *  </code>
 * 
 *  And to return it, I have added status helper methods, which make it simple for everyone.
 * 
 *  <code>
 *  ScriptAttributes.getInstance().getCurrentStatus();
 *  </code>
 * </a>
 * 
 * @author Ryley Kimmel <ryley.kimmel@live.com>
 */
public final class ScriptAttributes {
 
    /**
     * A 'lazy' singleton implementation.
     */
    private static final ScriptAttributes INSTANCE = new ScriptAttributes();
 
    /**
     * A map of strings->objects, which represent attributes.
     */
    private final Map<String, Object> attributes = new HashMap<>();
 
    /**
     * Adds an attribute to the attribute map.
     * @param key The attributes key.
     * @param value The value of the attribute.
     */
    public void add(String key, Object value) {
        attributes.put(key, value);
    }
 
    /**
     * Returns the value of a specified key.
     * @param key The key.
     * @return The value of the specified key, <tt>null</tt> if the key does not exist.
     */
    public Object getValue(String key) {
        return attributes.get(key);
    }
 
    /**
     * Removes an attribute from the map by its key.
     * @param key The key to remove.
     */
    public void remove(String key) {
        attributes.remove(key);
    }
 
    /**
     * Removes a set of keys from the map.
     * @param keys The keys to remove.
     */
    public void remove(String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }
 
    /**
     * Returns whether or not the map contains the specified key.
     * @param key The key.
     * @return <code>true</code> if the key exists, otherwise </code>false</code>
     */
    public boolean contains(String key) {
        return attributes.containsKey(key);
    }
 
    // ... status helpers
 
    /**
     * Updates the current status of your script.
     * @param newStatus The new status.
     */
    public void updateStatus(String newStatus) {
        add("CURRENT_STATUS", newStatus);
    }
 
    /**
     * Returns the current status of your script.
     * @return The current status of your script, <tt>null</tt> if no status exists.
     */
    public String getStatus() {
        return (String) getValue("CURRENT_STATUS");
    }
 
    /**
     * Returns the singleton instance of this class.
     * @return The singleton instance.
     */
    public static ScriptAttributes getInstance() {
        return INSTANCE;
    }
 
    /**
     * Default private constructor, used to prevent this class from being instantiated.
     * <a>
     *  This constructor should not be instanced directly, use {@link #getInstance()} instead!
     * </a>
     * @see {@link #getInstance()}.
     */
    private ScriptAttributes() {
 
    }
 
}
Edited by Ryley
Posted (edited)

Why not just extend the HashMap<String, Object> onto the class and create a static constant of the class itself? You could remove all the already-existing methods from the class, i.e., #getValue(String).

 

Here's what I would do instead:

public class ScriptAttribute extends HashMap<String, Object> {

	private static final ScriptAttribute INSTANCE = new ScriptAttribute();

	private static final String KEY_STATUS = "CURRENT_STATUS";

        static {

            INSTANCE.put(KEY_STATUS, "null");
        }

	private ScriptAttribute() {
	}

	public String getStatus() {
		return (String) get(KEY_STATUS);
	}

	public void setStatus(String status) {
		put(KEY_STATUS, status);
	}

	/**
	 * This may look weird, but:
	 * <code>
	 * #setStatus("Al Kharid");
	 * #updateStatus("Walking to Bank");
	 * 
	 * #getStatus() @return "Al Kharid - Walking to Bank"
	 * </code>
	 * 
	 * @param updateStatus
	 * 		Status to concatenate onto the prior state
	 */
	public void updateStatus(String updateStatus) {
		put(KEY_STATUS, getStatus() + " - " + updateStatus);
	}

	public void remove(String... keys) {
		if (keys == null || keys.length == 0)
			for (String next : keys)
				if (next != null && next.length() > 0)
					remove(next);
	}

	public static ScriptAttribute getInstance() {
		return INSTANCE;
	}
}

...A few changes, but in a ScriptAdapter class (A class that merely extends Script and allows script conformity) would be:

public class ScriptAdapter extends Script {

	. . .

	public static ScriptAttribute getAttributeHandler() {
		return ScriptAttribute.getInstance();
	}
}

I would do this so that you can direct the access to the script's attributes via the main script class.

 

1 second after posting and I just remembered something::

I would override the #remove(Object) to prevent the removal of important keys, i.e., CURRENT_STATUS, etc.

 

P.S. I did kind of rush the code, so updateStatus(String) would continuously append the existing String for CURRENT_STATUS, e.g., "Al Kharid - Going to Bank - Going to Mines - ..."

 

..It's not too bad, especially if you wanted to keep track of the executing states in order, but it wouldn't look good in the paint, though. smile.png

Edited by liverare
  • 2 weeks later...
Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...