aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/config/items
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/api/config/items')
-rw-r--r--Src/Wasabi/api/config/items/attrbool.h65
-rw-r--r--Src/Wasabi/api/config/items/attrcb.h127
-rw-r--r--Src/Wasabi/api/config/items/attrfloat.h52
-rw-r--r--Src/Wasabi/api/config/items/attrfn.h15
-rw-r--r--Src/Wasabi/api/config/items/attrhandler.h129
-rw-r--r--Src/Wasabi/api/config/items/attribs.h12
-rw-r--r--Src/Wasabi/api/config/items/attribute.cpp131
-rw-r--r--Src/Wasabi/api/config/items/attribute.h218
-rw-r--r--Src/Wasabi/api/config/items/attrint.h65
-rw-r--r--Src/Wasabi/api/config/items/attrstr.cpp14
-rw-r--r--Src/Wasabi/api/config/items/attrstr.h85
-rw-r--r--Src/Wasabi/api/config/items/cfgitem.h233
-rw-r--r--Src/Wasabi/api/config/items/cfgitemi.cpp274
-rw-r--r--Src/Wasabi/api/config/items/cfgitemi.h158
-rw-r--r--Src/Wasabi/api/config/items/cfgitemx.cpp27
-rw-r--r--Src/Wasabi/api/config/items/cfgitemx.h42
-rw-r--r--Src/Wasabi/api/config/items/intarray.cpp49
-rw-r--r--Src/Wasabi/api/config/items/intarray.h18
18 files changed, 1714 insertions, 0 deletions
diff --git a/Src/Wasabi/api/config/items/attrbool.h b/Src/Wasabi/api/config/items/attrbool.h
new file mode 100644
index 00000000..324a2e11
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrbool.h
@@ -0,0 +1,65 @@
+#ifndef _ATTRBOOL_H
+#define _ATTRBOOL_H
+
+#include "attribute.h"
+
+// inherit from this one, or just use it
+
+/**
+ Boolean configuration attributes have two values, true or false.
+ They can be used like any other config item.
+
+ @short Boolean configuration attribute.
+ @ver 1.0
+ @author Nullsoft
+ @see _int
+ @see _string
+ @see _float
+*/
+class _bool : public Attribute {
+public:
+ /**
+ Optionally set the name and default value of
+ your configuration attribute during construction.
+
+ @param name Name of the configuration attribute.
+ @param default_val Default value.
+ */
+ _bool(const wchar_t *name=NULL, int default_val=0) : Attribute(name) {
+ setValueAsInt(!!default_val, true);
+ }
+
+ // convenience operators
+ /**
+ Get the value of the attribute.
+ */
+ operator bool() { return !!getValueAsInt(); }
+
+ /**
+ Set the value of the attribute.
+ */
+ bool operator =(int newval) { setValueAsInt(!!newval); return *this; }
+
+ // from Attribute
+
+ /**
+ Get the attribute type. This will return
+ a constant representing the attribute type.
+
+ These constants can be: BOOL, FLOAT, STRING and INT.
+
+ @see AttributeType
+ @ret The attribute type.
+ */
+ virtual int getAttributeType() { return AttributeType::BOOL; }
+
+ /**
+ Get the configuration group to be used to represent
+ this attribute in the registry.
+
+ @ret Config group to be used.
+ */
+ virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.bool"; }
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrcb.h b/Src/Wasabi/api/config/items/attrcb.h
new file mode 100644
index 00000000..3aa0e41d
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrcb.h
@@ -0,0 +1,127 @@
+#ifndef _ATTRCB_H
+#define _ATTRCB_H
+
+#include "attribute.h"
+
+/**
+ Enables you to register callbacks on
+ a specific attribute to monitor if it's
+ value has been changed by the user or other.
+
+ This class is not meant to be used on it's own.
+ Please derive from it instead.
+
+ @short Attribute callback
+ @ver 1.0
+ @author Nullsoft
+ @see Attribute
+ @see int_attrCB
+ @see _int
+ @see _float
+ @see _string
+ @see _bool
+*/
+class AttrCallback {
+public:
+ /**
+ Does nothing.
+ */
+ virtual ~AttrCallback() {}
+
+ /**
+ Event triggered when the value of the attribute,
+ for which this callback has been registered, changes.
+
+ This is a pure virtual, please override to implement
+ your custom behavior.
+
+ @param attr Attribute for which the value has changed.
+ */
+ virtual void onValueChange(Attribute *attr)=0;
+};
+
+/**
+ Enables you to register callbacks on a specific
+ integer or boolean attribute to monitor if the
+ value has been changed by the user or other.
+
+ @short Integer or Boolean attribute Callback.
+ @ver 1.0
+ @author Nullsoft
+ @see Attribute
+ @see _int
+ @see _bool
+*/
+class int_attrCB : public AttrCallback {
+ typedef void (*fnPtrType)(int);
+public:
+ /**
+ Upon construction, you must specify which
+ function will be called when the value of
+ the attribute has indeed changed.
+
+ This is done using a pointer to the function.
+ The function must accept one parameter of type
+ int, like so: void myfunc(int val);
+
+ @param _fn Pointer to the function to use on value change.
+ */
+ int_attrCB(fnPtrType _fn) { fnptr = _fn; }
+
+ /**
+ Event triggered when the value of the attribute,
+ for which this callback has been registered, changes.
+
+ Override this to implement your own behavior.
+ The default is to send the new value of the attribute
+ to a function which you specify upon construction
+ of this object.
+
+ @param attr Attribute for which the value has changed.
+ */
+ virtual void onValueChange(Attribute *attr) {
+ ASSERT(attr->getAttributeType() == AttributeType::INT ||
+ attr->getAttributeType() == AttributeType::BOOL);
+ (*fnptr)(attr->getValueAsInt());
+ }
+private:
+ fnPtrType fnptr;
+};
+
+class string_attrCB : public AttrCallback {
+ typedef void (*fnPtrType)(const wchar_t *);
+public:
+ /**
+ Upon construction, you must specify which
+ function will be called when the value of
+ the attribute has indeed changed.
+
+ This is done using a pointer to the function.
+ The function must accept one parameter of type
+ int, like so: void myfunc(const char *val);
+
+ @param _fn Pointer to the function to use on value change.
+ */
+ string_attrCB(fnPtrType _fn) { fnptr = _fn; }
+
+ /**
+ Event triggered when the value of the attribute,
+ for which this callback has been registered, changes.
+
+ Override this to implement your own behavior.
+ The default is to send the name of the attribute
+ to a function which you specify upon construction
+ of this object.
+
+ @param attr Attribute for which the value has changed.
+ */
+ virtual void onValueChange(Attribute *attr)
+ {
+ ASSERT(attr->getAttributeType() == AttributeType::STRING);
+ (*fnptr)(attr->getAttributeName());
+ }
+private:
+ fnPtrType fnptr;
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrfloat.h b/Src/Wasabi/api/config/items/attrfloat.h
new file mode 100644
index 00000000..056f0c46
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrfloat.h
@@ -0,0 +1,52 @@
+#ifndef _ATTRFLOAT_H
+#define _ATTRFLOAT_H
+
+#include "attribute.h"
+
+// actually it's a double :)
+
+class _float : public Attribute {
+public:
+ /**
+ Optionally set the name and default value of
+ your configuration attribute during construction.
+
+ @param name Name of the configuration attribute.
+ @param default_val Default value.
+ */
+ _float(const wchar_t *name=NULL, double default_val=0.f) : Attribute(name) {
+ setValueAsDouble(default_val, true);
+ }
+
+ /**
+ Get the attribute type. This will return
+ a constant representing the attribute type.
+
+ These constants can be: BOOL, FLOAT, STRING and INT.
+
+ @see AttributeType
+ @ret The attribute type.
+ */
+ virtual int getAttributeType() { return AttributeType::FLOAT; }
+
+ /**
+ Get the configuration group to be used to represent
+ this attribute in the registry.
+
+ @ret Config group to be used.
+ */
+ virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.float"; }
+
+ // convenience operators
+ /**
+ Get the value of the attribute.
+ */
+ operator double() { return getValueAsDouble(); }
+
+ /**
+ Set the value of the attribute.
+ */
+ double operator =(double newval) { return setValueAsDouble(newval) ? newval : getValueAsDouble(); }
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrfn.h b/Src/Wasabi/api/config/items/attrfn.h
new file mode 100644
index 00000000..54f46df0
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrfn.h
@@ -0,0 +1,15 @@
+#ifndef _ATTRFN_H
+#define _ATTRFN_H
+
+#include "attrstr.h"
+
+class _filename : public _string {
+public:
+ _filename(const wchar_t *name, const wchar_t *default_val=L"")
+ : _string(name, default_val) { }
+
+ virtual int getAttributeType() { return AttributeType::FILENAME; }
+ virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.filename"; }
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrhandler.h b/Src/Wasabi/api/config/items/attrhandler.h
new file mode 100644
index 00000000..c2624f46
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrhandler.h
@@ -0,0 +1,129 @@
+//!## An object to multiplex the callbacks of multiple attributes.
+#ifndef _ATTRHANDLER_H
+#define _ATTRHANDLER_H
+
+// This class is meant to be subclassed. The methods you must provide
+// are given as pure virtuals. See ExampleAttrib for more details, and
+// an example subclass that you can copy for your own use.
+
+#include "attrcb.h"
+#include "attribs.h"
+#include <bfc/map.h>
+
+//
+// Forward References
+class WAComponentClient;
+class Attribute;
+
+
+//
+// Class Definition
+template <class TCallback>
+class AttrHandler {
+protected:
+ // Heh, oops. Can't have one AttrCallback handle lots of different attribs, anymore. I fix.
+ class AttrHandlerChild : public AttrCallback {
+ public:
+ AttrHandlerChild(AttrHandler *_parent) : AttrCallback() {
+ ASSERT(_parent != NULL);
+ recursion = 0;
+ callback = NULL;
+ parent = _parent;
+ }
+
+ // Here is where we split out the different value types
+ virtual void onValueChange(Attribute *attr) {
+ if (!recursion) {
+ // protect our programmers from stack overflow, please.
+ recursion = 1;
+ if ((callback != NULL) && (parent != NULL)) {
+ int id;
+ // find the id from the map (friendly)
+ int success = parent->attribmap.getItem(attr,&id);
+ if (success) {
+ // and send it to the proper handling function (poorman's RTTI)
+ switch (attr->getAttributeType()) {
+ case AttributeType::INT:
+ callback->onIntChange(id,*static_cast<_int *>(attr));
+ break;
+ case AttributeType::BOOL:
+ callback->onBoolChange(id, *static_cast<_bool *>(attr));
+ break;
+ case AttributeType::FLOAT:
+ callback->onFloatChange(id, *static_cast<_float *>(attr));
+ break;
+ case AttributeType::STRING:
+ callback->onStringChange(id, *static_cast<_string *>(attr));
+ break;
+ }
+ }
+ }
+ recursion = 0;
+ }
+ }
+
+ virtual void bindCallbackObj(TCallback *callbackobj) {
+ // Be advised, this may be null. That's okay, we test for it above.
+ callback = callbackobj;
+ }
+ private:
+ int recursion;
+ TCallback *callback;
+ AttrHandler *parent;
+ };
+
+public:
+ AttrHandler() {
+ component = NULL;
+ callback = NULL;
+ }
+
+ // Call this method to bind your component (in your component's constructor)
+ virtual void bindComponent(WAComponentClient *parentcomponent) {
+ component = parentcomponent;
+ }
+
+ // Call this method to bind your callback object (usually your window in its constructor)
+ virtual void bindCallbackObj(TCallback *callbackobj) {
+ // Bind ourselves.
+ callback = callbackobj;
+
+ // Then go through and rebind any children.
+ int i, num = attrchildren.getNumItems();
+ for (i = 0; i < num; i++) {
+ AttrHandlerChild *child = attrchildren.enumItem(i);
+ child->bindCallbackObj(callback);
+ }
+ }
+
+ // Call this method to register each attribute.
+ virtual void registerAttribute(Attribute *attr, int id) {
+ ASSERTPR(component != NULL, "BIND YOUR COMPONENT before registering Attributes to a Handler.");
+ // register the attrib with a child object as its callback
+ AttrHandlerChild *child = new AttrHandlerChild(this);
+ attrchildren.addItem(child);
+ component->registerAttribute(attr, child);
+ // and save its id mapping
+ attribmap.addItem(attr, id);
+ }
+
+#if 0
+ // Your callback object (probably your primary window class) must implement
+ // its own versions of these methods here. They will be called by the
+ // switch statement below.
+ virtual void onIntChange(int id, int *attr);
+ virtual void onBoolChange(int id, bool *attr);
+ virtual void onFloatChange(int id, double *attr);
+ virtual void onStringChange(int id, const char *attr);
+#endif
+
+
+private:
+ friend AttrHandlerChild;
+ TCallback *callback;
+ WAComponentClient *component;
+ Map< Attribute *, int > attribmap;
+ PtrList<AttrHandlerChild> attrchildren;
+};
+
+#endif // _ATTRHANDLER_H
diff --git a/Src/Wasabi/api/config/items/attribs.h b/Src/Wasabi/api/config/items/attribs.h
new file mode 100644
index 00000000..1e35f78b
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attribs.h
@@ -0,0 +1,12 @@
+#ifndef _ATTRIBS_H
+#define _ATTRIBS_H
+
+// a convenience header to get all the attrib types in one whack
+
+#include "attrbool.h"
+#include "attrfloat.h"
+#include "attrint.h"
+#include "attrstr.h"
+#include "attrfn.h"
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attribute.cpp b/Src/Wasabi/api/config/items/attribute.cpp
new file mode 100644
index 00000000..27b519b6
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attribute.cpp
@@ -0,0 +1,131 @@
+#include <precomp.h>
+
+#include "attribute.h"
+#include <api/config/items/cfgitemi.h>
+
+
+Attribute::Attribute(const wchar_t *newname, const wchar_t *_desc) :
+ NamedW(newname), desc(_desc), cfgitemi(NULL), private_storage(NULL) { }
+
+Attribute::~Attribute() {
+ delete private_storage;
+}
+
+const wchar_t *Attribute::getAttributeName() {
+ return NamedW::getName();
+}
+
+const wchar_t *Attribute::getAttributeDesc() {
+ return desc;
+}
+
+int Attribute::getValueAsInt()
+{
+ wchar_t buf[1024]=L"";
+ getData(buf, 1024);
+ return WTOI(buf);
+}
+
+int Attribute::setValueAsInt(int newval, bool def)
+{
+ return setData(StringPrintfW(newval), def);
+}
+
+double Attribute::getValueAsDouble()
+{
+ wchar_t buf[1024] = {0};
+ getData(buf, 1024);
+ return WTOF(buf);
+}
+
+double Attribute::setValueAsDouble(double newval, bool def)
+{
+ return setData(StringPrintfW(newval), def);
+}
+
+int Attribute::getDataLen() {
+ if (private_storage != NULL)
+ return (int)private_storage->len()+1;
+
+ ASSERTPR(WASABI_API_CONFIG != NULL, "getDataLen() before API");
+ int r = WASABI_API_CONFIG->getStringPrivateLen(mkTag());
+ if (r < 0) {
+ r = (int)default_val.len()+1;
+ }
+ return r;
+}
+
+int Attribute::getData(wchar_t *data, int data_len)
+{
+ if (data == NULL || data_len < 0)
+ return 0;
+ if (private_storage != NULL)
+ {
+ if (private_storage->isempty())
+ {
+ if (data_len >= 1) {
+ *data = 0;
+ return 1;
+ }
+ return 0;
+ }
+ WCSCPYN(data, private_storage->getValue(), data_len);
+ return MIN((int)private_storage->len(), data_len);
+ }
+ ASSERTPR(WASABI_API_CONFIG != NULL, "can't get without api");
+ if (WASABI_API_CONFIG == NULL) return 0;
+ int r = WASABI_API_CONFIG->getStringPrivate(mkTag(), data, data_len, default_val.isempty() ? L"" : default_val.getValue());
+ return r;
+}
+
+int Attribute::setData(const wchar_t *data, bool def)
+{
+ if (def) { // setting default value
+ default_val = data;
+ return 1;
+ }
+ ASSERTPR(WASABI_API_CONFIG != NULL, "can't set data before api");
+ if (WASABI_API_CONFIG == NULL) return 0;
+
+ int r = setDataNoCB(data);
+ if (r && cfgitemi != NULL) cfgitemi->cfgitem_onAttribSetValue(this);
+ return r;
+}
+
+int Attribute::setDataNoCB(const wchar_t *data)
+{
+ if (private_storage != NULL) {
+ private_storage->setValue(data);
+ } else {
+ WASABI_API_CONFIG->setStringPrivate(mkTag(), data);
+ }
+ dependent_sendEvent(Attribute::depend_getClassGuid(), Event_DATACHANGE);
+ return 1;
+}
+
+void Attribute::setCfgItem(CfgItemI *item)
+{
+ delete private_storage; private_storage = NULL;
+ ASSERT(cfgitemi == NULL || item == NULL);
+ cfgitemi = item;
+ if (cfgitemi != NULL)
+ {
+ if (cfgitemi->cfgitem_usePrivateStorage())
+ private_storage = new StringW;
+ }
+}
+
+StringW Attribute::mkTag()
+{
+ StringW ret;
+ if (cfgitemi)
+ {
+ ret = cfgitemi->cfgitem_getPrefix();
+ }
+ ret.cat(getName());
+ return ret;
+}
+
+void Attribute::disconnect() {
+ setCfgItem(NULL);
+}
diff --git a/Src/Wasabi/api/config/items/attribute.h b/Src/Wasabi/api/config/items/attribute.h
new file mode 100644
index 00000000..c91e8065
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attribute.h
@@ -0,0 +1,218 @@
+#ifndef _ATTRIBUTE_H
+#define _ATTRIBUTE_H
+
+#include <bfc/depend.h>
+#include <bfc/named.h>
+#include <bfc/common.h>
+#include <bfc/string/StringW.h>
+
+class CfgItemI;
+
+// lowercase types are reserved for official Nullsoft use
+// uppercase are 3rd-party defined
+namespace AttributeType {
+ /**
+ Attribute types.
+ */
+ enum {
+ NONE = 0,
+ INT = MK3CC('i','n','t'), // attrint.h
+ STRING = MK3CC('s','t','r'), // attrstr.h
+ BOOL = MK4CC('b','o','o','l'), // attrbool.h
+ FLOAT = MK4CC('f','l','o','t'), // attrfloat.h
+ FILENAME = MK2CC('f','n'), // attrfn.h
+ };
+};
+
+/**
+ Generic configuration attribute.
+
+ Configuration attributes enable you to store
+ uniquely identifiable values that get pushed
+ to a configuration file automatically upon shutdown
+ of any Wasabi application.
+
+ You shouldn't normally use this on
+ it's own, look at the CfgItemI class
+ instead.
+
+ @short Generic configuration attribute.
+ @ver 1.0
+ @author Nullsoft
+ @see _float
+ @see _int
+ @see _bool
+ @see _string
+ @see CfgItemI
+*/
+class NOVTABLE Attribute : public DependentI, private NamedW
+{
+public:
+ static const GUID *depend_getClassGuid() {
+ // {5AB601D4-1628-4604-808A-7ED899849BEB}
+ static const GUID ret =
+ { 0x5ab601d4, 0x1628, 0x4604, { 0x80, 0x8a, 0x7e, 0xd8, 0x99, 0x84, 0x9b, 0xeb } };
+ return &ret;
+ }
+protected:
+
+ /**
+ Optionally set the name and default value of
+ your configuration attribute during construction.
+
+ @param name Name of the configuration attribute.
+ @param default_val Default value.
+ */
+ Attribute(const wchar_t *name=NULL, const wchar_t *desc=NULL);
+
+public:
+ virtual ~Attribute();
+
+ /**
+ Set the name of the configuration
+ attribute.
+
+ @param newname Name of the attribute.
+ */
+ void setName(const wchar_t *newname);
+
+ /**
+ Get the name of the configuration
+ attribute.
+
+ @ret Name of the attribute.
+ */
+ const wchar_t *getAttributeName();
+
+ /**
+ Get the attribute's description.
+
+ @ret Attribute's description.
+ */
+ const wchar_t *getAttributeDesc();
+
+ /**
+ Get the attribute type. Override
+ this for your custom attribute type.
+
+ @ret Attribute type.
+ */
+ virtual int getAttributeType()=0; // override me
+
+ /**
+ Get the configuration group to be used to represent
+ this attribute in the registry.
+
+ This is only called if the kernel doesn't have a default
+ config group set for your type already.
+
+ @ret Config group to be used.
+ */
+ virtual const wchar_t *getConfigGroup() { return NULL; } // override me
+
+ /**
+ Get the attribute's value as signed integer.
+
+ @ret Attribute value, as a signed integer.
+ */
+ int getValueAsInt();
+
+ /**
+ Set the attribute's value with a signed integer while
+ also being able to replace the default value previously
+ set.
+
+ @param newval Attribute's new value.
+ @param def true, replace the current default value; false, leave the default value unchanged;
+ */
+ int setValueAsInt(int newval, bool def=false);
+
+ /**
+ Get the attribute's value as signed double.
+
+ @ret Attribute value, as a signed double.
+ */
+ double getValueAsDouble();
+
+ /**
+ Set the attribute's value with a signed double while
+ also being able to replace the default value previously
+ set.
+
+ @param newval Attribute's new value.
+ @param def true, replace the current default value; false, leave the default value unchanged;
+ */
+ double setValueAsDouble(double newval, bool def=false);
+
+ /**
+ Get the length of the attribute's value (data)
+ in bytes.
+
+ @ret Attribute value (data) length, in bytes.
+ */
+ int getDataLen();
+
+ /**
+ Get the attribute's raw data.
+
+ This will return the data the attribute is storing
+ in a char buffer you hand to it.
+
+ @ret Attribute value, as a signed double.
+ @param data Pointer to a char buffer.
+ @param data_len The maximum amount of bytes the char buffer can hold.
+ */
+ int getData(wchar_t *data, int data_len);
+
+ /**
+ Set the attribute's value with a zero terminated string. Also
+ enables you to replace the default value previously
+ set.
+
+ @param newval Attribute's new value.
+ @param def true, replace the current default value; false, leave the default value unchanged;
+ */
+ int setData(const wchar_t *data, bool def=false);
+
+ void disconnect();
+
+ enum {
+ Event_DATACHANGE=100,
+ };
+protected:
+ friend class CfgItemI;
+
+ /**
+ Set the attribute's value without causing
+ a callback.
+
+ @ret 1.
+ @param data Attribute's new value.
+ */
+ int setDataNoCB(const wchar_t *data);
+
+ /**
+ Set the configuration item associated with this
+ attribute.
+ */
+ void setCfgItem(CfgItemI *item);
+
+ StringW mkTag();
+
+private:
+ StringW desc;
+ StringW default_val, *private_storage;
+ CfgItemI *cfgitemi;
+};
+
+#define ATTR_PERM_READ 1
+#define ATTR_PERM_WRITE 2
+
+#define ATTR_PERM_ALL (~0)
+
+// render hints for getRenderHint
+enum {
+ ATTR_RENDER_HINT_INT_CHECKMARK
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrint.h b/Src/Wasabi/api/config/items/attrint.h
new file mode 100644
index 00000000..c63af8ce
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrint.h
@@ -0,0 +1,65 @@
+#ifndef _ATTRINT_H
+#define _ATTRINT_H
+
+#include "attribute.h"
+
+// inherit from this one, or just use it
+/**
+ Boolean configuration attributes have two values, true or false.
+ They can be used like any other config item.
+
+ @short Integer configuration attribute.
+ @ver 1.0
+ @author Nullsoft
+ @see CfgItemI
+ @see _bool
+ @see _string
+ @see _float
+*/
+class _int : public Attribute {
+public:
+ /**
+ Optionally set the name and default value of
+ your configuration attribute during construction.
+
+ @param name Name of the configuration attribute.
+ @param default_val Default value.
+ */
+ _int(const wchar_t *name=NULL, int default_val=0) : Attribute(name) {
+ setValueAsInt(default_val, true);
+ }
+
+ // from AttributeI
+ /**
+ Get the attribute type. This will return
+ a constant representing the attribute type.
+
+ These constants can be: BOOL, FLOAT, STRING and INT.
+
+ @see AttributeType
+ @ret The attribute type.
+ */
+ virtual int getAttributeType() { return AttributeType::INT; }
+
+ /**
+ Get the configuration group to be used to represent
+ this attribute in the registry.
+
+ @ret Config group to be used.
+ */
+ virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.int"; }
+// virtual int getPermissions();
+
+ // convenience operators
+ /**
+ Get the value of the attribute.
+ */
+ operator int() { return getValueAsInt(); }
+
+ /**
+ Set the value of the attribute.
+ */
+ int operator =(int newval) { return setValueAsInt(newval) ? newval : getValueAsInt(); }
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/attrstr.cpp b/Src/Wasabi/api/config/items/attrstr.cpp
new file mode 100644
index 00000000..1209e2f3
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrstr.cpp
@@ -0,0 +1,14 @@
+#include <precomp.h>
+#include "attrstr.h"
+
+#include <bfc/memblock.h>
+
+const wchar_t *_string::getValue()
+{
+ int l = getDataLen();
+ if (l <= 0) return L"";
+ MemBlock<wchar_t> mb(l+2);
+ getData(mb.getMemory(), l+2);
+ returnval = mb;
+ return returnval;
+}
diff --git a/Src/Wasabi/api/config/items/attrstr.h b/Src/Wasabi/api/config/items/attrstr.h
new file mode 100644
index 00000000..cde81a64
--- /dev/null
+++ b/Src/Wasabi/api/config/items/attrstr.h
@@ -0,0 +1,85 @@
+#ifndef _ATTRSTR_H
+#define _ATTRSTR_H
+
+#include "attribute.h"
+
+#include <bfc/string/bfcstring.h>
+#include <bfc/common.h>
+
+/**
+ String configuration attributes, can have any string value
+ of any length. They can be used like any other config item.
+
+ @short String configuration attribute.
+ @ver 1.0
+ @author Nullsoft
+ @see _int
+ @see _bool
+ @see _float
+*/
+class _string : public Attribute {
+public:
+ /**
+ Optionally set the name and default value of
+ your configuration attribute during construction.
+
+ @param name
+ @param default_val
+ */
+ _string(const wchar_t *name=NULL, const wchar_t *default_val=NULL)
+ : Attribute(name) {
+ setData(default_val, true);
+ }
+
+ /**
+ Get the attribute type. This will return
+ a constant representing the attribute type.
+
+ These constants can be: BOOL, FLOAT, STRING and INT.
+
+ @see AttributeType
+ @ret The attribute type.
+ */
+ virtual int getAttributeType() { return AttributeType::STRING; }
+
+ /**
+ Get the configuration group to be used to represent
+ this attribute in the registry.
+
+ @ret Config group to be used.
+ */
+ virtual const wchar_t *getConfigGroup() { return L"studio.configgroup.string"; }
+
+//CUT virtual int getPermissions() { return ATTR_PERM_ALL; }
+
+ /**
+ Get the value of the attribute.
+
+ @ret The value of the attribute
+ */
+ const wchar_t *getValue();
+
+ /**
+ Set the value of the attribute.
+
+ @param val The value you want to set.
+ @ret 1, success; 0, failure;
+ */
+ int setValue(const wchar_t *val) { return setData(val); }
+
+ // convenience operators
+ /**
+ Get the value of the attribute.
+ */
+ operator const wchar_t *() { return getValue(); }
+
+ /**
+ Set the value of the attribute.
+ */
+ const wchar_t *operator =(const wchar_t *newval) { return setValue(newval) ? newval : getValue(); }
+
+private:
+ StringW returnval;
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/cfgitem.h b/Src/Wasabi/api/config/items/cfgitem.h
new file mode 100644
index 00000000..560198f0
--- /dev/null
+++ b/Src/Wasabi/api/config/items/cfgitem.h
@@ -0,0 +1,233 @@
+#ifndef _CFGITEM_H
+#define _CFGITEM_H
+
+#include <bfc/dispatch.h>
+#include <bfc/platform/types.h>
+#include <bfc/platform/guid.h>
+#include <bfc/wasabi_std.h>
+
+class ifc_dependent;
+class ifc_window;
+
+/* A CfgItem is a named, possibly unique (if GUID is set) interface to
+an object with 0 or more named attributes. If offers api_dependent-based callbacks
+when those attributes change.
+*/
+
+// abstract base class presented to the world
+/**
+
+
+ @short Base Config Item
+ @ver 1.0
+ @author Nullsoft
+ @see CfgItemI
+*/
+class NOVTABLE CfgItem : public Dispatchable
+{
+public:
+ /**
+ */
+ static const GUID *depend_getClassGuid() {
+ // {B4BE480E-2005-457c-A445-294F12387E74}
+ static const GUID ret =
+ { 0xb4be480e, 0x2005, 0x457c, { 0xa4, 0x45, 0x29, 0x4f, 0x12, 0x38, 0x7e, 0x74 } };
+ return &ret;
+ }
+
+ const wchar_t *getName();
+
+ /**
+ Get the GUID
+ */
+ GUID getGuid();
+
+ /**
+ Get the number of attributes
+ associated with this configuration
+ item.
+
+ @ret Number of attributes for this configuration item.
+ */
+ int getNumAttributes();
+
+ const wchar_t *enumAttribute(int n);
+
+ // so people can watch you for changes
+ ifc_dependent *getDependencyPtr();
+
+ // return * to your config xml if you want to specify it
+ const wchar_t *getConfigXML();
+ void onCfgGroupCreate(ifc_window *cfggroup, const wchar_t *attrname=NULL);
+ void onCfgGroupDelete(ifc_window *cfggroup);
+
+ // if you have child cfgitems, list them here
+ int getNumChildren();
+ CfgItem *enumChild(int n);
+ GUID getParentGuid();
+
+ void onRegister(); // kernel calls these
+ void onDeregister();
+
+ int getAttributeType(const wchar_t *name);
+ const wchar_t *getAttributeConfigGroup(const wchar_t *name);
+ int getDataLen(const wchar_t *name);
+ int getData(const wchar_t *name, wchar_t *data, int data_len);
+ int setData(const wchar_t *name, const wchar_t *data);
+
+ int getDataAsInt(const wchar_t *name, int def_val=0)
+ {
+ wchar_t buf[256];
+ if (getData(name, buf, sizeof(buf))==-1) return def_val;
+ return WTOI(buf);
+ }
+ void setDataAsInt(const wchar_t *name, int val) {
+ wchar_t buf[256];
+ WCSNPRINTF(buf, 256, L"%d", val); // this uses SPRINTF ON PURPOSE, motherfucker BU
+ setData(name, buf);
+ }
+
+ double getDataAsFloat(const wchar_t *name, double def_val=0) {
+ wchar_t buf[256];
+ if (getData(name, buf, sizeof(buf))==-1) return def_val;
+ return WTOF(buf);
+ }
+ void setDataAsFloat(const wchar_t *name, double val) {
+ wchar_t buf[256];
+ WCSNPRINTF(buf, 256, L"%f", val); // this uses SPRINTF ON PURPOSE, motherfucker BU
+ setData(name, buf);
+ }
+
+ int addAttribute(const wchar_t *name, const wchar_t *defval);
+ int delAttribute(const wchar_t *name);
+
+ enum {
+ Event_ATTRIBUTE_ADDED=100, // ptr is name of attrib
+ Event_ATTRIBUTE_REMOVED=200,// ptr is name of attrib
+ Event_ATTRIBUTE_CHANGED=300, // ptr is name of attrib
+ Event_NAMECHANGE=400,
+ };
+
+protected:
+ enum {
+ CFGITEM_GETNAME=100,
+ CFGITEM_GETGUID=110,
+ CFGITEM_GETNUMATTRIBUTES=200,
+ CFGITEM_ENUMATTRIBUTE=210,
+ CFGITEM_GETDEPENDENCYPTR=300,
+ CFGITEM_GETNUMCHILDREN=400,
+ CFGITEM_ENUMCHILD=410,
+ CFGITEM_GETPARENTGUID=420,
+ CFGITEM_ONREGISTER=500,
+ CFGITEM_ONDEREGISTER=510,
+ CFGITEM_GETCONFIGXML=600,
+ CFGITEM_ONCFGGROUPCREATE=610,
+ CFGITEM_ONCFGGROUPDELETE=620,
+ CFGITEM_GETATTRIBUTETYPE=700,
+ CFGITEM_GETATTRIBUTECONFIGGROUP=710,
+ CFGITEM_GETDATALEN=800,
+ CFGITEM_GETDATA=810,
+ CFGITEM_SETDATA=820,
+ CFGITEM_ADDATTRIB=830,
+ CFGITEM_DELATTRIB=840,
+ };
+};
+
+inline const wchar_t *CfgItem::getName() {
+ return _call(CFGITEM_GETNAME, L"");
+}
+
+inline GUID CfgItem::getGuid() {
+ return _call(CFGITEM_GETGUID, INVALID_GUID);
+}
+
+inline int CfgItem::getNumAttributes() {
+ return _call(CFGITEM_GETNUMATTRIBUTES, 0);
+}
+
+inline const wchar_t *CfgItem::enumAttribute(int n) {
+ return _call(CFGITEM_ENUMATTRIBUTE, (const wchar_t *)NULL, n);
+}
+
+inline ifc_dependent *CfgItem::getDependencyPtr() {
+ return _call(CFGITEM_GETDEPENDENCYPTR, (ifc_dependent*)NULL);
+}
+
+inline const wchar_t *CfgItem::getConfigXML() {
+ return _call(CFGITEM_GETCONFIGXML, (const wchar_t*)NULL);
+}
+
+inline void CfgItem::onCfgGroupCreate(ifc_window *cfggroup, const wchar_t *attrname) {
+ _voidcall(CFGITEM_ONCFGGROUPCREATE, cfggroup, attrname);
+}
+
+inline void CfgItem::onCfgGroupDelete(ifc_window *cfggroup) {
+ _voidcall(CFGITEM_ONCFGGROUPDELETE, cfggroup);
+}
+
+inline int CfgItem::getNumChildren() {
+ return _call(CFGITEM_GETNUMCHILDREN, 0);
+}
+
+inline CfgItem *CfgItem::enumChild(int n) {
+ return _call(CFGITEM_ENUMCHILD, (CfgItem*)NULL, n);
+}
+
+inline
+GUID CfgItem::getParentGuid() {
+ return _call(CFGITEM_GETPARENTGUID, INVALID_GUID);
+}
+
+inline void CfgItem::onRegister() { _voidcall(CFGITEM_ONREGISTER); }
+inline void CfgItem::onDeregister() { _voidcall(CFGITEM_ONDEREGISTER); }
+
+inline
+int CfgItem::getAttributeType(const wchar_t *name) {
+ return _call(CFGITEM_GETATTRIBUTETYPE, 0, name);
+}
+
+inline
+const wchar_t *CfgItem::getAttributeConfigGroup(const wchar_t *name) {
+ return _call(CFGITEM_GETATTRIBUTECONFIGGROUP, (const wchar_t *)NULL, name);
+}
+
+inline
+int CfgItem::getDataLen(const wchar_t *name) {
+ return _call(CFGITEM_GETDATALEN, -1, name);
+}
+
+inline
+int CfgItem::getData(const wchar_t *name, wchar_t *data, int data_len) {
+ return _call(CFGITEM_GETDATA, -1, name, data, data_len);
+}
+
+inline
+int CfgItem::setData(const wchar_t *name, const wchar_t *data) {
+ return _call(CFGITEM_SETDATA, -1, name, data);
+}
+
+inline
+int CfgItem::addAttribute(const wchar_t *name, const wchar_t *defval) {
+ return _call(CFGITEM_ADDATTRIB, 0, name, defval);
+}
+
+inline
+int CfgItem::delAttribute(const wchar_t *name) {
+ return _call(CFGITEM_DELATTRIB, 0, name);
+}
+
+inline int _intVal(CfgItem *cfgitem, const wchar_t *name, int def_val=0) {
+ if (cfgitem == NULL) return def_val;
+ return cfgitem->getDataAsInt(name, def_val);
+}
+
+#define _int_getValue _intVal
+
+//CUT kill these
+inline void _int_setValue(CfgItem *cfgitem, const wchar_t *name, int val) {
+ cfgitem->setDataAsInt(name, val);
+}
+// CfgItemI is in cfgitemi.h if you need it
+
+
+#endif
diff --git a/Src/Wasabi/api/config/items/cfgitemi.cpp b/Src/Wasabi/api/config/items/cfgitemi.cpp
new file mode 100644
index 00000000..b8734031
--- /dev/null
+++ b/Src/Wasabi/api/config/items/cfgitemi.cpp
@@ -0,0 +1,274 @@
+#include <precomp.h>
+
+#include "cfgitemi.h"
+#include <api/config/items/attrcb.h>
+#include <api/config/items/attribs.h>
+
+#include <bfc/wasabi_std.h>
+#include <bfc/memblock.h>
+
+CfgItemI::CfgItemI(const wchar_t *name, GUID guid)
+:NamedW(name), myguid(guid), parent_guid(INVALID_GUID) { }
+
+CfgItemI::~CfgItemI()
+{
+ deregisterAll();
+}
+
+const wchar_t *CfgItemI::cfgitem_getName()
+{
+ return NamedW::getName();
+}
+
+GUID CfgItemI::cfgitem_getGuid()
+{
+ return myguid;
+}
+
+void CfgItemI::cfgitem_setPrefix(const wchar_t *_prefix)
+{
+ prefix = _prefix;
+}
+
+const wchar_t *CfgItemI::cfgitem_getPrefix()
+{
+ return prefix.c_str();
+}
+
+int CfgItemI::cfgitem_getNumAttributes()
+{
+ return attributes.getNumItems();
+}
+
+const wchar_t *CfgItemI::cfgitem_enumAttribute(int n)
+{
+ Attribute *attr = attributes[n];
+ if (attr) return attr->getAttributeName();
+ return NULL;
+}
+
+const wchar_t *CfgItemI::cfgitem_getConfigXML()
+{
+ return cfgxml.c_str();
+}
+
+int CfgItemI::cfgitem_getNumChildren()
+{
+ return children.getNumItems();
+}
+
+CfgItem *CfgItemI::cfgitem_enumChild(int n)
+{
+ return children[n];
+}
+
+GUID CfgItemI::cfgitem_getParentGuid()
+{
+ return parent_guid;
+}
+
+void CfgItemI::cfgitem_onRegister()
+{
+ foreach(children)
+ WASABI_API_CONFIG->config_registerCfgItem(children.getfor());
+ endfor
+}
+void CfgItemI::cfgitem_onDeregister()
+{
+ foreach(children)
+ WASABI_API_CONFIG->config_deregisterCfgItem(children.getfor());
+ endfor
+}
+
+Attribute *CfgItemI::getAttributeByName(const wchar_t *name)
+{
+ Attribute *attr;
+ foreach(attributes)
+ attr = attributes.getfor();
+ if (!WCSICMP(name, attr->getAttributeName())) return attr;
+ endfor
+ return NULL;
+}
+
+int CfgItemI::cfgitem_getAttributeType(const wchar_t *name)
+{
+ Attribute *attr = getAttributeByName(name);
+ if (attr == NULL) return AttributeType::NONE;
+ return attr->getAttributeType();
+}
+
+const wchar_t *CfgItemI::cfgitem_getAttributeConfigGroup(const wchar_t *name)
+{
+ Attribute *attr = getAttributeByName(name);
+ if (attr == NULL) return NULL;
+ return attr->getConfigGroup();
+}
+
+int CfgItemI::cfgitem_getDataLen(const wchar_t *name)
+{
+ Attribute *attr = getAttributeByName(name);
+ if (attr == NULL) return -1;
+ return attr->getDataLen();
+}
+
+int CfgItemI::cfgitem_getData(const wchar_t *name, wchar_t *data, int data_len)
+{
+ Attribute *attr = getAttributeByName(name);
+ if (attr == NULL) return -1;
+ return attr->getData(data, data_len);
+}
+
+int CfgItemI::cfgitem_setData(const wchar_t *name, const wchar_t *data)
+{
+ Attribute *attr = getAttributeByName(name);
+ if (attr == NULL) return -1;
+ int ret = attr->setDataNoCB(data);
+ if (ret) cfgitem_onAttribSetValue(attr);
+ return ret;
+}
+
+int CfgItemI::cfgitem_onAttribSetValue(Attribute *attr)
+{
+ // notify dependency watchers that an attribute changed
+ dependent_sendEvent(CfgItem::depend_getClassGuid(), Event_ATTRIBUTE_CHANGED, 0, (void*)attr->getAttributeName());
+
+ //for (int i = 0; ; i++)
+ //{
+ // AttrCallback *acb;
+ // if (!callbacks.multiGetItem(attr, i, &acb))
+ // break;
+ //
+ // acb->onValueChange(attr);
+ //}
+ auto elements = callbacks.equal_range(attr);
+ for (auto& it = elements.first; it != elements.second; ++it)
+ {
+ AttrCallback* acb = it->second;
+ if (acb)
+ {
+ acb->onValueChange(attr);
+ }
+ }
+
+ return 0;
+}
+
+void CfgItemI::cfgitem_setGUID(GUID guid)
+{
+ myguid = guid;
+}
+
+int CfgItemI::setName(const wchar_t *name)
+{
+ NamedW::setName(name);
+ // notify dependency watchers that name changed?
+ dependent_sendEvent(CfgItem::depend_getClassGuid(), Event_NAMECHANGE);
+ return 1;
+}
+
+int CfgItemI::registerAttribute(Attribute *attr, AttrCallback *acb)
+{
+ if (attributes.haveItem(attr)) return 0;
+ int ret = attributes.addItem(attr) != NULL;
+ if (!ret) return ret;
+
+ attr->setCfgItem(this);
+
+ // set optional callback
+ if (acb != NULL)
+ {
+ addCallback(attr, acb);
+ }
+
+ // notify dependency watchers of new attribute
+ dependent_sendEvent(CfgItem::depend_getClassGuid(), Event_ATTRIBUTE_ADDED, 0, (void*)attr->getAttributeName());
+
+ return ret;
+}
+
+int CfgItemI::deregisterAttribute(Attribute *attr)
+{
+ if (!attributes.haveItem(attr)) return 0;
+ int ret = attributes.removeItem(attr);
+ // notify dependency watchers of attribute going away
+ dependent_sendEvent(CfgItem::depend_getClassGuid(), Event_ATTRIBUTE_REMOVED, 0, (void*)attr->getAttributeName());
+
+ // remove callbacks
+ //callbacks.multiDelAllForItem(attr, TRUE);
+ auto elements = callbacks.equal_range(attr);
+ for (auto& it = elements.first; it != elements.second; ++it)
+ {
+ AttrCallback* acb = it->second;
+ if (acb)
+ {
+ delete acb;
+ }
+ }
+ callbacks.erase(attr);
+
+
+ attr->disconnect();
+
+ return ret;
+}
+
+void CfgItemI::addCallback(Attribute *attr, AttrCallback *acb)
+{
+ ASSERT(attr != NULL);
+ ASSERT(acb != NULL);
+ //callbacks.multiAddItem(attr, acb);
+ callbacks.insert({ attr, acb });
+}
+
+void CfgItemI::deregisterAll()
+{
+ foreach(children)
+ children.getfor()->deregisterAll();
+ endfor
+ while (attributes.getNumItems()) deregisterAttribute(attributes[0]);
+}
+
+void CfgItemI::addChildItem(CfgItemI *child)
+{
+ ASSERT(child != NULL);
+ if (!children.haveItem(child))
+ {
+ children.addItem(child);
+ child->setParentGuid(myguid);
+ }
+}
+
+void CfgItemI::setCfgXml(const wchar_t *groupname)
+{
+ cfgxml = groupname;
+}
+
+void CfgItemI::setParentGuid(GUID guid)
+{
+ parent_guid = guid;
+}
+
+void *CfgItemI::dependent_getInterface(const GUID *classguid)
+{
+ HANDLEGETINTERFACE(CfgItem);
+ return NULL;
+}
+
+int CfgItemI::cfgitem_addAttribute(const wchar_t *name, const wchar_t *defval)
+{
+ if (getAttributeByName(name)) return 0;
+ registerAttribute(newattribs.addItem(new _string(name, defval)));
+ return 1;
+}
+
+int CfgItemI::cfgitem_delAttribute(const wchar_t *name)
+{
+ Attribute *attr = getAttributeByName(name);
+ if (!newattribs.haveItem(attr)) return 0;
+ deregisterAttribute(attr);
+ delete attr;
+ newattribs.removeItem(attr);
+ return 1;
+}
+
+
diff --git a/Src/Wasabi/api/config/items/cfgitemi.h b/Src/Wasabi/api/config/items/cfgitemi.h
new file mode 100644
index 00000000..7824abf5
--- /dev/null
+++ b/Src/Wasabi/api/config/items/cfgitemi.h
@@ -0,0 +1,158 @@
+#ifndef _CFGITEMI_H
+#define _CFGITEMI_H
+
+#include "cfgitemx.h"
+
+#include <bfc/named.h>
+#include <bfc/ptrlist.h>
+#include <bfc/depend.h>
+
+#include <map>
+#include <string>
+
+class AttrCallback;
+class Attribute;
+
+// this is the one you inherit from/use
+/**
+
+ @short Configuration Item
+ @ver 1.0
+ @author Nullsoft
+ @see Attribute
+ @see _bool
+ @see _int
+ @see _float
+ @see _string
+*/
+class CfgItemI : public CfgItemX, public DependentI, private NamedW
+{
+public:
+ /**
+ Optionally sets the name and the GUID of the
+ configuration item if they are specified
+ upon creation of the object.
+
+ @param name Name of the configuration item.
+ @param guid GUID of the configuration item.
+ */
+ CfgItemI(const wchar_t *name=NULL, GUID guid=INVALID_GUID);
+
+ /**
+ Does nothing.
+ */
+ virtual ~CfgItemI();
+
+ /**
+ Get the name of the configuration item.
+
+ @ret Name of the configuration item.
+ */
+ const wchar_t *cfgitem_getName();
+
+ /**
+ Get the GUID of the configuration item.
+
+ @ret GUID of the configuration item.
+ */
+ GUID cfgitem_getGuid();
+
+ /**
+ Sets the prefix to be prepended in the config file for all attributes
+ of this item.
+
+ @see cfgitem_getPrefix
+ @param prefix The prefix.
+ */
+ void cfgitem_setPrefix(const wchar_t *prefix);
+/**
+ Gets the config prefix, if any was set.
+
+ @see cfgitem_setPrefix
+ @ret Pointer to the config prefix.
+*/
+ const wchar_t *cfgitem_getPrefix();
+
+ /**
+ Get the number of attributes registered
+ to this configuration item.
+
+ @ret Number of attributes.
+ */
+ int cfgitem_getNumAttributes();
+
+ /**
+ Enumerate the attributes registered
+ with this configuration item.
+
+ @ret
+ */
+ const wchar_t *cfgitem_enumAttribute(int n);
+
+ const wchar_t *cfgitem_getConfigXML();
+ virtual void cfgitem_onCfgGroupCreate(ifc_window *cfggroup, const wchar_t *attrname) {}
+ virtual void cfgitem_onCfgGroupDelete(ifc_window *cfggroup) {}
+
+ virtual int cfgitem_getNumChildren();
+ virtual CfgItem *cfgitem_enumChild(int n);
+ virtual GUID cfgitem_getParentGuid();
+
+ virtual void cfgitem_onRegister();
+ virtual void cfgitem_onDeregister();
+
+ int cfgitem_getAttributeType(const wchar_t *name);
+ const wchar_t *cfgitem_getAttributeConfigGroup(const wchar_t *name);
+ int cfgitem_getDataLen(const wchar_t *name);
+ int cfgitem_getData(const wchar_t *name, wchar_t *data, int data_len);
+ int cfgitem_setData(const wchar_t *name, const wchar_t *data);
+
+ // override these to catch notifications from attribs, call down
+ virtual int cfgitem_onAttribSetValue(Attribute *attr);
+
+ virtual int cfgitem_usePrivateStorage() { return 0; } //override and return 1 to keep stuff out of system settings
+
+protected:
+ void cfgitem_setGUID(GUID guid);
+
+public:
+ int setName(const wchar_t *name);
+ int registerAttribute(Attribute *attr, AttrCallback *acb=NULL);
+ // does not call delete on the attribute
+ int deregisterAttribute(Attribute *attr);
+ void deregisterAll();
+
+ void addCallback(Attribute *attr, AttrCallback *acb);
+
+ int cfgitem_addAttribute(const wchar_t *name, const wchar_t *defval);
+ int cfgitem_delAttribute(const wchar_t *name);
+
+protected:
+
+ // derived classes can override this to catch name changes
+ virtual void cfgitem_onSetName() { }
+
+ Attribute *getAttributeByName(const wchar_t *name);
+
+ void addChildItem(CfgItemI *child);
+
+ void setCfgXml(const wchar_t *groupname);
+
+ void setParentGuid(GUID guid);
+
+private:
+ api_dependent *cfgitem_getDependencyPtr() { return this; };
+ virtual void *dependent_getInterface(const GUID *classguid);
+
+ // from Named
+ virtual void onSetName() { cfgitem_onSetName(); }
+
+ std::wstring prefix;
+ PtrList<Attribute> attributes;
+ std::multimap<Attribute*, AttrCallback*> callbacks; //CUT
+ PtrList<CfgItemI> children;
+ std::wstring cfgxml;
+ GUID myguid, parent_guid;
+ PtrList<Attribute> newattribs;
+};
+
+#endif
diff --git a/Src/Wasabi/api/config/items/cfgitemx.cpp b/Src/Wasabi/api/config/items/cfgitemx.cpp
new file mode 100644
index 00000000..b656dfc9
--- /dev/null
+++ b/Src/Wasabi/api/config/items/cfgitemx.cpp
@@ -0,0 +1,27 @@
+#include <precomp.h>
+#include "cfgitemx.h"
+
+#define CBCLASS CfgItemX
+START_DISPATCH
+ CB(CFGITEM_GETNAME, cfgitem_getName);
+ CB(CFGITEM_GETGUID, cfgitem_getGuid);
+ CB(CFGITEM_GETNUMATTRIBUTES, cfgitem_getNumAttributes);
+ CB(CFGITEM_ENUMATTRIBUTE, cfgitem_enumAttribute);
+ CB(CFGITEM_GETCONFIGXML, cfgitem_getConfigXML);
+ VCB(CFGITEM_ONCFGGROUPCREATE, cfgitem_onCfgGroupCreate);
+ VCB(CFGITEM_ONCFGGROUPDELETE, cfgitem_onCfgGroupDelete);
+ CB(CFGITEM_GETNUMCHILDREN, cfgitem_getNumChildren);
+ CB(CFGITEM_ENUMCHILD, cfgitem_enumChild);
+ CB(CFGITEM_GETPARENTGUID, cfgitem_getParentGuid);
+ VCB(CFGITEM_ONREGISTER, cfgitem_onRegister);
+ VCB(CFGITEM_ONDEREGISTER, cfgitem_onDeregister);
+ CB(CFGITEM_GETATTRIBUTETYPE, cfgitem_getAttributeType);
+ CB(CFGITEM_GETATTRIBUTECONFIGGROUP, cfgitem_getAttributeConfigGroup);
+ CB(CFGITEM_GETDATALEN, cfgitem_getDataLen);
+ CB(CFGITEM_GETDATA, cfgitem_getData);
+ CB(CFGITEM_SETDATA, cfgitem_setData);
+ CB(CFGITEM_GETDEPENDENCYPTR, cfgitem_getDependencyPtr);
+ CB(CFGITEM_ADDATTRIB, cfgitem_addAttribute);
+ CB(CFGITEM_DELATTRIB, cfgitem_delAttribute);
+END_DISPATCH
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/Wasabi/api/config/items/cfgitemx.h b/Src/Wasabi/api/config/items/cfgitemx.h
new file mode 100644
index 00000000..6d5a9408
--- /dev/null
+++ b/Src/Wasabi/api/config/items/cfgitemx.h
@@ -0,0 +1,42 @@
+#ifndef NULLSOFT_WASABI_CFGITEMX_H
+#define NULLSOFT_WASABI_CFGITEMX_H
+
+#include "cfgitem.h"
+
+class CfgItemX : public CfgItem
+{
+public:
+ virtual ~CfgItemX() {}
+ virtual const wchar_t *cfgitem_getName()=0;
+ virtual GUID cfgitem_getGuid()=0;
+ virtual int cfgitem_getNumAttributes()=0;
+ virtual const wchar_t *cfgitem_enumAttribute(int n)=0;
+ virtual const wchar_t *cfgitem_getConfigXML()=0;
+ virtual void cfgitem_onCfgGroupCreate(ifc_window *cfggroup, const wchar_t *attrname)=0;
+ virtual void cfgitem_onCfgGroupDelete(ifc_window *cfggroup)=0;
+
+ virtual int cfgitem_getNumChildren()=0;
+ virtual CfgItem *cfgitem_enumChild(int n)=0;
+ virtual GUID cfgitem_getParentGuid()=0;
+
+ virtual void cfgitem_onRegister()=0;
+ virtual void cfgitem_onDeregister()=0;
+
+ virtual int cfgitem_getAttributeType(const wchar_t *name)=0;
+ virtual const wchar_t *cfgitem_getAttributeConfigGroup(const wchar_t *name)=0;
+
+ virtual int cfgitem_getDataLen(const wchar_t *name)=0;
+ virtual int cfgitem_getData(const wchar_t *name, wchar_t *data, int data_len)=0;
+ virtual int cfgitem_setData(const wchar_t *name, const wchar_t *data)=0;
+ virtual ifc_dependent *cfgitem_getDependencyPtr()=0;
+ virtual int cfgitem_delAttribute(const wchar_t *name)=0;
+ virtual int cfgitem_addAttribute(const wchar_t *name, const wchar_t *defval)=0;
+
+protected:
+ RECVS_DISPATCH;
+
+
+};
+
+
+#endif \ No newline at end of file
diff --git a/Src/Wasabi/api/config/items/intarray.cpp b/Src/Wasabi/api/config/items/intarray.cpp
new file mode 100644
index 00000000..c6ba4676
--- /dev/null
+++ b/Src/Wasabi/api/config/items/intarray.cpp
@@ -0,0 +1,49 @@
+#include <precomp.h>
+
+#include "intarray.h"
+
+
+enum { MAX_ARRAY=8 };
+
+int IntArray::read(const wchar_t *name, int *x1, int *x2, int *x3, int *x4, int *x5, int *x6, int *x7, int *x8) {
+ PtrList<int> list;
+ if (x1) { list.addItem(x1); }
+ if (x2) { list.addItem(x2); }
+ if (x3) { list.addItem(x3); }
+ if (x4) { list.addItem(x4); }
+ if (x5) { list.addItem(x5); }
+ if (x6) { list.addItem(x6); }
+ if (x7) { list.addItem(x7); }
+ if (x8) { list.addItem(x8); }
+ ASSERT(list.getNumItems() >= 1);
+
+ int array[MAX_ARRAY]; // gcc rules, msvc drools
+ for (int i = 0; i < list.getNumItems(); i++) {
+ if (list[i]) array[i] = *list[i];
+ }
+ if (!WASABI_API_CONFIG->getIntArrayPrivate(name, array, list.getNumItems())) return 0;
+ for (int j = 0; j < list.getNumItems(); j++) {
+ if (list[j]) *list[j] = array[j];
+ }
+ return 1;
+}
+
+void IntArray::write(const wchar_t *name, int x1) {
+ int array[] = { x1 };
+ WASABI_API_CONFIG->setIntArrayPrivate(name, array, sizeof(array)/sizeof(int));
+}
+
+void IntArray::write(const wchar_t *name, int x1, int x2) {
+ int array[] = { x1, x2 };
+ WASABI_API_CONFIG->setIntArrayPrivate(name, array, sizeof(array)/sizeof(int));
+}
+
+void IntArray::write(const wchar_t *name, int x1, int x2, int x3) {
+ int array[] = { x1, x2, x3 };
+ WASABI_API_CONFIG->setIntArrayPrivate(name, array, sizeof(array)/sizeof(int));
+}
+
+void IntArray::write(const wchar_t *name, int x1, int x2, int x3, int x4) {
+ int array[] = { x1, x2, x3, x4 };
+ WASABI_API_CONFIG->setIntArrayPrivate(name, array, sizeof(array)/sizeof(int));
+}
diff --git a/Src/Wasabi/api/config/items/intarray.h b/Src/Wasabi/api/config/items/intarray.h
new file mode 100644
index 00000000..edb26322
--- /dev/null
+++ b/Src/Wasabi/api/config/items/intarray.h
@@ -0,0 +1,18 @@
+#ifndef _INTARRAY_H
+#define _INTARRAY_H
+
+#include <bfc/common.h>
+#include <bfc/named.h>
+#include <bfc/ptrlist.h>
+
+class IntArray
+{
+public:
+ static int read(const wchar_t *name, int *x1, int *x2=NULL, int *x3=NULL, int *x4=NULL, int *x5=NULL, int *x6=NULL, int *x7=NULL, int *x8=NULL);
+ static void write(const wchar_t *name, int x1);
+ static void write(const wchar_t *name, int x1, int x2);
+ static void write(const wchar_t *name, int x1, int x2, int x3);
+ static void write(const wchar_t *name, int x1, int x2, int x3, int x4);
+};
+
+#endif