Added demo for cpp module and updated the CppModule

This commit is contained in:
2025-06-24 22:11:15 +03:00
parent 89385a8c89
commit 962d813466
16 changed files with 304 additions and 62 deletions

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\DiscordBotCore.PluginCore\DiscordBotCore.PluginCore.csproj" />
<ProjectReference Include="..\..\Modules\CppCompatibilityModule\CppCompatibilityModule.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,9 @@
using System.Runtime.InteropServices;
namespace CppModuleDemo;
public static class Delegates
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ModifyComplexObject(ref ExampleComplexObject obj);
}

View File

@@ -0,0 +1,19 @@
using System.Runtime.InteropServices;
namespace CppModuleDemo;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct ExampleComplexObject
{
public int IntegerValue;
public double DoubleValue;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string StringValue;
public ExampleComplexObject(int integerValue, double doubleValue, string stringValue)
{
IntegerValue = integerValue;
DoubleValue = doubleValue;
StringValue = stringValue;
}
}

View File

@@ -0,0 +1,10 @@
using CppCompatibilityModule;
using CppCompatibilityModule.Extern;
namespace CppModuleDemo;
internal static class InternalSettings
{
internal static ExternalApplicationHandler? ExternalApplicationHandler { get; set; } = null;
internal static Guid DemoModuleInternalId { get; set; } = Guid.Empty;
}

View File

@@ -0,0 +1,78 @@
using Discord;
using Discord.WebSocket;
using DiscordBotCore.Logging;
using DiscordBotCore.PluginCore.Interfaces;
namespace CppModuleDemo;
public class ModuleSlashCommand : IDbSlashCommand
{
public string Name => "cpp-module-demo";
public string Description => "A demo command to showcase the C++ module integration with Discord Bot Core.";
public bool CanUseDm => false;
public bool HasInteraction => false;
public List<SlashCommandOptionBuilder> Options => new List<SlashCommandOptionBuilder>()
{
new SlashCommandOptionBuilder()
{
Name = "example-integer-value", Description = "An example integer value",
Type = ApplicationCommandOptionType.Integer, IsRequired = true
},
new SlashCommandOptionBuilder()
{
Name = "example-number-value", Description = "An example number value",
Type = ApplicationCommandOptionType.Number, IsRequired = true
},
new SlashCommandOptionBuilder()
{
Name = "example-string-value", Description = "An example boolean value",
Type = ApplicationCommandOptionType.String, IsRequired = true
}
};
public async void ExecuteServer(ILogger logger, SocketSlashCommand context)
{
long integerValue = (long)context.Data.Options.First(option => option.Name == "example-integer-value").Value;
double numberValue = (double)context.Data.Options.First(option => option.Name == "example-number-value").Value;
string stringValue = (string)context.Data.Options.First(option => option.Name == "example-string-value").Value;
if(integerValue > int.MaxValue || integerValue < int.MinValue)
{
await context.Channel.SendMessageAsync("The provided integer value is out of range. Please provide a valid integer.");
return;
}
await context.RespondAsync("Processing your request...", ephemeral: true);
await context.Channel.SendMessageAsync("CppModuleDemo invoked with: \n" +
$"Integer Value: {integerValue}\n" +
$"Number Value: {numberValue}\n" +
$"String Value: {stringValue}");
ExampleComplexObject complexObject = new ExampleComplexObject
{
IntegerValue = (int)integerValue,
DoubleValue = numberValue,
StringValue = stringValue
};
Delegates.ModifyComplexObject? modifyComplexObject =
InternalSettings.ExternalApplicationHandler?.GetFunctionDelegate<Delegates.ModifyComplexObject>(
InternalSettings.DemoModuleInternalId, "modifyComplexObject");
if (modifyComplexObject is null)
{
await context.Channel.SendMessageAsync("Failed to retrieve the C++ function delegate. Please check the C++ module integration.");
return;
}
modifyComplexObject(ref complexObject);
await context.Channel.SendMessageAsync("CppModuleDemo command executed successfully! New values are:\n" +
$"Integer Value: {((ExampleComplexObject)complexObject).IntegerValue}\n" +
$"Number Value: {((ExampleComplexObject)complexObject).DoubleValue}\n" +
$"String Value: {((ExampleComplexObject)complexObject).StringValue}");
}
}

View File

@@ -0,0 +1,31 @@
using CppCompatibilityModule;
using CppCompatibilityModule.Extern;
using DiscordBotCore.PluginCore.Helpers.Execution.DbEvent;
using DiscordBotCore.PluginCore.Interfaces;
namespace CppModuleDemo;
public class StartupEvent : IDbEvent
{
public string Name => "CppModuleDemoStartupEvent";
public string Description => "A demo event to showcase the C++ module integration with Discord Bot Core on startup.";
private static string _DllModule = "libCppModuleDemo.dylib";
public void Start(IDbEventExecutingArgument args)
{
args.PluginBaseDirectory.Create();
InternalSettings.ExternalApplicationHandler = new ExternalApplicationHandler(args.Logger);
string fullPath = Path.Combine(args.PluginBaseDirectory.FullName, _DllModule);
Guid id = InternalSettings.ExternalApplicationHandler.CreateApplication(fullPath);
if (id == Guid.Empty)
{
args.Logger.Log("Failed to create the C++ module application. Please check the DLL path and ensure it is correct.", this);
return;
}
args.Logger.Log($"CppModuleDemo started successfully with application ID: {id}", this);
InternalSettings.DemoModuleInternalId = id;
}
}

View File

@@ -0,0 +1,37 @@
using Discord;
using Discord.WebSocket;
using DiscordBotCore.Logging;
using DiscordBotCore.PluginCore.Interfaces;
namespace CppModuleDemo;
public class StopSlashCommand : IDbSlashCommand
{
public string Name => "stop-cpp-module-demo";
public string Description => "Stops the C++ module demo and cleans up resources.";
public bool CanUseDm => false;
public bool HasInteraction => false;
public List<SlashCommandOptionBuilder> Options => [];
public async void ExecuteServer(ILogger logger, SocketSlashCommand context)
{
if (InternalSettings.ExternalApplicationHandler == null)
{
logger.Log("No C++ module is currently running.", this);
return;
}
Guid id = InternalSettings.DemoModuleInternalId;
if (id == Guid.Empty)
{
logger.Log("No valid C++ module ID found. Cannot stop the module.", this);
return;
}
InternalSettings.ExternalApplicationHandler.StopApplication(id);
InternalSettings.DemoModuleInternalId = Guid.Empty;
logger.Log("CppModuleDemo stopped successfully.", this);
await context.Channel.SendMessageAsync("CppModuleDemo has been stopped and resources cleaned up.");
}
}