Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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));
}

View file

@ -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