~Beschreibung~
DataCollectoren sind nichts anderes als eine TList in einer TList in einer TList... , nur das man diese Einträge nun gezielt benennen kann.
z.b. sind aufbauten wie:
Code: [AUSKLAPPEN] [EINKLAPPEN] Data
|-SubData
||-Int "Data" = 0
|-String "Hallo" = "Welt"
möglich ohne größere Probleme.
Bis jetzt kann man einen DataCollector als Datei, komprimierte Datei oder komprimierte Bank zurückerhalten und laden.
~Der Code~
BlitzMax: [AUSKLAPPEN] [EINKLAPPEN] Const DC_TYPE_CNTR:Byte = %00000000 Const DC_TYPE_BANK:Byte = %00000001 Const DC_TYPE_STNG:Byte = %00000010 Const DC_TYPE_BYTE:Byte = %00000011 Const DC_TYPE_SHRT:Byte = %00000100 Const DC_TYPE_INTE:Byte = %00000101 Const DC_TYPE_LONG:Byte = %00000110 Const DC_TYPE_FLOT:Byte = %00000111 Const DC_TYPE_DBLE:Byte = %00001000 Const DC_FRMT_CNTR_OPEN:Byte = %11111100 Const DC_FRMT_CNTR_CLSE:Byte = %11111110
Type DC Field m_Parent:DC, m_Link:TLink Field m_Name:String Field m_Type:Byte Field m_Data:Object Method GetDataDC:DC() Return DC(m_Data) End Method Method GetDataBank:TBank() Return TBank(m_Data) End Method Method GetDataString:String() Return String(m_Data) End Method Method GetDataByte:Byte() Return TBank(m_Data).PeekByte(0) EndMethod Method GetDataShort:Short() Return TBank(m_Data).PeekShort(0) End Method Method GetDataInt:Int() Return TBank(m_Data).PeekInt(0) End Method Method GetDataLong:Long() Return TBank(m_Data).PeekLong(0) End Method Method GetDataFloat:Float() Return TBank(m_Data).PeekFloat(0) End Method Method GetDataDouble:Double() Return TBank(m_Data).PeekDouble(0) End Method Method SetDataDC:DC(Data:DC) Local DC:DC = DC(m_Data) m_Data = Data Return DC End Method Method SetDataBank(Data:TBank) TBank(m_Data).Resize(Data.Size()) CopyBank(Data, 0, TBank(Self.m_Data), 0, Data.Size()) End Method Method SetDataString(Data:String) m_Data = Data End Method Method SetDataByte(Data:Byte) TBank(m_Data).PokeByte(0, Data) EndMethod Method SetDataShort(Data:Short) TBank(m_Data).PokeShort(0, Data) EndMethod Method SetDataInt(Data:Int) TBank(m_Data).PokeInt(0, Data) EndMethod Method SetDataLong(Data:Long) TBank(m_Data).PokeLong(0, Data) EndMethod Method SetDataFloat(Data:Float) TBank(m_Data).PokeFloat(0, Data) EndMethod Method SetDataDouble(Data:Double) TBank(m_Data).PokeDouble(0, Data) EndMethod Method GetName:String() Return m_Name End Method Method SetName(Name:String) m_Name = Name End Method Method AddContainer:DC(Name:String) If m_Type = DC_TYPE_CNTR Local DC:DC = New DC DC.m_Parent = Self DC.m_Name = Name DC.m_Type = DC_TYPE_CNTR DC.m_Data = New TList m_Link = TList(m_Data).AddLast(DC) Return DC End If End Method Method AddBank:DC(Name:String, Data:TBank) If m_Type = DC_TYPE_CNTR Local DC:DC = New DC DC.m_Parent = Self DC.m_Name = Name DC.m_Type = DC_TYPE_BANK DC.m_Data = CreateBank(Data.Size()) CopyBank(Data, 0, TBank(DC.m_Data), 0, Data.Size()) m_Link = TList(m_Data).AddLast(DC) Return DC End If End Method Method AddString:DC(Name:String, Data:String) If m_Type = DC_TYPE_CNTR Local DC:DC = New DC DC.m_Name = Name DC.m_Type = DC_TYPE_STNG DC.m_Data = Data DC.m_Parent = Self m_Link = TList(m_Data).AddLast(DC) Return DC End If End Method Method AddByte:DC(Name:String, Data:Byte) If m_Type = DC_TYPE_CNTR Local DC:DC = New DC DC.m_Parent = Self DC.m_Name = Name DC.m_Type = DC_TYPE_BYTE DC.m_Data = CreateBank(1) TBank(DC.m_Data).PokeByte(0, Data) m_Link = TList(m_Data).AddLast(DC) Return DC End If End Method Method AddShort:DC(Name:String, Data:Short) If m_Type = DC_TYPE_CNTR Local DC:DC = New DC DC.m_Parent = Self DC.m_Name = Name DC.m_Type = DC_TYPE_SHRT DC.m_Data = CreateBank(2) TBank(DC.m_Data).PokeShort(0, Data) m_Link = TList(m_Data).AddLast(DC) Return DC End If End Method Method AddInt:DC(Name:String, Data:Int) If m_Type = DC_TYPE_CNTR Local DC:DC = New DC DC.m_Parent = Self DC.m_Name = Name DC.m_Type = DC_TYPE_INTE DC.m_Data = CreateBank(4) TBank(DC.m_Data).PokeInt(0, Data) m_Link = TList(m_Data).AddLast(DC) Return DC End If End Method Method AddLong:DC(Name:String, Data:Long) If m_Type = DC_TYPE_CNTR Local DC:DC = New DC DC.m_Parent = Self DC.m_Name = Name DC.m_Type = DC_TYPE_LONG DC.m_Data = CreateBank(8) TBank(DC.m_Data).PokeLong(0, Data) m_Link = TList(m_Data).AddLast(DC) Return DC End If End Method Method AddFloat:DC(Name:String, Data:Float) If m_Type = DC_TYPE_CNTR Local DC:DC = New DC DC.m_Parent = Self DC.m_Name = Name DC.m_Type = DC_TYPE_FLOT DC.m_Data = CreateBank(4) TBank(DC.m_Data).PokeFloat(0, Data) m_Link = TList(m_Data).AddLast(DC) Return DC End If End Method Method AddDouble:DC(Name:String, Data:Double) If m_Type = DC_TYPE_CNTR Local DC:DC = New DC DC.m_Parent = Self DC.m_Name = Name DC.m_Type = DC_TYPE_DBLE DC.m_Data = CreateBank(8) TBank(DC.m_Data).PokeDouble(0, Data) m_Link = TList(m_Data).AddLast(DC) Return DC End If End Method Method New() End Method Method Destroy() If m_Parent <> Null TList(m_Parent.m_Data).Remove(Self) m_Parent.Sort() End If If m_Type = DC_TYPE_CNTR For Local dcData:DC = EachIn TList(m_Data) dcData.Destroy() dcData = Null Next TList(m_Data).clear() End If m_Parent = Null m_Link = Null m_Name = Null m_Type = Null m_Data = Null End Method Method Save:Byte(File:String) If m_Type = DC_TYPE_CNTR And m_Parent = Null Local fStream:TStream = WriteFile(File) If fStream Self.Write(fStream) CloseFile(fStream) Return True Else Return False EndIf Else Return False End If End Method Method SaveCompressed:Byte(File:String, Compression:Int = 9) If m_Type = DC_TYPE_CNTR And m_Parent = Null Local iSize:Int Self.GetSize(iSize) Local fBank:TBank = CreateBank(iSize) Local fStream:TBankStream = CreateBankStream(fBank) If fStream Self.Write(fStream) Local fromBankSize:Int = fStream.Size() Local fromBank:TBank = CreateBank(fromBankSize) Local destBankSize:Int = Ceil(fromBankSize * 1.001) + 2 + 4 Local destBank:TBank = CreateBank(destBankSize) fStream.Seek(0) fromBank.Read(fStream, 0, fromBankSize) compress2(destBank.Buf(), destBankSize, fromBank.Buf(), fromBankSize, Compression) destBank.Resize(destBankSize) Local fStream2:TStream = WriteFile(File) If fStream2 fStream2.WriteInt(fromBankSize) destBank.Write(fStream2, 0, destBankSize) CloseFile fStream2 fStream = Null;fStream2 = Null fromBank = Null;destBank = Null fBank = Null Else fStream = Null;fStream2 = Null fromBank = Null;destBank = Null fBank = Null Return False End If Else fBank = Null fStream = Null Return False EndIf Else Return False End If End Method Method SaveBank:TBank(Compression:Int = 9) Local fBank:TBank = CreateBank(4) If fBank <> Null Local bStream:TBankStream = CreateBankStream(fBank) If bStream Self.Write(bStream) Local fromBankSize:Int = bStream.Size() Local fromBank:TBank = CreateBank(fromBankSize) Local destBankSize:Int = Ceil(fromBankSize * 1.001) + 2 + 4 Local destBank:TBank = CreateBank(destBankSize) bStream.Seek(0) fromBank.Read(bStream, 0, fromBankSize) compress2(destBank.Buf(), destBankSize, fromBank.Buf(), fromBankSize, Compression) destBank.Resize(destBankSize + 4) destBank.PokeInt(destBankSize, fromBankSize) fromBank = Null bStream = Null fBank = Null Return destBank Else fBank = Null Return Null EndIf Else Return Null End If End Method Method FindChild:DC(Name:String) If m_Type = DC_TYPE_CNTR For Local dcData:DC = EachIn TList(m_Data) If dcData.m_Name = Name Return dcData End If Next End If End Method Method GetContents:DC[] () If m_Type = DC_TYPE_CNTR Return DC[] (TList(m_Data).ToArray()) EndIf End Method Method Sort() If m_Type = DC_TYPE_CNTR TList(m_Data).Sort(True, _DC_SortFunc) End If End Method Method GetSize(iSize:Int Var) Select m_Type Case DC_TYPE_CNTR iSize = iSize + 7 + m_Name.length For Local dcData:DC = EachIn TList(m_Data) dcData.GetSize(iSize) Next Case DC_TYPE_BANK iSize = iSize + 9 + m_Name.Length + TBank(m_Data).Size() Case DC_TYPE_STNG iSize = iSize + 9 + m_Name.Length + String(m_Data).length Case DC_TYPE_BYTE iSize = iSize + 6 + m_Name.Length Case DC_TYPE_SHRT iSize = iSize + 7 + m_Name.Length Case DC_TYPE_INTE, DC_TYPE_FLOT iSize = iSize + 9 + m_Name.Length Case DC_TYPE_DBLE, DC_TYPE_LONG iSize = iSize + 13 + m_Name.Length End Select End Method Method Write(fStream:TStream) fStream.WriteByte(m_Type) Select m_Type Case DC_TYPE_CNTR fStream.WriteInt(m_Name.Length) fStream.WriteString(m_Name) fStream.WriteByte(DC_FRMT_CNTR_OPEN) For Local dcData:DC = EachIn TList(m_Data) dcData.Write(fStream) Next fStream.WriteByte(DC_FRMT_CNTR_CLSE) Case DC_TYPE_BANK fStream.WriteInt(m_Name.Length) fStream.WriteString(m_Name) fStream.WriteInt(TBank(m_Data).Size()) fStream.Write(TBank(m_Data).Buf(), TBank(m_Data).Size()) Case DC_TYPE_STNG fStream.WriteInt(m_Name.Length) fStream.WriteString(m_Name) fStream.WriteInt(String(m_Data).Length) fStream.WriteString(String(m_Data)) Case DC_TYPE_BYTE fStream.WriteInt(m_Name.Length) fStream.WriteString(m_Name) fStream.Write(TBank(m_Data).Buf(), 1) Case DC_TYPE_SHRT fStream.WriteInt(m_Name.Length) fStream.WriteString(m_Name) fStream.Write(TBank(m_Data).Buf(), 2) Case DC_TYPE_INTE, DC_TYPE_FLOT fStream.WriteInt(m_Name.Length) fStream.WriteString(m_Name) fStream.Write(TBank(m_Data).Buf(), 4) Case DC_TYPE_DBLE, DC_TYPE_LONG fStream.WriteInt(m_Name.Length) fStream.WriteString(m_Name) fStream.Write(TBank(m_Data).Buf(), 8) End Select End Method End Type
Function _DC_SortFunc:Int(so1:Object, so2:Object) Local o1:DC = DC(so1), o2:DC = DC(so2) Select o1.m_Type Case DC_TYPE_CNTR Select o2.m_Type Case DC_TYPE_CNTR Return 0 Case DC_TYPE_BANK Return 1 Case DC_TYPE_STNG Return 1 Case DC_TYPE_BYTE Return 1 Case DC_TYPE_SHRT Return 1 Case DC_TYPE_INTE Return 1 Case DC_TYPE_LONG Return 1 Case DC_TYPE_FLOT Return 1 Case DC_TYPE_DBLE Return 1 End Select Case DC_TYPE_BANK Select o2.m_Type Case DC_TYPE_CNTR Return - 1 Case DC_TYPE_BANK Return 0 Case DC_TYPE_STNG Return 1 Case DC_TYPE_BYTE Return 1 Case DC_TYPE_SHRT Return 1 Case DC_TYPE_INTE Return 1 Case DC_TYPE_LONG Return 1 Case DC_TYPE_FLOT Return 1 Case DC_TYPE_DBLE Return 1 End Select Case DC_TYPE_STNG Select o2.m_Type Case DC_TYPE_CNTR Return - 1 Case DC_TYPE_BANK Return - 1 Case DC_TYPE_STNG Return 0 Case DC_TYPE_BYTE Return 1 Case DC_TYPE_SHRT Return 1 Case DC_TYPE_INTE Return 1 Case DC_TYPE_LONG Return 1 Case DC_TYPE_FLOT Return 1 Case DC_TYPE_DBLE Return 1 End Select Case DC_TYPE_BYTE Select o2.m_Type Case DC_TYPE_CNTR Return - 1 Case DC_TYPE_BANK Return - 1 Case DC_TYPE_STNG Return - 1 Case DC_TYPE_BYTE Return 0 Case DC_TYPE_SHRT Return 1 Case DC_TYPE_INTE Return 1 Case DC_TYPE_LONG Return 1 Case DC_TYPE_FLOT Return 1 Case DC_TYPE_DBLE Return 1 End Select Case DC_TYPE_SHRT Select o2.m_Type Case DC_TYPE_CNTR Return - 1 Case DC_TYPE_BANK Return - 1 Case DC_TYPE_STNG Return - 1 Case DC_TYPE_BYTE Return - 1 Case DC_TYPE_SHRT Return 0 Case DC_TYPE_INTE Return 1 Case DC_TYPE_LONG Return 1 Case DC_TYPE_FLOT Return 1 Case DC_TYPE_DBLE Return 1 End Select Case DC_TYPE_INTE Select o2.m_Type Case DC_TYPE_CNTR Return - 1 Case DC_TYPE_BANK Return - 1 Case DC_TYPE_STNG Return - 1 Case DC_TYPE_BYTE Return - 1 Case DC_TYPE_SHRT Return - 1 Case DC_TYPE_INTE Return 0 Case DC_TYPE_LONG Return 1 Case DC_TYPE_FLOT Return 1 Case DC_TYPE_DBLE Return 1 End Select Case DC_TYPE_LONG Select o2.m_Type Case DC_TYPE_CNTR Return - 1 Case DC_TYPE_BANK Return - 1 Case DC_TYPE_STNG Return - 1 Case DC_TYPE_BYTE Return - 1 Case DC_TYPE_SHRT Return - 1 Case DC_TYPE_INTE Return - 1 Case DC_TYPE_LONG Return 0 Case DC_TYPE_FLOT Return 1 Case DC_TYPE_DBLE Return 1 End Select Case DC_TYPE_FLOT Select o2.m_Type Case DC_TYPE_CNTR Return - 1 Case DC_TYPE_BANK Return - 1 Case DC_TYPE_STNG Return - 1 Case DC_TYPE_BYTE Return - 1 Case DC_TYPE_SHRT Return - 1 Case DC_TYPE_INTE Return - 1 Case DC_TYPE_LONG Return - 1 Case DC_TYPE_FLOT Return 0 Case DC_TYPE_DBLE Return 1 End Select Case DC_TYPE_DBLE Select o2.m_Type Case DC_TYPE_CNTR Return - 1 Case DC_TYPE_BANK Return - 1 Case DC_TYPE_STNG Return - 1 Case DC_TYPE_BYTE Return - 1 Case DC_TYPE_SHRT Return - 1 Case DC_TYPE_INTE Return - 1 Case DC_TYPE_LONG Return - 1 Case DC_TYPE_FLOT Return - 1 Case DC_TYPE_DBLE Return 0 End Select End Select End Function
Function DC_CreateContainer:DC(Name:String) Local DC:DC = New DC DC.m_Name = Name DC.m_Type = DC_TYPE_CNTR DC.m_Data = New TList Return DC End Function Function DC_LoadFromFile:DC(File:String, Compressed:Byte) Local fStream:TStream = ReadFile(file) Local DCR:DC If fStream If Compressed = False DCR = DC_Read(fStream, Null) Else Local destSize:Int = fStream.ReadInt() Local destBank:TBank = CreateBank(destSize) Local fromBank:TBank = CreateBank(FileSize(File) - 4) fromBank.Read(fStream, 0, fromBank.Size()) uncompress(destBank.Buf(), destSize, fromBank.Buf(), fromBank.Size()) destBank.Resize(destSize) Local bStream:TBankStream = CreateBankStream(destBank) DCR = DC_Read(bStream, Null) bStream = Null destBank = Null fromBank = Null EndIf CloseFile fStream fStream = Null DCR.Sort() Return DCR Else Return Null EndIf End Function Function DC_LoadFromBank:DC(Bank:TBank) Local DCR:DC If Bank Local destSize:Int = Bank.PeekInt(Bank.Size() - 4) Local destBank:TBank = CreateBank(destSize) uncompress(destBank.Buf(), destSize, Bank.Buf(), Bank.Size() - 4) destBank.Resize(destSize) Local bStream:TBankStream = CreateBankStream(destBank) If bStream DCR = DC_Read(bStream, Null) bStream = Null destBank = Null DCR.Sort() Return DCR Else bStream = Null destBank = Null Return Null EndIf Else Return Null End If End Function Function DC_Read:DC(fStream:TStream, Parent:DC) Local bType:Byte = fStream.ReadByte() Local ThisDC:DC If bType <> DC_FRMT_CNTR_CLSE And bType <> DC_FRMT_CNTR_OPEN And fStream.Eof() = False Local iNameL:Int = fStream.ReadInt() Local sName:String = fStream.ReadString(iNameL) Select bType Case DC_TYPE_CNTR If Parent = Null Then ThisDC = DC_CreateContainer(sName) Else ThisDC = Parent.AddContainer(sName) EndIf DC_Read(fStream, ThisDC) Case DC_TYPE_BANK Local iBankL:Int = fStream.ReadInt() Local bBank:TBank = CreateBank(iBankL) bBank.Read(fStream, 0, iBankL) ThisDc = Parent.AddBank(sName, bBank) bBank = Null Case DC_TYPE_STNG Local sStrL:Int = fStream.ReadInt() Local sStrn:String = fStream.ReadString(sstrl) Thisdc = Parent.AddString(sName, sStrn) Case DC_TYPE_BYTE Local sByte:Byte = fStream.ReadByte() ThisDC = Parent.AddByte(sName, sByte) Case DC_TYPE_SHRT Local sShort:Short = fStream.ReadShort() ThisDC = Parent.AddShort(sName, sShort) Case DC_TYPE_INTE Local sInt:Int = fStream.ReadInt() ThisDC = Parent.AddInt(sName, sInt) Case DC_TYPE_LONG Local sLong:Long = fStream.ReadLong() ThisDC = Parent.AddLong(sName, sLong) Case DC_TYPE_FLOT Local sFloat:Float = fStream.ReadFloat() ThisDC = Parent.AddFloat(sName, sFloat) Case DC_TYPE_DBLE Local sDouble:Double = fStream.ReadDouble() ThisDC = Parent.AddDouble(sName, sDouble) EndSelect Return ThisDC ElseIf bType = DC_FRMT_CNTR_OPEN While DC_Read(fStream, Parent) <> Null Wend Else Return Null EndIf End Function Function DC_PrintContents(DC:DC, Depth:String = "") ?Debug Local Arr:DC[] = DC.GetContents() If DC.m_Type = DC_TYPE_CNTR And Depth = "" DebugLog Depth + "[CNTO]" + DC.m_Name Depth = Depth + " " EndIf For Local _i:Int = 0 To Arr.Length - 1 Select Arr[_i].m_Type Case DC_TYPE_CNTR DebugLog Depth + "[CNTO]" + Arr[_i].m_Name DC_PrintContents(Arr[_i], Depth + " ") DebugLog Depth + "[CNTC]" + Arr[_i].m_Name Case DC_TYPE_BANK DebugLog Depth + "[BANK]" + Arr[_i].m_Name Case DC_TYPE_STNG DebugLog Depth + "[STNG]" + Arr[_i].m_Name Case DC_TYPE_BYTE DebugLog Depth + "[BYTE]" + Arr[_i].m_Name Case DC_TYPE_SHRT DebugLog Depth + "[SHRT]" + Arr[_i].m_Name Case DC_TYPE_INTE DebugLog Depth + "[INTE]" + Arr[_i].m_Name Case DC_TYPE_FLOT DebugLog Depth + "[FLOT]" + Arr[_i].m_Name Case DC_TYPE_DBLE DebugLog Depth + "[DBLE]" + Arr[_i].m_Name EndSelect Next If DC.m_Type = DC_TYPE_CNTR And Depth = " " Then DebugLog "[CNTC]" + DC.m_Name ? End Function
~Beispiel/Tutorial~
BlitzMax: [AUSKLAPPEN] [EINKLAPPEN] Include "Collector.bmx"
Local dcMain:DC = DC_CreateContainer("Main") dcMain.AddString("TestString", "Hallo Welt") dcMain.AddByte("TestByte", 204) dcMain.AddShort("TestShort", 65500) dcMain.AddInt("TestInt", 1000000000000) dcMain.AddLong("TestLong", 10000000000) dcMain.AddFloat("TestFloat", 1000000.0) dcMain.AddDouble("TestDouble", 10000.0) Local dcData:DC = dcMain.AddContainer("Data") Local myBank:TBank = CreateBank(64) dcData.AddBank("TestBank", myBank)
Local dcShort:DC = dcMain.FindChild("TestShort") dcShort.SetDataShort(0) Local myshort:Short = dcShort.GetDataShort()
dcMain.Save("HelloWorld.ddc") dcMain.Destroy() dcMain = Null dcMain = DC_LoadFromFile("HelloWorld.ddc", False) DC_PrintContents(dcMain)
~Editor für cdc/ddc(cdc=Compressed DataCollector, ddc=Decompressed DataCollector)~
Ist derzeit in Arbeit, dank anfrage von HexenMeister . Dieser wird auch von DataCollectoren gebrauch machen.
|