# Post Edit delegate for an asset? (datatable)

**URL:** <https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773>\
**Category:** C++\
**Tags:** unreal-engine, bug-report, editor, feedback, CPP, question\
**Created:** [December 27, 2022, 7:32am UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773 "2022-12-27T07:32:56Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Roy\_Wierer.Seda145](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/roy_wierer.seda145/32/906551_2.png) [@Roy\_Wierer.Seda145](https://forums.unrealengine.com/u/Roy_Wierer.Seda145)\
**Post date:** [December 27, 2022, 7:32am UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/1 "2022-12-27T07:32:56Z")

</div>

I wish to track any modification to only a single datatable. A UDataTable has a delegate for that, but it is not accessible from an FDataTableRowHandle (const datatable).

 ![afbeelding](https://d3kjluh73b9h9o.cloudfront.net/original/4X/6/d/7/6d73c69fb9a4d1f1cbcaf5cc6e484e2e2f4aaeec.png)

Currently I am using:

```auto
FCoreUObjectDelegates::OnObjectModified.AddUObject(this, &UMyObject::ActOnObjectChanged);

```

Where I have to check if any changed UObject happens to be this datatable. Another side effect which seems to be caused by this workaround is that I don’t get the most recent data from the DataTable during ActOnObjectChanged. It lags one edit behind, which breaks the system.

---

<div class="post-metadata">

**Author:** ![Jambax](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/jambax/32/904177_2.png) [@Jambax](https://forums.unrealengine.com/u/Jambax)\
**Post date:** [December 27, 2022, 9:37am UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/2 "2022-12-27T09:37:41Z")

</div>

You can’t bind to the table member of FDataTableRowHandle because it’s a pointer to a const table, and the event is a member of that table.

DataTables should be treated as “const” at runtime, they are meant for static data only. If you want a Key/Value pair set at runtime then just use regular TMap’s.

Assuming this for an edit-time tool, if so, you can just cast the const away. FTableRowBase also has callbacks for when the table is modified, which you can override for a specific table struct.

You can also use the Data Validation system to validate tables on save and log errors etc.

---

<div class="post-metadata">

**Author:** ![Roy\_Wierer.Seda145](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/roy_wierer.seda145/32/906551_2.png) [@Roy\_Wierer.Seda145](https://forums.unrealengine.com/u/Roy_Wierer.Seda145)\
**Post date:** [December 27, 2022, 10:01am UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/3 "2022-12-27T10:01:16Z")

</div>

It is used within an editor module to update an object on the editor panel when I update my datatable. The datatable itself is not modified through my code, I only want to know when it is modified during editor time. The FDataTableRowHandle format is used so I can use the datatable + row “picker” on the editor panel.

Is it not undefined behavior to const\_cast away the const and then write to its delegate?

> [const\_cast conversion - cppreference.com](https://en.cppreference.com/w/cpp/language/const_cast)

---

<div class="post-metadata">

**Author:** ![Jambax](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/jambax/32/904177_2.png) [@Jambax](https://forums.unrealengine.com/u/Jambax)\
**Post date:** [December 27, 2022, 10:13am UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/4 "2022-12-27T10:13:55Z")

</div>

The issue is that UObject::Modify is always called _before_ changes are made, you want to find some kind of post-edit change delegate. They do exist but I can’t name them currently.

RE the const\_cast - probably, but I’ve always found it works fine in practice. Design decisions at the engine level sometimes make it hard to care about const-correctness when making editor tools…

---

<div class="post-metadata">

**Author:** ![Roy\_Wierer.Seda145](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/roy_wierer.seda145/32/906551_2.png) [@Roy\_Wierer.Seda145](https://forums.unrealengine.com/u/Roy_Wierer.Seda145)\
**Post date:** [December 27, 2022, 11:33am UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/5 "2022-12-27T11:33:45Z")

</div>

that post-edit delegate sounds like the way to go, I’d rather not mess with possible UB. I found something that might just be it, but I don’t know how to use it:

```auto
FDataTableEditorUtils::FDataTableEditorManager::Get().AddListener([]( ??? ) { });

```

It makes use of INotifyOnChanged (ListenerManager) of which I can’t find any example in engine .cpp files.

```auto
FDataTableEditorUtils::BroadcastPostChange(DataTable, EDataTableChangeInfo::RowList);

```

 ![afbeelding](https://d3kjluh73b9h9o.cloudfront.net/original/4X/1/2/5/125b69901c8f287a141fe7e27c9db2db6d5f787c.png)

---

<div class="post-metadata">

**Author:** ![Roy\_Wierer.Seda145](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/roy_wierer.seda145/32/906551_2.png) [@Roy\_Wierer.Seda145](https://forums.unrealengine.com/u/Roy_Wierer.Seda145)\
**Post date:** [December 27, 2022, 10:17pm UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/6 "2022-12-27T22:17:08Z")

</div>

bump

---

<div class="post-metadata">

**Author:** ![Roy\_Wierer.Seda145](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/roy_wierer.seda145/32/906551_2.png) [@Roy\_Wierer.Seda145](https://forums.unrealengine.com/u/Roy_Wierer.Seda145)\
**Post date:** [December 29, 2022, 8:57am UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/7 "2022-12-29T08:57:29Z")

</div>

🆙

---

<div class="post-metadata">

**Author:** ![Roy\_Wierer.Seda145](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/roy_wierer.seda145/32/906551_2.png) [@Roy\_Wierer.Seda145](https://forums.unrealengine.com/u/Roy_Wierer.Seda145)\
**Post date:** [December 30, 2022, 10:48pm UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/8 "2022-12-30T22:48:20Z")

</div>

🔼

---

<div class="post-metadata">

**Author:** ![Roy\_Wierer.Seda145](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/roy_wierer.seda145/32/906551_2.png) [@Roy\_Wierer.Seda145](https://forums.unrealengine.com/u/Roy_Wierer.Seda145)\
**Post date:** [December 31, 2022, 9:46pm UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/9 "2022-12-31T21:46:06Z")

</div>

🆙

---

<div class="post-metadata">

**Author:** ![Roy\_Wierer.Seda145](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/roy_wierer.seda145/32/906551_2.png) [@Roy\_Wierer.Seda145](https://forums.unrealengine.com/u/Roy_Wierer.Seda145)\
**Post date:** [January 3, 2023, 9:13pm UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/10 "2023-01-03T21:13:10Z")

</div>

👋

---

<div class="post-metadata">

**Author:** ![Roy\_Wierer.Seda145](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/roy_wierer.seda145/32/906551_2.png) [@Roy\_Wierer.Seda145](https://forums.unrealengine.com/u/Roy_Wierer.Seda145)\
**Post date:** [February 2, 2023, 6:52pm UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/11 "2023-02-02T18:52:51Z")

</div>

Up 🙂

---

<div class="post-metadata">

**Author:** ![Roy\_Wierer.Seda145](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/roy_wierer.seda145/32/906551_2.png) [@Roy\_Wierer.Seda145](https://forums.unrealengine.com/u/Roy_Wierer.Seda145)\
**Post date:** [February 25, 2023, 11:55pm UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/12 "2023-02-25T23:55:29Z")

</div>

let’s try again

---

<div class="post-metadata">

**Author:** ![Roy\_Wierer.Seda145](https://d1ap1mz92jnks1.cloudfront.net/user_avatar/forums.unrealengine.com/roy_wierer.seda145/32/906551_2.png) [@Roy\_Wierer.Seda145](https://forums.unrealengine.com/u/Roy_Wierer.Seda145)\
**Post date:** [February 27, 2023, 4:19pm UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/13 "2023-02-27T16:19:46Z")

</div>

> [@Losing const qualifier through soft pointer? Hacky?](https://forums.unrealengine.com/t/losing-const-qualifier-through-soft-pointer-hacky/779114):
>
> In a specific situation where I need to access a loaded asset, I could only retrieve a const pointer. Casting away const on a variable and then modifying that variable results in undefined behavior: [const\_cast conversion - cppreference.com](https://en.cppreference.com/w/cpp/language/const_cast) . Instead of const casting I realized I could simply get to the object by first making a soft pointer of the UObject pointer and then getting the asset. – Hacky? – const UObject\* A = nullptr; TSoftObjectPtr B = TSoftObjectPtr(A); UObject\* C = B.Get();

---

<div class="post-metadata">

**Author:** ![wumbo](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@wumbo](https://forums.unrealengine.com/u/wumbo)\
**Post date:** [April 21, 2023, 11:52pm UTC](https://forums.unrealengine.com/t/post-edit-delegate-for-an-asset-datatable/736773/14 "2023-04-21T23:52:33Z")

</div>

Make your class inherit from `public FListenerManager<UDataTable, FDataTableEditorUtils::EDataTableChangeInfo>::BaseNotifyOnChanged`, and override the `PreChange` and `PostChange` functions.

You can replace `UDataTable` in above with a more specific class you want.

```cpp
class UMyDataTableListener : public UObject, public FListenerManager<UDataTable, FDataTableEditorUtils::EDataTableChangeInfo>::BaseNotifyOnChanged
{
    virtual void PreChange(const UDataTable* Changed, FDataTableEditorUtils::EDataTableChangeInfo ChangedType) override;
    virtual void PostChange(const UDataTable* Changed, FDataTableEditorUtils::EDataTableChangeInfo ChangedType) override;
}

```

Then do:

```cpp
FDataTableEditorUtils::FDataTableEditorManager::Get().AddListener(this); 

```

Don’t forget to remove the listener at some point.
