1
0
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

This commit is contained in:
Sandu Liviu Catalin 2021-09-23 22:13:13 +03:00
parent 259af04d0e
commit 1d85603dfb
2 changed files with 482 additions and 3 deletions

View File

@ -170,6 +170,32 @@ void Register_DPP_Message(HSQUIRRELVM vm, Table & ns)
.SquirrelFunc(_SC("_typename"), &SqDppEmbed::Fn) .SquirrelFunc(_SC("_typename"), &SqDppEmbed::Fn)
// Member Properties // Member Properties
.Prop(_SC("Valid"), &DpEmbed::IsValid) .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"), ns.Bind(_SC("Reaction"),

View File

@ -291,7 +291,7 @@ struct DpComponent
// Cleanup options, if any // Cleanup options, if any
if (!mSqOptions.IsNull()) if (!mSqOptions.IsNull())
{ {
mSqOptions.CastI< Components >()->Cleanup(); mSqOptions.CastI< Options >()->Cleanup();
// Release script resources // Release script resources
mSqOptions.Release(); mSqOptions.Release();
} }
@ -473,7 +473,7 @@ struct DpComponent
} }
/* -------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------
* Add a sub-component, only valid for action rows. * 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) DpComponent & AddComponent(DpComponent & comp)
{ {
@ -1288,6 +1288,16 @@ struct DpEmbed
* Whether the referenced pointer is owned. * Whether the referenced pointer is owned.
*/ */
bool mOwned{false}; 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. * Default constructor.
*/ */
@ -1344,6 +1354,19 @@ struct DpEmbed
*/ */
void Cleanup() 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? // Do we own this to try delete it?
if (!mOwned && mPtr) { if (!mOwned && mPtr) {
// Not our job, simply forget about it // Not our job, simply forget about it
@ -1362,11 +1385,441 @@ struct DpEmbed
* Check whether a valid instance is managed. * Check whether a valid instance is managed.
*/ */
SQMOD_NODISCARD bool IsValid() const { return static_cast< bool >(mPtr); } 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 struct DpReaction
{ {