#pragma once #include #include #include #include #include namespace hgl { using namespace io; template class PAttribBase { public: PAttribBase()=default; virtual ~PAttribBase()=default; virtual const bool ParseFromString(const String &str)=0; virtual String MakeToString()const=0; }; template class PAttrib:public PAttribBase { protected: String name; T value; T default_value; public: PAttrib(const String &n,const T &v) { name=n; value=v; default_value=v; } virtual ~PAttrib()=default; virtual const bool ParseFromString(const String &str)=0; virtual String MakeToString()const=0; virtual const T &Get(){return value;} virtual void Set(const T &v){value=v;} };//template class PAttrib template class PNumberAttrib:public PAttrib { protected: T min_value,max_value; public: PNumberAttrib(const String &n,const T &dv,const T &min_v,const T &max_v):PAttrib(n,dv) { min_value=min_v; max_value=max_v; } virtual ~PNumberAttrib()=default; const bool ParseFromString(const String &str) override { if(ToNumber(str,this->value)) { if(this->value>=min_value&&this->value<=max_value) return(true); } this->value=this->default_value; return(false); } String MakeToString() const override { return String::numberOf(this->value); } };//class PNumberAttrib:public PAttrib template using PIntAttrib =PNumberAttrib; template using PUintAttrib =PNumberAttrib; template class PFloatNumberAttrib:public PAttrib { protected: T min_value,max_value; uint frac; public: PFloatNumberAttrib(const String &n,const T &dv,const T &min_v,const T &max_v,const int f):PAttrib(n,dv) { min_value=min_v; max_value=max_v; frac=f; } virtual ~PFloatNumberAttrib()=default; const bool ParseFromString(const String &str) override { if(ToNumber(str,this->value)) { if(this->value>=min_value&&this->value<=max_value) return(true); } this->value=this->default_value; return(false); } void SetFrac(uint f){frac=f;} String MakeToString() const override { return String::floatOf(this->value,frac); } };//class PFloatNumberAttrib:public PAttrib template using PFloatAttrib =PFloatNumberAttrib; template using PDoubleAttrib=PFloatNumberAttrib; template class PBoolAttrib:public PAttrib { public: using PAttrib::PAttrib; const bool ParseFromString(const String &str) { if(str.ToBool(this->value)) return(true); this->value=this->default_value; return(false); } String MakeToString() const override { return(this->value?"true":"false"); } }; template class PStringAttrib:public PAttrib> { public: using PAttrib>::PAttrib; const bool ParseFromString(const String &str) override { this->value=str; return(true); } String MakeToString() const override { return this->value; } }; template using PAttribMap=Map,PAttribBase *>; /** * 向属性列表中写入一个属性 */ template static bool Add(PAttribMap &pa_map,const String &str) { String name; C *value; int off; if(str.Length()<2)return(false); if(((off=str.FindChar(C('\t')))==-1) &&((off=str.FindChar(C(' '))) ==-1) &&((off=str.FindChar(C('='))) ==-1) &&((off=str.FindChar(C(':'))) ==-1)) return(false); name.Strcpy(str,off); off++; value=str.c_str()+off; while(true) { if(*value == C('\t') ||*value == C('=') ||*value == C(' ') ||*value == C(':')) { value++; continue; } break; } PAttribBase *attr=GetObjectFromList(pa_map,name); if(attr) attr->ParseFromString(value); return(true); } template class PAttribSet { using PString=String; using PStringList=StringList; PAttribMap pa_map; public: operator PAttribMap &() {return pa_map;} operator const PAttribMap &()const {return pa_map;} public: template PNumberAttrib *CreateNumberAttrib(const PString &name,const T &dv,const T &min_v,const T &max_v) { PNumberAttrib *obj=new PNumberAttrib(name,dv,min_v,max_v); pa_map.Add(name,obj); return obj; } /** * 创建一个浮点数属性 * @param name 属性名称 * @param dv 默认值 * @param min_v 最小值 * @param max_v 最大值 * @param frac 小数点后位数 * @return 属性对象 */ template PFloatNumberAttrib *CreateFloatAttrib(const PString &name,const T &dv,const T &min_v,const T &max_v,const int frac) { PFloatNumberAttrib *obj=new PFloatNumberAttrib(name,dv,min_v,max_v,frac); pa_map.Add(name,obj); return obj; } PBoolAttrib *CreateBoolAttrib(const PString &name,const bool &dv) { PBoolAttrib *obj=new PBoolAttrib(name,dv); pa_map.Add(name,obj); return obj; } PStringAttrib *CreateStringAttrib(const PString &name,const PString &dv) { PStringAttrib *obj=new PStringAttrib(name,dv); pa_map.Add(name,obj); return obj; } public: bool Add(const PString &name,PAttribBase *attr) { return pa_map.Add(name,attr); } bool Add(const PString &str) { return Add(pa_name,str); } PAttribBase *Get(const PString &name){return GetObjectFromList(pa_map,name);} void Delete(const PString &name){pa_map.DeleteByKey(name);} void Clear(){pa_map.Clear();} void ClearData(){pa_map.ClearData();} void Enum(void (*enum_func)(const String &key,PAttribBase * &value)) { pa_map.Enum(enum_func); }; };//template class PAttribSet using UTF8PAttribSet =PAttribSet; using UTF16PAttribSet =PAttribSet; using WidePAttribSet =PAttribSet; using OSPAttribSet =PAttribSet; }//namespace hgl