powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Добавление классов в TObjectDictionary
10 сообщений из 10, страница 1 из 1
Добавление классов в TObjectDictionary
    #39837110
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вычитываю XML, добавляю в TObjectDictionary

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
  TAssetType = record
    padding : Byte;
    directory : String;
    FileExt : String;
  end;

  TAssetBoolType = array[Boolean] of TAssetType; //False - unpacked, True - packed;

  TAssetClass = class
  private
    fVal : TAssetBoolType;
    function Get(T: Boolean): TAssetType;
  public
    property Val[T: Boolean] : TAssetType read Get; default;
    constructor Create;
  end;


----------------


  fUOPAssets := TObjectDictionary<Byte,TAssetClass>.Create([doOwnsValues]);

  for i := 0 to XMLDoc.Root.ItemCount - 1 do
  begin
    XML_Element := XMLDoc.Root.Items[i];
...
    if not fUOPAssets.TryGetValue(Num,AssetClass) then
      AssetClass := TAssetClass.Create;

    AssetClass.fVal[IsFilePacked].padding := XML_Element.Properties.IntValue('resourcetpaddingype',0);
    AssetClass.fVal[IsFilePacked].directory := XML_Element.Properties.Value('directory','').ToLower;
    AssetClass.fVal[IsFilePacked].FileExt := XML_Element.Properties.Value('suffix','').ToLower;

    fUOPAssets.AddOrSetValue(Num, AssetClass);
  end;



Какого-то беса результат TAssetClass.Create - есть указатель на тот же адрес, что и в прошлой итерации цикла. Уже и перекрывал конструктор, без толку.
Вроде просто всё, проще некуда. А не работает, точнее работает неправильно.

Содержимое словаря в приложенной картинкой, стрелками разных цветов выделил дублирующиеся указатели на объект.
Словарь заполняется один раз, освобождается в конце работы, в процессе - только чтение.

Что я делаю не так?
...
Рейтинг: 0 / 0
Добавление классов в TObjectDictionary
    #39837111
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rЧто я делаю не так?

Судьба Num не ясна, думаю, в нем собака и зарыта :)
...
Рейтинг: 0 / 0
Добавление классов в TObjectDictionary
    #39837114
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
    Num := XML_Element.Properties.IntValue('resourcetype',$FF);
    if Num = $FF then
      Continue;



$FF для пропуска строк без 'resourcetype', ну это понятно.
...
Рейтинг: 0 / 0
Добавление классов в TObjectDictionary
    #39837119
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0r,

А как этот код расположен по отношению к остальному?

Я подозреваю, что у Вас Num меняется в процессе: .Create не вызывается, меняется Num, старый объект с новым Num добавляется.
...
Рейтинг: 0 / 0
Добавление классов в TObjectDictionary
    #39837125
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
на отладке смотрел - нормально меняется на каждой итерации, в соотвествии с resourcetype в каждом элементе.

Выложу почти полный исходник:

под спойлером типы и классы.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
type
  TUOPAssets = class;

  TGetUOPAssets = function : TUOPAssets of object;

  TAssetType = record
    padding : Byte;
    directory : String;
    FileExt : String;
  end;

  TAssetBoolType = array[Boolean] of TAssetType; //False - unpacked, True - packed;

  TAssetClass = class
  private
    fVal : TAssetBoolType;
    function Get(T: Boolean): TAssetType;
  public
    property Val[T: Boolean] : TAssetType read Get; default;
    constructor Create;
  end;

  TUOPAssets = class
  private
    fUOPAssets : TObjectDictionary<Byte,TAssetClass>;
    FInited : Boolean;
  public
    constructor Create(ShardDir : String);
    property Inited : Boolean read FInited;
    property Assets : TObjectDictionary<Byte,TAssetClass> read fUOPAssets;
  end;

implementation
function TAssetClass.Get(T: Boolean): TAssetType;
begin
  Result := fVal[T];
end;

constructor TAssetClass.Create;
begin
  inherited Create;
end;



вот весь конструктор целиком, с разбором XML

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
constructor TUOPAssets.Create(ShardDir : String);
var UOPPackage : TMythicPackage;
    FileBuf : TArray<byte>;
    XMLDoc : TJclSimpleXML;
    XML_Element : TJclSimpleXMLElem;
    XMLString : String;
    IsFilePacked : Boolean;
    i  : Integer;
    AssetClass : TAssetClass;
    Asset : TAssetBoolType;
    Num : Byte;
begin
  inherited Create;
  FInited := False;
  if not FileExists(shardDir + 'MainMisc.uop') then
    Exit;
  UOPPackage := TMythicPackage.Create;
  UOPPackage.Open(shardDir + 'MainMisc.uop');
  if UOPPackage.FileCount = 0 then
  begin
    UOPPackage.DisposeOf;
    Exit;
  end;
  FileBuf := UOPPackage.UnpackByName('data/assetmap.xml');
  if Length(FileBuf) = 0 then
  begin
    UOPPackage.DisposeOf;
    Exit;
  end;
  XMLString := TEncoding.ANSI.GetString(FileBuf);
  fUOPAssets := TObjectDictionary<Byte,TAssetClass>.Create([doOwnsValues]);

  try
    XMLDoc := TJclSimpleXML.Create;
    XMLDoc.LoadFromString(XMLString);
  except
    Exit;
  end;
  if XMLDoc.Root.name <> 'assetmap' then Exit;

  for i := 0 to XMLDoc.Root.ItemCount - 1 do
  begin
    XML_Element := XMLDoc.Root.Items[i];
//    if XML_Element.Name <> 'patternmap' then Continue;
    if Assigned(XML_Element.Properties.ItemNamed['fileFormat']) then
      IsFilePacked := XML_Element.Properties.ItemNamed['fileFormat'].Value = 'packed'
    else
      IsFilePacked := True;
    Num := XML_Element.Properties.IntValue('resourcetype',$FF);
    if Num = $FF then
      Continue;
    if not fUOPAssets.TryGetValue(Num,AssetClass) then
      AssetClass := TAssetClass.Create;

    AssetClass.fVal[IsFilePacked].padding := XML_Element.Properties.IntValue('resourcetpaddingype',0);
    AssetClass.fVal[IsFilePacked].directory := XML_Element.Properties.Value('directory','').ToLower;
    AssetClass.fVal[IsFilePacked].FileExt := XML_Element.Properties.Value('suffix','').ToLower;

    fUOPAssets.AddOrSetValue(Num, AssetClass);
  end;
  FInited := True;
  XMLDoc.DisposeOf;
  UOPPackage.DisposeOf;
end;



а вот файл, который разбирается.

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
<assetmap>
   <patternmap resourcetype="1" fileFormat="raw" padding="8" directory="Data/WorldArt/" suffix="*" patternMatch="1" />
   <patternmap resourcetype="1" fileFormat="packed" padding="8" directory="Build/WorldArt/" suffix=".dds"/>
   <patternmap resourcetype="2" directory="Data/Maps/" suffix=".dat" />
   <patternmap resourcetype="3" fileFormat="raw" directory="Data/Definitions/Terrain/" suffix=".xml" />
   <patternmap resourcetype="3" fileFormat="packed" directory="Build/TerrainDefinition/" suffix=".bin" />
   <patternmap resourcetype="5" directory="Data/Statics/" suffix=".dat" />
   <patternmap resourcetype="6" fileFormat="raw" padding="8" directory="Data/Definitions/TileArt/" suffix=".tileart" />
   <patternmap resourcetype="6" fileFormat="packed" padding="8" directory="Build/TileArt/" suffix=".bin" />
   <patternmap resourcetype="8" padding="8" directory="Data/Textures/" suffix="*" patternMatch="1" />
   <patternmap resourcetype="8" fileFormat="packed" padding="8" directory="Build/TerrainTexture/" suffix=".dds"/>
   <bitmaskmap resourcetype="9" fileFormat="raw" directory="Data/Sectors/" suffix=".sector">
      <section prefix="Facet_" mask="0x3f" padding="2"/>
      <section prefix="/" mask="0xffffffc0" padding="8"/>
   </bitmaskmap>
   <bitmaskmap resourcetype="9" fileFormat="packed" directory="Build/Sectors/" suffix=".bin">
      <section prefix="Facet_" mask="0x3f" padding="2"/>
      <section prefix="/" mask="0xffffffc0" padding="8"/>
   </bitmaskmap>
   <patternmap resourcetype="10" padding="8" directory="Data/Definitions/LegacyTerrain/" suffix=".legacyterrain" />
   <patternmap resourcetype="11" fileFormat="raw" padding="8" directory="Data/Definitions/Animation/" suffix=".animation" />
   <patternmap resourcetype="11" fileFormat="packed" padding="8" directory="Build/AnimationDefinition/" suffix=".bin" />
   <patternmap resourcetype="12" fileFormat="raw" padding="8" directory="Data/Definitions/Animation/" suffix=".sequence" />
   <patternmap resourcetype="12" fileFormat="packed" padding="8" directory="Build/AnimationSequence/" suffix=".bin" />
   <patternmap resourcetype="13" fileFormat="raw" padding="8" directory="Data/Definitions/Effect/" suffix=".effects" />
   <patternmap resourcetype="13" fileFormat="packed" padding="8" directory="Build/EffectDefinitionCollection/" suffix=".bin" />
   <bitmaskmap resourcetype="14" directory="Data/Anim/" suffix=".tga">
      <section isDirectory="1" patternMatch="1" mask="0xffffc000" padding="6"/>
      <section isDirectory="1" patternMatch="1" mask="0x3f00" padding="2"/>
      <section mask="0xff" padding="4"/>
   </bitmaskmap>
   <patternmap resourcetype="15" padding="3" directory="Data/LocalizedStrings/" suffix=".cliloc" />
   <bitmaskmap resourcetype="16" fileFormat="packed" directory="Build/AnimationFrame/" suffix=".bin">
      <section isDirectory="1" mask="0xffff00" padding="6"/>
      <section mask="0xff" padding="2"/>
   </bitmaskmap>
   <bitmaskmap resourcetype="25" fileFormat="packed" directory="Build/AnimationLegacyFrame/" suffix=".bin">
      <section isDirectory="1" mask="0xffff00" padding="6"/>
      <section mask="0xff" padding="2"/>
   </bitmaskmap>
   <bitmaskmap resourcetype="18" fileFormat="packed" directory="Build/Paperdoll/" suffix=".bin">
      <section isDirectory="1" mask="0xffffc0" padding="6"/>
      <section mask="0x3f" padding="2"/>
   </bitmaskmap>
   <patternmap resourcetype="19" fileFormat="raw" padding="6" directory="Data/Definitions/Multi/" suffix=".multi" />
   <patternmap resourcetype="19" fileFormat="packed" padding="6" directory="Build/MultiCollection/" suffix=".bin" />
   <simplemap resourcetype="20" fileFormat="raw" resourcenumber="0" filename="Data/Definitions/Multi/housing.xml" />
   <simplemap resourcetype="20" fileFormat="packed" resourcenumber="0" filename="Build/MultiCollection/housing.bin" />
   <simplemap resourcetype="21" fileFormat="raw" resourcenumber="0" filename="Data/Sectors/waypoint.xml" />
   <simplemap resourcetype="21" fileFormat="packed" resourcenumber="0" filename="Build/Sectors/waypoint.bin" />
   <patternmap resourcetype="22" fileFormat="raw" directory="Data/TileArtLegacy/" suffix="*" patternMatch="1" />
   <patternmap resourcetype="22" fileFormat="packed" padding="8" directory="Build/TileArtLegacy/" suffix=".dds"/>
   <patternmap resourcetype="23" fileFormat="raw" padding="8" directory="Data/Definitions/Facet/" suffix=".xml" />
   <patternmap resourcetype="23" fileFormat="packed" padding="8" directory="Build/FacetDefinition/" suffix=".bin" />
   <patternmap resourcetype="24" fileFormat="raw" padding="8" directory="EditorData/BrushMulti/" suffix=".multi" />
   <!-- Resource type 25 is only used by legacy -->
   <patternmap resourcetype="26" fileFormat="raw" directory="Data/TileArtEnhanced/" suffix="*" patternMatch="1" />
   <patternmap resourcetype="26" fileFormat="packed" padding="8" directory="Build/TileArtEnhanced/" suffix=".dds" />
 </assetmap>

...
Рейтинг: 0 / 0
Добавление классов в TObjectDictionary
    #39837170
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rКакого-то беса результат TAssetClass.Create - есть указатель на тот же адрес, что и в прошлой итерации цикла.Так код этому и не противоречит. Как написал - так и работает.
...
Рейтинг: 0 / 0
Добавление классов в TObjectDictionary
    #39837180
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а поподробнее?
AssetClass := TAssetClass.Create;
же должно создавать НОВЫЙ экземпляр класса.
...
Рейтинг: 0 / 0
Добавление классов в TObjectDictionary
    #39837181
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
докопался.

оказывается, в TDictionary.DoSetValue
происходит

ValueNotify(oldValue, cnRemoved);
ValueNotify(Value, cnAdded);


а на cnRemoved в TObjectDictionary происходит уничтожение объекта.


вот уж чего не ожидал.
...
Рейтинг: 0 / 0
Добавление классов в TObjectDictionary
    #39837189
Cobalt747
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rдокопался.

оказывается, в TDictionary.DoSetValue
происходит

ValueNotify(oldValue, cnRemoved);
ValueNotify(Value, cnAdded);


а на cnRemoved в TObjectDictionary происходит уничтожение объекта.


вот уж чего не ожидал.
Рекомендую обращать внимание на параметры конструктора используемых объектов.
...
Рейтинг: 0 / 0
Добавление классов в TObjectDictionary
    #39837193
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
обращал, и doOwnsValues ставил вполне осознанно.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Добавление классов в TObjectDictionary
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]