#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 BaseString &str)=0; virtual BaseString MakeToString()const=0; }; template class PAttrib:public PAttribBase { protected: BaseString name; T value; T default_value; public: PAttrib(const BaseString &n,const T &v) { name=n; value=v; default_value=v; } virtual ~PAttrib()=default; virtual const bool ParseFromString(const BaseString &str)=0; virtual BaseString 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 BaseString &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 BaseString &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); } BaseString MakeToString() const override { return BaseString(this->value); } };//class PNumberAttrib:public PAttrib template using PIntAttrib =PNumberAttrib; template using PUintAttrib =PNumberAttrib; template using PFloatAttrib =PNumberAttrib; template using PDoubleAttrib=PNumberAttrib; template class PBoolAttrib:public PAttrib { public: using PAttrib::PAttrib; const bool ParseFromString(const BaseString &str) { if(str.ToBool(this->value)) return(true); this->value=this->default_value; return(false); } BaseString MakeToString() const override { return(this->value?"true":"false"); } }; template class PStringAttrib:public PAttrib> { public: using PAttrib>::PAttrib; const bool ParseFromString(const BaseString &str) override { this->value=str; return(true); } BaseString MakeToString() const override { return this->value; } }; template class PAttribSet { using PString=BaseString; using PStringList=StringList; Map,PAttribBase *> 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; } 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); } PAttribBase *Get(const PString &name){return GetObject(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 BaseString &key,PAttribBase *value)) { pa_map.Enum(enum_func); }; public: /** * 保存到文本文件中 */ template bool SaveToTextFile(const OSString &filename,const PString &gap_ch=PString("\t")) ///<保存列表到文件 { FileOutputStream fos; EndianTextOutputStream tos(&fos); if(!fos.CreateTrunc(filename))return(false); tos.WriteBOM(); const int count=pa_map.GetCount(); auto **pa_obj=pa_map.GetDataList(); for(int i=0;ileft); tos.WriteString(gap_ch); tos.WriteString((*pa_obj)->right->MakeToString()); tos.WriteLineEnd(); ++pa_obj; } return(true); } private: bool Add(const PString &str) ///<向列表中增加一项 { PString 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=Get(name); if(attr) attr->ParseFromString(value); return(true); } public: /** * 从文本文件中加载 */ virtual bool LoadFromTextFile(const OSString &filename) ///<从文件中加载列表 { PStringList sl; if(LoadStringListFromTextFile(sl,filename)<=0) return(false); int n=sl.GetCount(); while(n--) Add(sl[n]); return(true); } };//template class PAttribSet using UTF8PAttribSet =PAttribSet; using UTF16PAttribSet =PAttribSet; using WidePAttribSet =PAttribSet; using OSPAttribSet =PAttribSet; }//namespace hgl