Jump to content

Script attributes


Ryley

Recommended Posts

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

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