SlideShare a Scribd company logo
Using Reflections and Automatic
Code Generation
Ivan Dolgushin
Game Developer
Appturn
It is Very Technical:
• A lot of code
• Only 5 pictures
• About not writing code
Cloning
namespace System
{
[ComVisible (true)]
public interface ICloneable
{
//
// Methods
//
object Clone ();
}
}
#region ICloneable implementation
public virtual object Clone()
{
return new BaseClass(this);
}
#endregion
Manual Implementation
#region ICloneable implementation
public override object Clone()
{
return new DerivedClass(this);
}
#endregion
Manual Implementation
#region ICloneable implementation
public virtual object Clone()
{
return new BaseClass(this);
}
#endregion
#region ICloneable implementation
public override object Clone()
{
return new DerivedClass(this);
}
#endregion
Manual Implementation
System.Activator
#region ICloneable implementation
public object Clone()
{
return Activator
.CreateInstance(
this.GetType(),
this
);
}
#endregion
Factory
public static BaseEffect CreateEffect(
Creature owner, Creature caster,
EEffectType effectType, byte effectlLevel)
{
var effectInfo = ObjectsConfig.Instance
.GetEffectInfo(effectType);
return (BaseEffect)Activator
.CreateInstance(
Type.GetType(effectInfo.TypeName),
owner, caster,
effectType, effectlLevel);
}
System.Reflection
#region ICloneable implementation
public object Clone()
{
return this
.GetType().GetConstructor(
new Type[] { this.GetType() }
).Invoke(new object[] { this });
}
#endregion
Field Value Comparison
Data Storage Classes
public class ObjectBaseLevelInfo
{
public int RequiredObjectLevel = 0;
public int LaboratoryUpgradeCost = 0;
public uint LaboratoryUpgradeDuration = 0;
public int UpgradeCost = 0;
public uint UpgradeDuration = 0;
public int Hp = 0;
public int XpAmount = 0;
public int VisualLevel = 1;
}
Data Storage Classes
public class MonsterLevelInfo
: ObjectBaseLevelInfo
{
public int Xp = 0;
public float MovementSpeed = 0f;
public byte MinLvlDrop = 0;
public byte MaxLvlDrop = 0;
public float DropChance = 0f;
}
Manual Comparator
public override bool Equals(object obj)
{
MonsterLevelInfo other
= obj as MonsterLevelInfo;
return null != obj
&& base.Equals(obj)
&& Xp == other.Xp
&& MovementSpeed == other.MovementSpeed
&& MinLvlDrop == other.MinLvlDrop
&& MaxLvlDrop == other.MaxLvlDrop
&& DropChance == other.DropChance;
}
System.Reflection
public static bool ValueEqual(this object a, object b)
{
if (object.ReferenceEquals(a, b)) return true;
Type typeA = a.GetType();
if (typeA != b.GetType()) return false;
foreach (FieldInfo fi in typeA.GetFields(
BindingFlags.Public |
BindingFlags.GetField |
BindingFlags.GetProperty |
BindingFlags.FlattenHierarchy))
{
if (fi.GetValue(a) != fi.GetValue(b))
return false;
}
return true;
}
Let’s Add More Control
[AttributeUsage(AttributeTargets.Field)]
public class DontCompareAttribute : Attribute {}
public static bool ValueEqual(this object a, object b)
{
...
foreach (FieldInfo fi in typeA.GetFields(...))
{
if (fi.GetCustomAttributes(
typeof(DontCompareAttribute),
true).Length == 0
&& fi.GetValue(a) != fi.GetValue(b))
return false;
}
return true;
}
Data Storage Class
public class MonsterLevelInfo
: ObjectBaseLevelInfo
{
public int Xp = 0;
public float MovementSpeed = 0f;
public byte MinLvlDrop = 0;
public byte MaxLvlDrop = 0;
[DontCompare]
public float DropChance = 0f;
}
Data Storage Class
[Serializable]
[XmlType("MonsterLevel")]
public class MonsterLevelInfo : ObjectBaseLevelInfo
{
[XmlAttribute]
public int Xp = 0;
[XmlAttribute]
public float MovementSpeed = 0f;
[XmlAttribute]
public byte MinLvlDrop = 0;
[XmlAttribute]
public byte MaxLvlDrop = 0;
[XmlAttribute]
[DontCompare]
public float DropChance = 0f;
}
System.CodeDom
public static void GenerateComparators()
{
CodeCompileUnit targetUnit;
CodeTypeDeclaration targetClass;
Assembly assembly = GetAssemblies().First(a => a.GetName().Name == "Assembly-CSharp");
foreach (Type type in assembly.GetTypes())
{
object[] genAttributes = type.GetCustomAttributes(typeof(GenerateComparatorAttribute), false);
if (genAttributes.Length > 0)
{
targetUnit = new CodeCompileUnit();
CodeNamespace ns = new CodeNamespace(type.Namespace);
ns.Imports.Add(new CodeNamespaceImport("System"));
targetClass = new CodeTypeDeclaration(type.Name);
targetClass.IsClass = true; targetClass.IsPartial = true;
targetClass.TypeAttributes = TypeAttributes.Public;
ns.Types.Add(targetClass);
targetUnit.Namespaces.Add(ns);
targetClass.Members.Add(GenerateComparator(type));
using (CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp")) {
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";
string outputFileName = Path.Combine(outputDirName, type.FullName + ".Comparator.cs");
using (StreamWriter sourceWriter = new StreamWriter(outputFileName))
{
provider.GenerateCodeFromCompileUnit(targetUnit, sourceWriter, options);
}
}
}
}
}
System.CodeDom
foreach (FieldInfo fi in type.GetFields(...))
{
var checkExpr = new CodeBinaryOperatorExpression(
new CodeFieldReferenceExpression(thisRef, fi.Name),
CodeBinaryOperatorType.ValueEquality,
new CodeFieldReferenceExpression(argRef, fi.Name));
var appendExpr = new CodeBinaryOperatorExpression(
retRef, CodeBinaryOperatorType.BooleanAnd, checkExpr);
CodeAssignStatement checkStatement =
new CodeAssignStatement(retRef, appendExpr);
compareMethod.Statements.Add(checkStatement);
}
Call It With Unity Menu
public static partial class CodeGeneration
{
[MenuItem("Tools/Code Generation/Comparators",
false, 1103)]
public static void GenerateComparators()
{
Comparer.GenerateComparators();
}
}
WYG
public partial class MonsterLevelInfo
{
public override bool Equals(object obj)
{
bool rv = true;
MonsterLevelInfo other=obj as MonsterLevelInfo;
if ((other == null)) return false;
rv = (rv && (this.Xp == other.Xp));
...
rv = (rv && (this.Hp == other.Hp));
rv = (rv && (this.XpAmount == other.XpAmount));
return rv ;
}
}
Enum Converter
Generated Convert Method
public static EResearch MonsterToResearchType(EObject v)
{
EResearchType rv = default(EResearchType);
switch (v) {
case EObject.Cobra: rv = EResearch.Cobra; break;
case EObject.Crab: rv = EResearch.Crab; break;
case EObject.Kobold: rv = EResearch.Kobold; break;
case EObject.Orc: rv = EResearch.Orc; break;
case EObject.Shaman: rv = EResearch.Shaman; break;
case EObject.Spider: rv = EResearch.Spider; break;
case EObject.Imp: rv = EResearch.Imp; break;
}
return rv;
}
System.CodeDom
System.CodeDom
StringBuilder switchBuilder = new StringBuilder();
switchBuilder.AppendLine("switch (v) {");
foreach(var val in Enum.GetNames(sourceEnum))
{
if (Enum.IsDefined(destEnum, val))
{
switchBuilder.AppendFormat(
"case {0}.{2}: retValue = {1}.{2}; ",
sourceEnum, destEnum, val);
switchBuilder.AppendLine("break;");
}
}
convertMethod.Statements.Add(
new CodeSnippetStatement(switchBuilder));
Xml Serialization
XML Serializer Generator Tool
(Sgen.exe)
The XML Serializer Generator creates an XML
serialization assembly for types in a specified
assembly in order to improve the startup
performance of a XmlSerializer when it serializes
or deserializes objects of the specified types.
Sgen.exe
rm -R *.cs
sgen --assembly:Assembly-CSharp.dll 
--reference:UnityEngine.dll 
--verbose --force --keep 
--type:PaperPath.ObjectBaseLevelInfo 
--type:PaperPath.MonsterLevelInfo 
...
--type:PaperPath.CharacterLevelInfo 
result=$(find . -name *.cs)
mv $result ../Assets/Classes/GeneratedSerializers.cs
rm Assembly-CSharp.XmlSerializers.dll
Do It with Unity
[MenuItem("Tools/Code Generation/Serializers”)]
public static void RegenerateSerializers()
{
System.IO.Directory.CreateDirectory(OutDir);
CompileAssemblies();
PrepareSGen();
GenerateSerializers();
System.IO.Directory.Delete(OutDir, true);
}
Compile
public static void CompileAssemblies()
{
HandleExecutable he = new HandleExecutable();
he.OutputHandler = Log;
he.ErrorHandler = LogError;
string Configuration = "Debug";
string Solution = "Client.sln";
he.CallExecutable("xbuild"
, string.Format("/property:OutDir={0}
/p:Configuration={1} {2}",
OutDir, Configuration, Solution)
, ””, true);
}
Prepare Script
public static string GetScript()
{
StringBuilder sgenScript = new StringBuilder();
sgenScript.AppendLine("rm -R *.cs");
sgenScript.AppendFormat("sgen --assembly:{0} --reference:{1}” +
” --force –keep”, AssemblyPath, DependencyPaths);
foreach (Type type in GetAssembly().GetTypes())
{
object[] genAttributes = type.GetCustomAttributes(
typeof(GenerateSerializersAttribute), false);
if (genAttributes.Length > 0)
sgenScript.AppendLine(" --type:" + type.FullName + " ");
}
sgenScript.AppendLine();
sgenScript.AppendLine("result=$(find . -name *.cs)");
sgenScript.AppendLine("mv $result ../" + GeneratedSerializersPath);
sgenScript.AppendLine("rm Assembly-CSharp.XmlSerializers.dll");
return sgenScript;
}
Run Script and Postprocess
public static void GenerateSerializers()
{
HandleExecutable he = new HandleExecutable();
he.CallExecutable("sh”, "generate.sh”, OutDir, true);
string serializersCode = File.ReadAllText(GSPath);
serializersCode = serializersCode.Replace(
"(type.FullName)",
"(type.FullName.Replace("+", "."))");
File.WriteAllText(
GeneratedSerializersPath,
serializersCode);
}
Thank You!
Questions?
Feel free to contact me
ivand@appturn.com
Ad

More Related Content

What's hot (20)

ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
Domenic Denicola
 
Google Guava
Google GuavaGoogle Guava
Google Guava
Alexander Korotkikh
 
响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架
jeffz
 
Google Guava & EMF @ GTUG Nantes
Google Guava & EMF @ GTUG NantesGoogle Guava & EMF @ GTUG Nantes
Google Guava & EMF @ GTUG Nantes
mikaelbarbero
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
RameshNair6
 
Clean code with google guava jee conf
Clean code with google guava jee confClean code with google guava jee conf
Clean code with google guava jee conf
Igor Anishchenko
 
Google guava overview
Google guava overviewGoogle guava overview
Google guava overview
Steve Min
 
Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streams
mattpodwysocki
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
Adam L Barrett
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
Duoyi Wu
 
V8
V8V8
V8
changehee lee
 
A JIT Smalltalk VM written in itself
A JIT Smalltalk VM written in itselfA JIT Smalltalk VM written in itself
A JIT Smalltalk VM written in itself
ESUG
 
Javascript tid-bits
Javascript tid-bitsJavascript tid-bits
Javascript tid-bits
David Atchley
 
Explaining ES6: JavaScript History and What is to Come
Explaining ES6: JavaScript History and What is to ComeExplaining ES6: JavaScript History and What is to Come
Explaining ES6: JavaScript History and What is to Come
Cory Forsyth
 
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
e-Legion
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.
boyney123
 
Painless Persistence with Realm
Painless Persistence with RealmPainless Persistence with Realm
Painless Persistence with Realm
Christian Melchior
 
連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」
matuura_core
 
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Kenji Tanaka
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
Howard Lewis Ship
 
响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架
jeffz
 
Google Guava & EMF @ GTUG Nantes
Google Guava & EMF @ GTUG NantesGoogle Guava & EMF @ GTUG Nantes
Google Guava & EMF @ GTUG Nantes
mikaelbarbero
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
RameshNair6
 
Clean code with google guava jee conf
Clean code with google guava jee confClean code with google guava jee conf
Clean code with google guava jee conf
Igor Anishchenko
 
Google guava overview
Google guava overviewGoogle guava overview
Google guava overview
Steve Min
 
Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streams
mattpodwysocki
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
Adam L Barrett
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
Duoyi Wu
 
A JIT Smalltalk VM written in itself
A JIT Smalltalk VM written in itselfA JIT Smalltalk VM written in itself
A JIT Smalltalk VM written in itself
ESUG
 
Explaining ES6: JavaScript History and What is to Come
Explaining ES6: JavaScript History and What is to ComeExplaining ES6: JavaScript History and What is to Come
Explaining ES6: JavaScript History and What is to Come
Cory Forsyth
 
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
e-Legion
 
Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.Introduction into ES6 JavaScript.
Introduction into ES6 JavaScript.
boyney123
 
Painless Persistence with Realm
Painless Persistence with RealmPainless Persistence with Realm
Painless Persistence with Realm
Christian Melchior
 
連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」
matuura_core
 
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Kenji Tanaka
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
Howard Lewis Ship
 

Viewers also liked (13)

Process instrumentation unit 02
Process instrumentation unit 02Process instrumentation unit 02
Process instrumentation unit 02
Rajamangala University of Technology Rattanakosin
 
Teamworking
TeamworkingTeamworking
Teamworking
Ivan Dolgushin
 
Name list tnca thai assembly
Name list tnca thai assemblyName list tnca thai assembly
Name list tnca thai assembly
joansr9
 
TNCA Thai assembly
TNCA Thai assemblyTNCA Thai assembly
TNCA Thai assembly
0804998818
 
Output log
Output logOutput log
Output log
yranos94
 
กิจกรรมที่ 4 วงจรการพัฒนาโปรแกรม
กิจกรรมที่ 4 วงจรการพัฒนาโปรแกรมกิจกรรมที่ 4 วงจรการพัฒนาโปรแกรม
กิจกรรมที่ 4 วงจรการพัฒนาโปรแกรม
draught
 
Practice of Android Reverse Engineering
Practice of Android Reverse EngineeringPractice of Android Reverse Engineering
Practice of Android Reverse Engineering
National Cheng Kung University
 
Microprocessor chapter 9 - assembly language programming
Microprocessor  chapter 9 - assembly language programmingMicroprocessor  chapter 9 - assembly language programming
Microprocessor chapter 9 - assembly language programming
Wondeson Emeye
 
Assembly Language Lecture 5
Assembly Language Lecture 5Assembly Language Lecture 5
Assembly Language Lecture 5
Motaz Saad
 
List of 8085 programs
List of 8085 programsList of 8085 programs
List of 8085 programs
ASHOKA INSTITUTE OF TECHNOLOGY & MANAGEMENT,VARANASI,U.P.
 
Assembly Language Programming Of 8085
Assembly Language Programming Of 8085Assembly Language Programming Of 8085
Assembly Language Programming Of 8085
techbed
 
Assembly language programming(unit 4)
Assembly language programming(unit 4)Assembly language programming(unit 4)
Assembly language programming(unit 4)
Ashim Saha
 
Name list tnca thai assembly
Name list tnca thai assemblyName list tnca thai assembly
Name list tnca thai assembly
joansr9
 
TNCA Thai assembly
TNCA Thai assemblyTNCA Thai assembly
TNCA Thai assembly
0804998818
 
Output log
Output logOutput log
Output log
yranos94
 
กิจกรรมที่ 4 วงจรการพัฒนาโปรแกรม
กิจกรรมที่ 4 วงจรการพัฒนาโปรแกรมกิจกรรมที่ 4 วงจรการพัฒนาโปรแกรม
กิจกรรมที่ 4 วงจรการพัฒนาโปรแกรม
draught
 
Microprocessor chapter 9 - assembly language programming
Microprocessor  chapter 9 - assembly language programmingMicroprocessor  chapter 9 - assembly language programming
Microprocessor chapter 9 - assembly language programming
Wondeson Emeye
 
Assembly Language Lecture 5
Assembly Language Lecture 5Assembly Language Lecture 5
Assembly Language Lecture 5
Motaz Saad
 
Assembly Language Programming Of 8085
Assembly Language Programming Of 8085Assembly Language Programming Of 8085
Assembly Language Programming Of 8085
techbed
 
Assembly language programming(unit 4)
Assembly language programming(unit 4)Assembly language programming(unit 4)
Assembly language programming(unit 4)
Ashim Saha
 
Ad

Similar to Using Reflections and Automatic Code Generation (20)

PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
Andrey Karpov
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
Tomáš Kypta
 
Using the Windows 8 Runtime from C++
Using the Windows 8 Runtime from C++Using the Windows 8 Runtime from C++
Using the Windows 8 Runtime from C++
Microsoft Developer Network (MSDN) - Belgium and Luxembourg
 
JavaScript (without DOM)
JavaScript (without DOM)JavaScript (without DOM)
JavaScript (without DOM)
Piyush Katariya
 
Object-oriented Basics
Object-oriented BasicsObject-oriented Basics
Object-oriented Basics
Jamie (Taka) Wang
 
The Xtext Grammar Language
The Xtext Grammar LanguageThe Xtext Grammar Language
The Xtext Grammar Language
Dr. Jan Köhnlein
 
2. Design patterns. part #2
2. Design patterns. part #22. Design patterns. part #2
2. Design patterns. part #2
Leonid Maslov
 
Java Script Workshop
Java Script WorkshopJava Script Workshop
Java Script Workshop
Dmitry Baranovskiy
 
JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)JavaScript - i och utanför webbläsaren (2010-03-03)
JavaScript - i och utanför webbläsaren (2010-03-03)
Anders Jönsson
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
andyrobinson8
 
Introduction kot iin
Introduction kot iinIntroduction kot iin
Introduction kot iin
Jedsada Tiwongvokul
 
Dlr
DlrDlr
Dlr
sharp-blade
 
Dynamic C#
Dynamic C# Dynamic C#
Dynamic C#
Antya Dev
 
Get started with YUI
Get started with YUIGet started with YUI
Get started with YUI
Adam Lu
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
Thierry Wasylczenko
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
Dmitry Sheiko
 
Java script for web developer
Java script for web developerJava script for web developer
Java script for web developer
Chalermpon Areepong
 
Deep dive into Oracle ADF
Deep dive into Oracle ADFDeep dive into Oracle ADF
Deep dive into Oracle ADF
Euegene Fedorenko
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
HamletDRC
 
Event recvr ss
Event recvr ssEvent recvr ss
Event recvr ss
Gayathri Narayanan
 
Ad

Recently uploaded (20)

Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Eric D. Schabell
 
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
Andre Hora
 
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AIScaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
danshalev
 
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage DashboardsAdobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
BradBedford3
 
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
AxisTechnolabs
 
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
ssuserb14185
 
PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025
mu394968
 
Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025
kashifyounis067
 
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdfMicrosoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
TechSoup
 
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
Egor Kaleynik
 
Not So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java WebinarNot So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java Webinar
Tier1 app
 
Douwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License codeDouwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License code
aneelaramzan63
 
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
F-Secure Freedome VPN 2025 Crack Plus Activation  New VersionF-Secure Freedome VPN 2025 Crack Plus Activation  New Version
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
saimabibi60507
 
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Andre Hora
 
Expand your AI adoption with AgentExchange
Expand your AI adoption with AgentExchangeExpand your AI adoption with AgentExchange
Expand your AI adoption with AgentExchange
Fexle Services Pvt. Ltd.
 
Societal challenges of AI: biases, multilinguism and sustainability
Societal challenges of AI: biases, multilinguism and sustainabilitySocietal challenges of AI: biases, multilinguism and sustainability
Societal challenges of AI: biases, multilinguism and sustainability
Jordi Cabot
 
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
steaveroggers
 
Revolutionizing Residential Wi-Fi PPT.pptx
Revolutionizing Residential Wi-Fi PPT.pptxRevolutionizing Residential Wi-Fi PPT.pptx
Revolutionizing Residential Wi-Fi PPT.pptx
nidhisingh691197
 
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Dele Amefo
 
Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025
kashifyounis067
 
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Eric D. Schabell
 
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
Andre Hora
 
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AIScaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
danshalev
 
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage DashboardsAdobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
Adobe Marketo Engage Champion Deep Dive - SFDC CRM Synch V2 & Usage Dashboards
BradBedford3
 
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
Interactive odoo dashboards for sales, CRM , Inventory, Invoice, Purchase, Pr...
AxisTechnolabs
 
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
ssuserb14185
 
PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025
mu394968
 
Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025
kashifyounis067
 
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdfMicrosoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
TechSoup
 
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
Egor Kaleynik
 
Not So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java WebinarNot So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java Webinar
Tier1 app
 
Douwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License codeDouwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License code
aneelaramzan63
 
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
F-Secure Freedome VPN 2025 Crack Plus Activation  New VersionF-Secure Freedome VPN 2025 Crack Plus Activation  New Version
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
saimabibi60507
 
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Andre Hora
 
Expand your AI adoption with AgentExchange
Expand your AI adoption with AgentExchangeExpand your AI adoption with AgentExchange
Expand your AI adoption with AgentExchange
Fexle Services Pvt. Ltd.
 
Societal challenges of AI: biases, multilinguism and sustainability
Societal challenges of AI: biases, multilinguism and sustainabilitySocietal challenges of AI: biases, multilinguism and sustainability
Societal challenges of AI: biases, multilinguism and sustainability
Jordi Cabot
 
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
steaveroggers
 
Revolutionizing Residential Wi-Fi PPT.pptx
Revolutionizing Residential Wi-Fi PPT.pptxRevolutionizing Residential Wi-Fi PPT.pptx
Revolutionizing Residential Wi-Fi PPT.pptx
nidhisingh691197
 
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Salesforce Data Cloud- Hyperscale data platform, built for Salesforce.
Dele Amefo
 
Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025
kashifyounis067
 

Using Reflections and Automatic Code Generation

  • 1. Using Reflections and Automatic Code Generation Ivan Dolgushin Game Developer Appturn
  • 2. It is Very Technical: • A lot of code • Only 5 pictures • About not writing code
  • 4. namespace System { [ComVisible (true)] public interface ICloneable { // // Methods // object Clone (); } }
  • 5. #region ICloneable implementation public virtual object Clone() { return new BaseClass(this); } #endregion Manual Implementation
  • 6. #region ICloneable implementation public override object Clone() { return new DerivedClass(this); } #endregion Manual Implementation
  • 7. #region ICloneable implementation public virtual object Clone() { return new BaseClass(this); } #endregion #region ICloneable implementation public override object Clone() { return new DerivedClass(this); } #endregion Manual Implementation
  • 8. System.Activator #region ICloneable implementation public object Clone() { return Activator .CreateInstance( this.GetType(), this ); } #endregion
  • 9. Factory public static BaseEffect CreateEffect( Creature owner, Creature caster, EEffectType effectType, byte effectlLevel) { var effectInfo = ObjectsConfig.Instance .GetEffectInfo(effectType); return (BaseEffect)Activator .CreateInstance( Type.GetType(effectInfo.TypeName), owner, caster, effectType, effectlLevel); }
  • 10. System.Reflection #region ICloneable implementation public object Clone() { return this .GetType().GetConstructor( new Type[] { this.GetType() } ).Invoke(new object[] { this }); } #endregion
  • 12. Data Storage Classes public class ObjectBaseLevelInfo { public int RequiredObjectLevel = 0; public int LaboratoryUpgradeCost = 0; public uint LaboratoryUpgradeDuration = 0; public int UpgradeCost = 0; public uint UpgradeDuration = 0; public int Hp = 0; public int XpAmount = 0; public int VisualLevel = 1; }
  • 13. Data Storage Classes public class MonsterLevelInfo : ObjectBaseLevelInfo { public int Xp = 0; public float MovementSpeed = 0f; public byte MinLvlDrop = 0; public byte MaxLvlDrop = 0; public float DropChance = 0f; }
  • 14. Manual Comparator public override bool Equals(object obj) { MonsterLevelInfo other = obj as MonsterLevelInfo; return null != obj && base.Equals(obj) && Xp == other.Xp && MovementSpeed == other.MovementSpeed && MinLvlDrop == other.MinLvlDrop && MaxLvlDrop == other.MaxLvlDrop && DropChance == other.DropChance; }
  • 15. System.Reflection public static bool ValueEqual(this object a, object b) { if (object.ReferenceEquals(a, b)) return true; Type typeA = a.GetType(); if (typeA != b.GetType()) return false; foreach (FieldInfo fi in typeA.GetFields( BindingFlags.Public | BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.FlattenHierarchy)) { if (fi.GetValue(a) != fi.GetValue(b)) return false; } return true; }
  • 16. Let’s Add More Control [AttributeUsage(AttributeTargets.Field)] public class DontCompareAttribute : Attribute {} public static bool ValueEqual(this object a, object b) { ... foreach (FieldInfo fi in typeA.GetFields(...)) { if (fi.GetCustomAttributes( typeof(DontCompareAttribute), true).Length == 0 && fi.GetValue(a) != fi.GetValue(b)) return false; } return true; }
  • 17. Data Storage Class public class MonsterLevelInfo : ObjectBaseLevelInfo { public int Xp = 0; public float MovementSpeed = 0f; public byte MinLvlDrop = 0; public byte MaxLvlDrop = 0; [DontCompare] public float DropChance = 0f; }
  • 18. Data Storage Class [Serializable] [XmlType("MonsterLevel")] public class MonsterLevelInfo : ObjectBaseLevelInfo { [XmlAttribute] public int Xp = 0; [XmlAttribute] public float MovementSpeed = 0f; [XmlAttribute] public byte MinLvlDrop = 0; [XmlAttribute] public byte MaxLvlDrop = 0; [XmlAttribute] [DontCompare] public float DropChance = 0f; }
  • 19. System.CodeDom public static void GenerateComparators() { CodeCompileUnit targetUnit; CodeTypeDeclaration targetClass; Assembly assembly = GetAssemblies().First(a => a.GetName().Name == "Assembly-CSharp"); foreach (Type type in assembly.GetTypes()) { object[] genAttributes = type.GetCustomAttributes(typeof(GenerateComparatorAttribute), false); if (genAttributes.Length > 0) { targetUnit = new CodeCompileUnit(); CodeNamespace ns = new CodeNamespace(type.Namespace); ns.Imports.Add(new CodeNamespaceImport("System")); targetClass = new CodeTypeDeclaration(type.Name); targetClass.IsClass = true; targetClass.IsPartial = true; targetClass.TypeAttributes = TypeAttributes.Public; ns.Types.Add(targetClass); targetUnit.Namespaces.Add(ns); targetClass.Members.Add(GenerateComparator(type)); using (CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp")) { CodeGeneratorOptions options = new CodeGeneratorOptions(); options.BracingStyle = "C"; string outputFileName = Path.Combine(outputDirName, type.FullName + ".Comparator.cs"); using (StreamWriter sourceWriter = new StreamWriter(outputFileName)) { provider.GenerateCodeFromCompileUnit(targetUnit, sourceWriter, options); } } } } }
  • 20. System.CodeDom foreach (FieldInfo fi in type.GetFields(...)) { var checkExpr = new CodeBinaryOperatorExpression( new CodeFieldReferenceExpression(thisRef, fi.Name), CodeBinaryOperatorType.ValueEquality, new CodeFieldReferenceExpression(argRef, fi.Name)); var appendExpr = new CodeBinaryOperatorExpression( retRef, CodeBinaryOperatorType.BooleanAnd, checkExpr); CodeAssignStatement checkStatement = new CodeAssignStatement(retRef, appendExpr); compareMethod.Statements.Add(checkStatement); }
  • 21. Call It With Unity Menu public static partial class CodeGeneration { [MenuItem("Tools/Code Generation/Comparators", false, 1103)] public static void GenerateComparators() { Comparer.GenerateComparators(); } }
  • 22. WYG public partial class MonsterLevelInfo { public override bool Equals(object obj) { bool rv = true; MonsterLevelInfo other=obj as MonsterLevelInfo; if ((other == null)) return false; rv = (rv && (this.Xp == other.Xp)); ... rv = (rv && (this.Hp == other.Hp)); rv = (rv && (this.XpAmount == other.XpAmount)); return rv ; } }
  • 24. Generated Convert Method public static EResearch MonsterToResearchType(EObject v) { EResearchType rv = default(EResearchType); switch (v) { case EObject.Cobra: rv = EResearch.Cobra; break; case EObject.Crab: rv = EResearch.Crab; break; case EObject.Kobold: rv = EResearch.Kobold; break; case EObject.Orc: rv = EResearch.Orc; break; case EObject.Shaman: rv = EResearch.Shaman; break; case EObject.Spider: rv = EResearch.Spider; break; case EObject.Imp: rv = EResearch.Imp; break; } return rv; }
  • 26. System.CodeDom StringBuilder switchBuilder = new StringBuilder(); switchBuilder.AppendLine("switch (v) {"); foreach(var val in Enum.GetNames(sourceEnum)) { if (Enum.IsDefined(destEnum, val)) { switchBuilder.AppendFormat( "case {0}.{2}: retValue = {1}.{2}; ", sourceEnum, destEnum, val); switchBuilder.AppendLine("break;"); } } convertMethod.Statements.Add( new CodeSnippetStatement(switchBuilder));
  • 28. XML Serializer Generator Tool (Sgen.exe) The XML Serializer Generator creates an XML serialization assembly for types in a specified assembly in order to improve the startup performance of a XmlSerializer when it serializes or deserializes objects of the specified types.
  • 29. Sgen.exe rm -R *.cs sgen --assembly:Assembly-CSharp.dll --reference:UnityEngine.dll --verbose --force --keep --type:PaperPath.ObjectBaseLevelInfo --type:PaperPath.MonsterLevelInfo ... --type:PaperPath.CharacterLevelInfo result=$(find . -name *.cs) mv $result ../Assets/Classes/GeneratedSerializers.cs rm Assembly-CSharp.XmlSerializers.dll
  • 30. Do It with Unity [MenuItem("Tools/Code Generation/Serializers”)] public static void RegenerateSerializers() { System.IO.Directory.CreateDirectory(OutDir); CompileAssemblies(); PrepareSGen(); GenerateSerializers(); System.IO.Directory.Delete(OutDir, true); }
  • 31. Compile public static void CompileAssemblies() { HandleExecutable he = new HandleExecutable(); he.OutputHandler = Log; he.ErrorHandler = LogError; string Configuration = "Debug"; string Solution = "Client.sln"; he.CallExecutable("xbuild" , string.Format("/property:OutDir={0} /p:Configuration={1} {2}", OutDir, Configuration, Solution) , ””, true); }
  • 32. Prepare Script public static string GetScript() { StringBuilder sgenScript = new StringBuilder(); sgenScript.AppendLine("rm -R *.cs"); sgenScript.AppendFormat("sgen --assembly:{0} --reference:{1}” + ” --force –keep”, AssemblyPath, DependencyPaths); foreach (Type type in GetAssembly().GetTypes()) { object[] genAttributes = type.GetCustomAttributes( typeof(GenerateSerializersAttribute), false); if (genAttributes.Length > 0) sgenScript.AppendLine(" --type:" + type.FullName + " "); } sgenScript.AppendLine(); sgenScript.AppendLine("result=$(find . -name *.cs)"); sgenScript.AppendLine("mv $result ../" + GeneratedSerializersPath); sgenScript.AppendLine("rm Assembly-CSharp.XmlSerializers.dll"); return sgenScript; }
  • 33. Run Script and Postprocess public static void GenerateSerializers() { HandleExecutable he = new HandleExecutable(); he.CallExecutable("sh”, "generate.sh”, OutDir, true); string serializersCode = File.ReadAllText(GSPath); serializersCode = serializersCode.Replace( "(type.FullName)", "(type.FullName.Replace("+", "."))"); File.WriteAllText( GeneratedSerializersPath, serializersCode); }