mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2024-11-08 00:37:15 +01:00
Expose DPP message embeds.
Some checks reported errors
continuous-integration/drone/push Build was killed
Some checks reported errors
continuous-integration/drone/push Build was killed
This commit is contained in:
parent
259af04d0e
commit
1d85603dfb
@ -170,6 +170,32 @@ void Register_DPP_Message(HSQUIRRELVM vm, Table & ns)
|
||||
.SquirrelFunc(_SC("_typename"), &SqDppEmbed::Fn)
|
||||
// Member Properties
|
||||
.Prop(_SC("Valid"), &DpEmbed::IsValid)
|
||||
.Prop(_SC("Title"), &DpEmbed::GetTitle, &DpEmbed::SetTitle)
|
||||
.Prop(_SC("Type"), &DpEmbed::GetType, &DpEmbed::SetType)
|
||||
.Prop(_SC("Description"), &DpEmbed::GetDescription, &DpEmbed::SetDescription)
|
||||
.Prop(_SC("URL"), &DpEmbed::GetURL, &DpEmbed::SetURL)
|
||||
.Prop(_SC("TimeStamp"), &DpEmbed::GetTimeStamp, &DpEmbed::SetTimeStamp)
|
||||
.Prop(_SC("Color"), &DpEmbed::GetColor, &DpEmbed::SetColor)
|
||||
.Prop(_SC("Footer"), &DpEmbed::GetFooter, &DpEmbed::SetFooter)
|
||||
.Prop(_SC("Image"), &DpEmbed::GetImage, &DpEmbed::SetImage)
|
||||
.Prop(_SC("Thumbnail"), &DpEmbed::GetThumbnail, &DpEmbed::SetThumbnail)
|
||||
.Prop(_SC("Video"), &DpEmbed::GetVideo, &DpEmbed::SetVideo)
|
||||
.Prop(_SC("Provider"), &DpEmbed::GetProvider, &DpEmbed::SetProvider)
|
||||
.Prop(_SC("Author"), &DpEmbed::GetAuthor, &DpEmbed::SetAuthor)
|
||||
.Prop(_SC("Fields"), &DpEmbed::GetFields)
|
||||
// Member Methods
|
||||
.FmtFunc(_SC("SetTitle"), &DpEmbed::ApplyTitle)
|
||||
.FmtFunc(_SC("SetType"), &DpEmbed::ApplyType)
|
||||
.FmtFunc(_SC("SetDescription"), &DpEmbed::ApplyDescription)
|
||||
.FmtFunc(_SC("SetURL"), &DpEmbed::ApplyURL)
|
||||
.FmtFunc(_SC("SetTimeStamp"), &DpEmbed::ApplyTimeStamp)
|
||||
.FmtFunc(_SC("SetFooter"), &DpEmbed::ApplyFooter)
|
||||
.FmtFunc(_SC("SetImage"), &DpEmbed::ApplyImage)
|
||||
.FmtFunc(_SC("SetThumbnail"), &DpEmbed::ApplyThumbnail)
|
||||
.FmtFunc(_SC("SetVideo"), &DpEmbed::ApplyVideo)
|
||||
.FmtFunc(_SC("SetProvider"), &DpEmbed::ApplyProvider)
|
||||
.FmtFunc(_SC("SetAuthor"), &DpEmbed::ApplyAuthor)
|
||||
.FmtFunc(_SC("AddField"), &DpEmbed::AddField)
|
||||
);
|
||||
// --------------------------------------------------------------------------------------------
|
||||
ns.Bind(_SC("Reaction"),
|
||||
|
@ -291,7 +291,7 @@ struct DpComponent
|
||||
// Cleanup options, if any
|
||||
if (!mSqOptions.IsNull())
|
||||
{
|
||||
mSqOptions.CastI< Components >()->Cleanup();
|
||||
mSqOptions.CastI< Options >()->Cleanup();
|
||||
// Release script resources
|
||||
mSqOptions.Release();
|
||||
}
|
||||
@ -473,7 +473,7 @@ struct DpComponent
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add a sub-component, only valid for action rows.
|
||||
* Adding subcomponents to a component will automatically set this component's type to SqDiscordComponentType.ActionRow.
|
||||
* Adding sub-components to a component will automatically set this component's type to SqDiscordComponentType.ActionRow.
|
||||
*/
|
||||
DpComponent & AddComponent(DpComponent & comp)
|
||||
{
|
||||
@ -1288,6 +1288,16 @@ struct DpEmbed
|
||||
* Whether the referenced pointer is owned.
|
||||
*/
|
||||
bool mOwned{false};
|
||||
// --------------------------------------------------------------------------------------------
|
||||
using Fields = DpVectorProxy< dpp::embed_field, DpEmbedField >;
|
||||
// --------------------------------------------------------------------------------------------
|
||||
LightObj mSqFooter{};
|
||||
LightObj mSqImage{};
|
||||
LightObj mSqThumbnail{};
|
||||
LightObj mSqVideo{};
|
||||
LightObj mSqProvider{};
|
||||
LightObj mSqAuthor{};
|
||||
LightObj mSqFields{};
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
@ -1344,6 +1354,19 @@ struct DpEmbed
|
||||
*/
|
||||
void Cleanup()
|
||||
{
|
||||
DropObject< DpEmbedFooter >(mSqFooter);
|
||||
DropObject< DpEmbedImage >(mSqImage);
|
||||
DropObject< DpEmbedImage >(mSqThumbnail);
|
||||
DropObject< DpEmbedImage >(mSqVideo);
|
||||
DropObject< DpEmbedProvider >(mSqProvider);
|
||||
DropObject< DpEmbedAuthor >(mSqAuthor);
|
||||
// Cleanup fields, if any
|
||||
if (!mSqFields.IsNull())
|
||||
{
|
||||
mSqFields.CastI< Fields >()->Cleanup();
|
||||
// Release script resources
|
||||
mSqFields.Release();
|
||||
}
|
||||
// Do we own this to try delete it?
|
||||
if (!mOwned && mPtr) {
|
||||
// Not our job, simply forget about it
|
||||
@ -1362,11 +1385,441 @@ struct DpEmbed
|
||||
* Check whether a valid instance is managed.
|
||||
*/
|
||||
SQMOD_NODISCARD bool IsValid() const { return static_cast< bool >(mPtr); }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated title of embed.
|
||||
*/
|
||||
SQMOD_NODISCARD const String & GetTitle() const { return Valid().title; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated title of embed.
|
||||
*/
|
||||
void SetTitle(StackStrF & title) const { Valid().set_title(title.ToStr()); }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated title of embed.
|
||||
*/
|
||||
DpEmbed & ApplyTitle(StackStrF & title) { SetTitle(title); return *this; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated type of embed (always "rich" for web-hook embeds).
|
||||
*/
|
||||
SQMOD_NODISCARD const String & GetType() const { return Valid().type; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated type of embed.
|
||||
*/
|
||||
void SetType(StackStrF & type) const
|
||||
{
|
||||
if (type.mLen > 0)
|
||||
{
|
||||
Valid().type.assign(type.mPtr, static_cast< size_t >(type.mLen));
|
||||
}
|
||||
else
|
||||
{
|
||||
Valid().type.clear();
|
||||
}
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated type of embed.
|
||||
*/
|
||||
DpEmbed & ApplyType(StackStrF & type) { SetType(type); return *this; }
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated description of embed.
|
||||
*/
|
||||
SQMOD_NODISCARD const String & GetDescription() const { return Valid().description; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated description of embed.
|
||||
*/
|
||||
void SetDescription(StackStrF & description) const { Valid().set_description(description.ToStr()); }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated description of embed.
|
||||
*/
|
||||
DpEmbed & ApplyDescription(StackStrF & description) { SetDescription(description); return *this; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated URL of embed.
|
||||
*/
|
||||
SQMOD_NODISCARD const String & GetURL() const { return Valid().url; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated URL of embed.
|
||||
*/
|
||||
void SetURL(StackStrF & url) const { Valid().set_url(url.ToStr()); }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated URL of embed.
|
||||
*/
|
||||
DpEmbed & ApplyURL(StackStrF & url) { SetURL(url); return *this; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve time-stamp of embed content.
|
||||
*/
|
||||
SQMOD_NODISCARD SQInteger GetTimeStamp() const
|
||||
{
|
||||
return static_cast< SQInteger >(std::chrono::duration_cast< std::chrono::seconds >(std::chrono::system_clock::from_time_t(Valid().timestamp).time_since_epoch()).count());
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify time-stamp of embed content.
|
||||
*/
|
||||
void SetTimeStamp(SQInteger s) const
|
||||
{
|
||||
Valid().timestamp = std::chrono::system_clock::to_time_t(std::chrono::time_point< std::chrono::system_clock >{std::chrono::seconds{s}});
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify time-stamp of embed content.
|
||||
*/
|
||||
DpEmbed & ApplyTimeStamp(SQInteger s) { SetTimeStamp(s); return *this; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated color code of the embed.
|
||||
*/
|
||||
SQMOD_NODISCARD SQInteger GetColor() const { return static_cast< SQInteger >(Valid().color); }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated color code of the embed.
|
||||
*/
|
||||
void SetColor(SQInteger color) const { Valid().set_color(static_cast< dpp::component_style >(color)); }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated footer information.
|
||||
*/
|
||||
SQMOD_NODISCARD LightObj & GetFooter()
|
||||
{
|
||||
// Do we have a value assigned?
|
||||
if (Valid().footer.has_value())
|
||||
{
|
||||
// Do we have a script object associated with it?
|
||||
if (mSqFooter.IsNull())
|
||||
{
|
||||
// Create the script object with non-owning reference
|
||||
mSqFooter = LightObj(SqTypeIdentity< DpEmbedFooter >{}, SqVM(), &(mPtr->footer.value()), false);
|
||||
}
|
||||
} else mSqFooter.Release(); // Make sure this is null
|
||||
// Return the associated script object
|
||||
return mSqFooter;
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated footer information.
|
||||
*/
|
||||
void SetFooter(LightObj & o)
|
||||
{
|
||||
Validate();
|
||||
// Is the specified object null?
|
||||
if (o.IsNull())
|
||||
{
|
||||
DropObject< DpEmbedFooter >(mSqFooter);
|
||||
// Finally release the instance
|
||||
mPtr->footer.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto * p = o.CastI< DpEmbedFooter >();
|
||||
// Is this the same instance?
|
||||
if (&p->Valid() == &(mPtr->footer.value()))
|
||||
{
|
||||
return; // Ignore (someone is playing dumb)
|
||||
}
|
||||
// Drop currently associated script object, if any
|
||||
DropObject< DpEmbedFooter >(mSqFooter);
|
||||
// Assign the new object
|
||||
mPtr->footer = *(p->mPtr);
|
||||
}
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated footer information.
|
||||
*/
|
||||
DpEmbed & ApplyFooter(LightObj & o) { SetFooter(o); return *this; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated image information.
|
||||
*/
|
||||
SQMOD_NODISCARD LightObj & GetImage()
|
||||
{
|
||||
// Do we have a value assigned?
|
||||
if (Valid().image.has_value())
|
||||
{
|
||||
// Do we have a script object associated with it?
|
||||
if (mSqImage.IsNull())
|
||||
{
|
||||
// Create the script object with non-owning reference
|
||||
mSqImage = LightObj(SqTypeIdentity< DpEmbedImage >{}, SqVM(), &(mPtr->image.value()), false);
|
||||
}
|
||||
} else mSqImage.Release(); // Make sure this is null
|
||||
// Return the associated script object
|
||||
return mSqImage;
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated image information.
|
||||
*/
|
||||
void SetImage(LightObj & o)
|
||||
{
|
||||
Validate();
|
||||
// Is the specified object null?
|
||||
if (o.IsNull())
|
||||
{
|
||||
DropObject< DpEmbedImage >(mSqImage);
|
||||
// Finally release the instance
|
||||
mPtr->image.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto * p = o.CastI< DpEmbedImage >();
|
||||
// Is this the same instance?
|
||||
if (&p->Valid() == &(mPtr->image.value()))
|
||||
{
|
||||
return; // Ignore (someone is playing dumb)
|
||||
}
|
||||
// Drop currently associated script object, if any
|
||||
DropObject< DpEmbedImage >(mSqImage);
|
||||
// Assign the new object
|
||||
mPtr->image = *(p->mPtr);
|
||||
}
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated image information.
|
||||
*/
|
||||
DpEmbed & ApplyImage(LightObj & o) { SetImage(o); return *this; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated thumbnail information.
|
||||
*/
|
||||
SQMOD_NODISCARD LightObj & GetThumbnail()
|
||||
{
|
||||
// Do we have a value assigned?
|
||||
if (Valid().thumbnail.has_value())
|
||||
{
|
||||
// Do we have a script object associated with it?
|
||||
if (mSqThumbnail.IsNull())
|
||||
{
|
||||
// Create the script object with non-owning reference
|
||||
mSqThumbnail = LightObj(SqTypeIdentity< DpEmbedImage >{}, SqVM(), &(mPtr->thumbnail.value()), false);
|
||||
}
|
||||
} else mSqThumbnail.Release(); // Make sure this is null
|
||||
// Return the associated script object
|
||||
return mSqThumbnail;
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated thumbnail information.
|
||||
*/
|
||||
void SetThumbnail(LightObj & o)
|
||||
{
|
||||
Validate();
|
||||
// Is the specified object null?
|
||||
if (o.IsNull())
|
||||
{
|
||||
DropObject< DpEmbedImage >(mSqThumbnail);
|
||||
// Finally release the instance
|
||||
mPtr->thumbnail.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto * p = o.CastI< DpEmbedImage >();
|
||||
// Is this the same instance?
|
||||
if (&p->Valid() == &(mPtr->thumbnail.value()))
|
||||
{
|
||||
return; // Ignore (someone is playing dumb)
|
||||
}
|
||||
// Drop currently associated script object, if any
|
||||
DropObject< DpEmbedImage >(mSqThumbnail);
|
||||
// Assign the new object
|
||||
mPtr->thumbnail = *(p->mPtr);
|
||||
}
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated thumbnail information.
|
||||
*/
|
||||
DpEmbed & ApplyThumbnail(LightObj & o) { SetThumbnail(o); return *this; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated video information (can't send these).
|
||||
*/
|
||||
SQMOD_NODISCARD LightObj & GetVideo()
|
||||
{
|
||||
// Do we have a value assigned?
|
||||
if (Valid().video.has_value())
|
||||
{
|
||||
// Do we have a script object associated with it?
|
||||
if (mSqVideo.IsNull())
|
||||
{
|
||||
// Create the script object with non-owning reference
|
||||
mSqVideo = LightObj(SqTypeIdentity< DpEmbedImage >{}, SqVM(), &(mPtr->video.value()), false);
|
||||
}
|
||||
} else mSqVideo.Release(); // Make sure this is null
|
||||
// Return the associated script object
|
||||
return mSqVideo;
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated video information (can't send these).
|
||||
*/
|
||||
void SetVideo(LightObj & o)
|
||||
{
|
||||
Validate();
|
||||
// Is the specified object null?
|
||||
if (o.IsNull())
|
||||
{
|
||||
DropObject< DpEmbedImage >(mSqVideo);
|
||||
// Finally release the instance
|
||||
mPtr->video.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto * p = o.CastI< DpEmbedImage >();
|
||||
// Is this the same instance?
|
||||
if (&p->Valid() == &(mPtr->video.value()))
|
||||
{
|
||||
return; // Ignore (someone is playing dumb)
|
||||
}
|
||||
// Drop currently associated script object, if any
|
||||
DropObject< DpEmbedImage >(mSqVideo);
|
||||
// Assign the new object
|
||||
mPtr->video = *(p->mPtr);
|
||||
}
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated video information (can't send these).
|
||||
*/
|
||||
DpEmbed & ApplyVideo(LightObj & o) { SetVideo(o); return *this; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated provider information (can't send these).
|
||||
*/
|
||||
SQMOD_NODISCARD LightObj & GetProvider()
|
||||
{
|
||||
// Do we have a value assigned?
|
||||
if (Valid().provider.has_value())
|
||||
{
|
||||
// Do we have a script object associated with it?
|
||||
if (mSqProvider.IsNull())
|
||||
{
|
||||
// Create the script object with non-owning reference
|
||||
mSqProvider = LightObj(SqTypeIdentity< DpEmbedProvider >{}, SqVM(), &(mPtr->provider.value()), false);
|
||||
}
|
||||
} else mSqProvider.Release(); // Make sure this is null
|
||||
// Return the associated script object
|
||||
return mSqProvider;
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated provider information (can't send these).
|
||||
*/
|
||||
void SetProvider(LightObj & o)
|
||||
{
|
||||
Validate();
|
||||
// Is the specified object null?
|
||||
if (o.IsNull())
|
||||
{
|
||||
DropObject< DpEmbedProvider >(mSqProvider);
|
||||
// Finally release the instance
|
||||
mPtr->provider.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto * p = o.CastI< DpEmbedProvider >();
|
||||
// Is this the same instance?
|
||||
if (&p->Valid() == &(mPtr->provider.value()))
|
||||
{
|
||||
return; // Ignore (someone is playing dumb)
|
||||
}
|
||||
// Drop currently associated script object, if any
|
||||
DropObject< DpEmbedProvider >(mSqProvider);
|
||||
// Assign the new object
|
||||
mPtr->provider = *(p->mPtr);
|
||||
}
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated provider information (can't send these).
|
||||
*/
|
||||
DpEmbed & ApplyProvider(LightObj & o) { SetProvider(o); return *this; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated author information.
|
||||
*/
|
||||
SQMOD_NODISCARD LightObj & GetAuthor()
|
||||
{
|
||||
// Do we have a value assigned?
|
||||
if (Valid().author.has_value())
|
||||
{
|
||||
// Do we have a script object associated with it?
|
||||
if (mSqAuthor.IsNull())
|
||||
{
|
||||
// Create the script object with non-owning reference
|
||||
mSqAuthor = LightObj(SqTypeIdentity< DpEmbedAuthor >{}, SqVM(), &(mPtr->author.value()), false);
|
||||
}
|
||||
} else mSqAuthor.Release(); // Make sure this is null
|
||||
// Return the associated script object
|
||||
return mSqAuthor;
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated author information.
|
||||
*/
|
||||
void SetAuthor(LightObj & o)
|
||||
{
|
||||
Validate();
|
||||
// Is the specified object null?
|
||||
if (o.IsNull())
|
||||
{
|
||||
DropObject< DpEmbedAuthor >(mSqAuthor);
|
||||
// Finally release the instance
|
||||
mPtr->author.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto * p = o.CastI< DpEmbedAuthor >();
|
||||
// Is this the same instance?
|
||||
if (&p->Valid() == &(mPtr->author.value()))
|
||||
{
|
||||
return; // Ignore (someone is playing dumb)
|
||||
}
|
||||
// Drop currently associated script object, if any
|
||||
DropObject< DpEmbedAuthor >(mSqAuthor);
|
||||
// Assign the new object
|
||||
mPtr->author = *(p->mPtr);
|
||||
}
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated author information.
|
||||
*/
|
||||
DpEmbed & ApplyAuthor(LightObj & o) { SetAuthor(o); return *this; }
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated embed fields.
|
||||
*/
|
||||
SQMOD_NODISCARD LightObj & GetFields()
|
||||
{
|
||||
if (mSqFields.IsNull())
|
||||
{
|
||||
mSqFields = LightObj{SqTypeIdentity< Fields >{}, SqVM(), &Valid().fields, false};
|
||||
}
|
||||
// Return the associated script object
|
||||
return mSqFields;
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add an embed field.
|
||||
*/
|
||||
DpEmbed & AddField(StackStrF & name, StackStrF & value)
|
||||
{
|
||||
return AddField_(name, value, false); *this;
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Add an embed field.
|
||||
*/
|
||||
DpEmbed & AddField_(StackStrF & name, StackStrF & value, bool inl)
|
||||
{
|
||||
// Perform the request
|
||||
mPtr->add_field(name.ToStr(), value.ToStr(), inl);
|
||||
// Do we have to sync a script wrapper?
|
||||
if (!mSqFields.IsNull())
|
||||
{
|
||||
mSqFields.CastI< Fields >()->mVec.emplace_back();
|
||||
}
|
||||
// Allow chaining
|
||||
return *this;
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Cleanup script object.
|
||||
*/
|
||||
template < class T > static void DropObject(LightObj & o)
|
||||
{
|
||||
// Do we have a script object associated with it?
|
||||
if (!o.IsNull())
|
||||
{
|
||||
auto * p = o.CastI< T >();
|
||||
// Is this script object the owner of the instance?
|
||||
if (!p->mOwned)
|
||||
{
|
||||
p->Cleanup(); // Invalidate
|
||||
}
|
||||
// Release it and revert to null
|
||||
o.Release();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Represets a reaction to a DpMessage.
|
||||
* Represents a reaction to a DpMessage.
|
||||
*/
|
||||
struct DpReaction
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user