diff --git a/CHANGELOG.md b/CHANGELOG.md
index 983d7fb..93fc90c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
The format is based on , and this project adheres mostly to Semantic Versioning. However, all releases before 1.0.0 have breaking changes between minor-version updates.
+## [2.2.0] - 2024-09-24
+
+### Added
+
+- `SocialEventInstance` class that pairs a `SocialEventDef` instance with a set of parameters, allowing for deferred execution outside of `SocialEngine.DispatchEvent(...)`.
+- Additional `SocialEngine.DispatchEvent(SocialEventInstance)` method overload.
+
+### Changed
+
+- `SocialEvent` class has been renamed `SocialEventType` to communicate its role as definition data
+
## [2.1.0] - 2024-07-06
### Added
@@ -71,3 +82,4 @@ _Initial release._
[1.1.0]: https://github.com/ShiJbey/TDRS/releases/tag/v1.1.0
[2.0.0]: https://github.com/ShiJbey/TDRS/releases/tag/v2.0.0
[2.1.0]: https://github.com/ShiJbey/TDRS/releases/tag/v2.1.0
+[2.2.0]: https://github.com/ShiJbey/TDRS/releases/tag/v2.2.0
diff --git a/Packages/com.shijbey.tdrs/Runtime/Serialization/SerializedSocialEvent.cs b/Packages/com.shijbey.tdrs/Runtime/Serialization/SerializedSocialEvent.cs
index 7f4fb23..600f958 100644
--- a/Packages/com.shijbey.tdrs/Runtime/Serialization/SerializedSocialEvent.cs
+++ b/Packages/com.shijbey.tdrs/Runtime/Serialization/SerializedSocialEvent.cs
@@ -30,9 +30,9 @@ public SerializedSocialEvent()
#region Public Methods
- public SocialEvent ToRuntimeInstance()
+ public SocialEventType ToRuntimeInstance()
{
- return new SocialEvent(
+ return new SocialEventType(
name: name,
roles: roles,
description: description,
diff --git a/Packages/com.shijbey.tdrs/Runtime/SocialEngine.cs b/Packages/com.shijbey.tdrs/Runtime/SocialEngine.cs
index 4a74d61..43cae04 100644
--- a/Packages/com.shijbey.tdrs/Runtime/SocialEngine.cs
+++ b/Packages/com.shijbey.tdrs/Runtime/SocialEngine.cs
@@ -455,6 +455,21 @@ public void Tick()
}
}
+ ///
+ /// Create a new SocialEventInstance
+ ///
+ ///
+ ///
+ ///
+ public SocialEventInstance InstantiateSocialEvent(string eventName, params string[] agents)
+ {
+ SocialEventType eventType = SocialEventLibrary.GetSocialEvent($"{eventName}/{agents.Length}");
+
+ var instance = new SocialEventInstance(this, eventType, agents);
+
+ return instance;
+ }
+
///
/// Dispatch an event throughout the social network and apply effects
///
@@ -520,6 +535,20 @@ public void DispatchEvent(string eventName, params string[] agents)
OnSocialEvent?.Invoke(this, new OnSocialEventArgs(eventName, ctx.Description, bindings));
}
+ public void DispatchEvent(SocialEventInstance eventInstance)
+ {
+ eventInstance.Execute();
+
+ OnSocialEvent?.Invoke(
+ this,
+ new OnSocialEventArgs(
+ eventInstance.EventType.Name,
+ eventInstance.Description,
+ eventInstance.Bindings
+ )
+ );
+ }
+
///
/// Reevaluate all relationships against the available social rules.
///
diff --git a/Packages/com.shijbey.tdrs/Runtime/SocialEventInstance.cs b/Packages/com.shijbey.tdrs/Runtime/SocialEventInstance.cs
new file mode 100644
index 0000000..49c22f4
--- /dev/null
+++ b/Packages/com.shijbey.tdrs/Runtime/SocialEventInstance.cs
@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using RePraxis;
+
+namespace TDRS
+{
+ ///
+ /// SocialEventDef data paired with parameters for deferred execution.
+ ///
+ public class SocialEventInstance
+ {
+ #region Fields
+
+ private SocialEngine m_engine;
+ private SocialEventType m_eventType;
+ private EffectContext m_baseContext;
+
+ #endregion
+
+ #region Properties
+
+ public SocialEngine Engine => m_engine;
+ public SocialEventType EventType => m_eventType;
+ public string Description => m_baseContext.Description;
+ public Dictionary Bindings => m_baseContext.Bindings;
+
+ #endregion
+
+ #region Constructors
+
+ public SocialEventInstance(
+ SocialEngine engine,
+ SocialEventType eventType,
+ params string[] agents
+ )
+ {
+ m_engine = engine;
+ m_eventType = eventType;
+
+ var bindings = new Dictionary();
+ for (int i = 0; i < eventType.Roles.Length; i++)
+ {
+ string role = eventType.Roles[i];
+ string agentID = agents[i];
+ bindings[role] = agentID;
+ }
+
+ // Create the base context for the events
+ m_baseContext = new EffectContext(engine, eventType.Description, bindings);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ ///
+ /// Execute the effects of this event and dispatch a C# event.
+ ///
+ public void Dispatch()
+ {
+ m_engine.DispatchEvent(this);
+ }
+
+ ///
+ /// Execute the effects of the event on the social engine.
+ ///
+ public void Execute()
+ {
+ foreach (var response in m_eventType.Responses)
+ {
+ var results = new DBQuery(response.Preconditions)
+ .Run(m_baseContext.Engine.DB, m_baseContext.Bindings);
+
+ // Skip this response because the query failed
+ if (!results.Success) continue;
+
+ // Create a new context for each binding result
+ foreach (var bindingSet in results.Bindings)
+ {
+ var scopedCtx = m_baseContext.WithBindings(bindingSet);
+
+ if (response.Description != "")
+ {
+ scopedCtx.DescriptionTemplate = response.Description;
+ }
+
+ try
+ {
+ var effects = response.Effects
+ .Select(effectString =>
+ {
+ return m_engine.EffectLibrary.CreateInstance(scopedCtx, effectString);
+ });
+
+ foreach (var effect in effects)
+ {
+ effect.Apply();
+ }
+ }
+ catch (ArgumentException ex)
+ {
+ throw new ArgumentException(
+ $"Error encountered while instantiating effects for '{m_eventType.Name}' event: "
+ + ex.Message
+ );
+ }
+ }
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Packages/com.shijbey.tdrs/Runtime/SocialEventInstance.cs.meta b/Packages/com.shijbey.tdrs/Runtime/SocialEventInstance.cs.meta
new file mode 100644
index 0000000..5f71cfc
--- /dev/null
+++ b/Packages/com.shijbey.tdrs/Runtime/SocialEventInstance.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3f34dc02abe5349fb98c22c41c35a19c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/com.shijbey.tdrs/Runtime/SocialEventLibrary.cs b/Packages/com.shijbey.tdrs/Runtime/SocialEventLibrary.cs
index aa8c27c..130c8ba 100644
--- a/Packages/com.shijbey.tdrs/Runtime/SocialEventLibrary.cs
+++ b/Packages/com.shijbey.tdrs/Runtime/SocialEventLibrary.cs
@@ -12,17 +12,17 @@ public class SocialEventLibrary
///
/// Event definitions sorted by name and cardinality.
///
- protected Dictionary m_events;
+ protected Dictionary m_events;
#endregion
- public Dictionary Events => m_events;
+ public Dictionary Events => m_events;
#region Constructors
public SocialEventLibrary()
{
- m_events = new Dictionary();
+ m_events = new Dictionary();
}
#endregion
@@ -33,7 +33,7 @@ public SocialEventLibrary()
/// Add a social event to the library.
///
///
- public void AddSocialEvent(SocialEvent socialEvent)
+ public void AddSocialEvent(SocialEventType socialEvent)
{
m_events[socialEvent.Symbol] = socialEvent;
}
@@ -43,7 +43,7 @@ public void AddSocialEvent(SocialEvent socialEvent)
///
///
///
- public SocialEvent GetSocialEvent(string symbol)
+ public SocialEventType GetSocialEvent(string symbol)
{
return m_events[symbol];
}
diff --git a/Packages/com.shijbey.tdrs/Runtime/SocialEventSO.cs b/Packages/com.shijbey.tdrs/Runtime/SocialEventSO.cs
index 217d01f..9023b70 100644
--- a/Packages/com.shijbey.tdrs/Runtime/SocialEventSO.cs
+++ b/Packages/com.shijbey.tdrs/Runtime/SocialEventSO.cs
@@ -25,7 +25,7 @@ public class SocialEventSO : ScriptableObject
[SerializeField]
private TriggerRuleData[] m_triggerRules;
- public SocialEvent GetSocialEvent()
+ public SocialEventType GetSocialEvent()
{
if (m_eventName == "")
{
@@ -65,7 +65,7 @@ public SocialEvent GetSocialEvent()
};
}
- var socialEvent = new SocialEvent(
+ var socialEvent = new SocialEventType(
name,
m_roles,
m_description,
diff --git a/Packages/com.shijbey.tdrs/Runtime/SocialEvent.cs b/Packages/com.shijbey.tdrs/Runtime/SocialEventType.cs
similarity index 95%
rename from Packages/com.shijbey.tdrs/Runtime/SocialEvent.cs
rename to Packages/com.shijbey.tdrs/Runtime/SocialEventType.cs
index 6cb28b4..79f1abd 100644
--- a/Packages/com.shijbey.tdrs/Runtime/SocialEvent.cs
+++ b/Packages/com.shijbey.tdrs/Runtime/SocialEventType.cs
@@ -5,7 +5,7 @@ namespace TDRS
///
/// Definition information for creating SocialEvent instances
///
- public class SocialEvent
+ public class SocialEventType
{
#region Fields
@@ -31,7 +31,7 @@ public class SocialEvent
#region Constructors
- public SocialEvent(
+ public SocialEventType(
string name,
string[] roles,
string description,
diff --git a/Packages/com.shijbey.tdrs/Runtime/SocialEvent.cs.meta b/Packages/com.shijbey.tdrs/Runtime/SocialEventType.cs.meta
similarity index 100%
rename from Packages/com.shijbey.tdrs/Runtime/SocialEvent.cs.meta
rename to Packages/com.shijbey.tdrs/Runtime/SocialEventType.cs.meta
diff --git a/Packages/com.shijbey.tdrs/Runtime/SocialEventYamlLoader.cs b/Packages/com.shijbey.tdrs/Runtime/SocialEventYamlLoader.cs
index 81f9975..5d01d1a 100644
--- a/Packages/com.shijbey.tdrs/Runtime/SocialEventYamlLoader.cs
+++ b/Packages/com.shijbey.tdrs/Runtime/SocialEventYamlLoader.cs
@@ -15,11 +15,11 @@ public class SocialEventYamlLoader
///
///
///
- public SocialEvent LoadSocialEvent(string yamlString)
+ public SocialEventType LoadSocialEvent(string yamlString)
{
var deserializer = new DeserializerBuilder().Build();
- SocialEvent socialEvent = deserializer
+ SocialEventType socialEvent = deserializer
.Deserialize(yamlString)
.ToRuntimeInstance();
@@ -31,11 +31,11 @@ public SocialEvent LoadSocialEvent(string yamlString)
///
///
///
- public List LoadSocialEvents(string yamlString)
+ public List LoadSocialEvents(string yamlString)
{
var deserializer = new DeserializerBuilder().Build();
- List socialEvent = deserializer
+ List socialEvent = deserializer
.Deserialize>(yamlString)
.Select(e => { return e.ToRuntimeInstance(); })
.ToList();
diff --git a/Packages/com.shijbey.tdrs/Tests/Editor/TestSocialEngine.cs b/Packages/com.shijbey.tdrs/Tests/Editor/TestSocialEngine.cs
index 4ebec84..3fd1c09 100644
--- a/Packages/com.shijbey.tdrs/Tests/Editor/TestSocialEngine.cs
+++ b/Packages/com.shijbey.tdrs/Tests/Editor/TestSocialEngine.cs
@@ -121,7 +121,7 @@ public void SetUp()
);
_engine.SocialEventLibrary.AddSocialEvent(
- new SocialEvent(
+ new SocialEventType(
name: "compliment",
roles: new string[]
{
@@ -305,6 +305,33 @@ public void TestDispatchEvent()
Assert.That(lisa.Traits.HasTrait("recently-complimented"), Is.False);
}
+ ///
+ /// Test that you can create social event instances and dispatch them.
+ ///
+ [Test]
+ public void TestCreateAndDispatchSocialEvent()
+ {
+ var jose = _engine.AddAgent("agent", "jose");
+ var lisa = _engine.AddAgent("agent", "lisa");
+ var sara = _engine.AddAgent("agent", "sara");
+
+ Assert.That(lisa.Traits.HasTrait("recently-complimented"), Is.False);
+
+ SocialEventInstance complimentEventInstance =
+ _engine.InstantiateSocialEvent("compliment", "jose", "lisa");
+
+ complimentEventInstance.Dispatch();
+
+ Assert.That(lisa.Traits.HasTrait("recently-complimented"), Is.True);
+
+ _engine.Tick();
+ _engine.Tick();
+ _engine.Tick();
+ _engine.Tick();
+
+ Assert.That(lisa.Traits.HasTrait("recently-complimented"), Is.False);
+ }
+
///
/// Ensure all agents and relationships are removed from the state.
///