Understanding Google V8's Architecture - c#

I'm not sure I understand V8's architecture (yes, I've read its documentation).
In C# with the v8sharp wrapper I write something like this, for example:
namespace App
{
class Point
{
public Point() { }
public Point(double x, double y) {
this.X = x;
this.Y = y;
}
public double X { get; set; }
public double Y { get; set; }
}
}
static class Program
{
static void Main() {
//registering with v8sharp
V8Engine engine = V8Engine.Create();
engine.Register<App.Point>();
//execute javascript
object rtn = engine.Execute("new App.Point(10, 10);");
}
}
How would I write the same thing in Standard C++ without this wrapper?
Thanks.

If you look here: http://code.google.com/apis/v8/embed.html they have a sample that is identical to yours under "Accessing Dynamic Variables"

Related

Why is this nested struct creation slower than un-nested?

I've been benchmarking some C# struct creation, and I've been surprised to find that creation of a nested struct is significantly slower than the un-nested version. I would have expected the JITter to basically produce the same assembly for a flat and nested structure, but this appears to not be the case.
Does anyone have an explanation for why the struct construction in my test code below doesn't get optimized down to just writing the 3 doubles? It seems to (if I'm reading the assembly correctly) zero and create a temporary memory location before writing the values to the final location - presumably actually creating a temporary copy of the nested struct.
And in the follow-up, is there a way to avoid this extra work such that the nested struct has similar creation speed to the un-nested one?
public class StructBenchmarks
{
public struct Vector3_dp
{
public Vector3_dp(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
}
public double X;
public double Y;
public double Z;
}
public readonly struct ContainsVector
{
public ContainsVector(double x, double y, double z)
{
m_vector = new Vector3_dp(x, y, z);
}
public ContainsVector(Vector3_dp input)
{
m_vector = input;
}
private readonly Vector3_dp m_vector;
}
private ContainsVector m_vector1;
private ContainsVector m_vector2;
private Vector3_dp m_vector3_dp1;
private Vector3_dp m_vector3_dp2;
// 0.2ns
public void Vector3_dp_Construction()
{
m_vector3_dp1 = new Vector3_dp(20, 30, 40);
}
// 3.8ns
public void Vector_Construction()
{
m_vector1 = new ContainsVector(20, 30, 40);
}
// 3.8ns
public void Vector_ConstructionFromVector3_dp()
{
m_vector1 = new ContainsVector(m_vector3_dp1);
}
// ~0ns
public void Vector3_dp_Copy()
{
m_vector3_dp1 = m_vector3_dp2;
}
// ~0ns
public void Vector_Copy()
{
m_vector1 = m_vector2;
}
}
And SharpLab link: https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8BYAKAAJLyABAZhoCZyBlDKAVzAwCEYA7MAAt82KAGtcZKuQDeU6VTrlcbThnIA1GF2i0A+gBMADvIWzTZxfS06o+4wAoDEdsAA2McgjTlnrj+QAnj5+7p4AXgCUFpbmFLGWABrkALxeANwxCZQAmqlBmfHZ0gBa+eGFxeQAvmRZZkqhAYmVxY0uYeQ5rdnt/p4lPQq1pPU09LDYznxugcqqXOQAwhB8GNgAlny4NhjQY3JFCUora5vbu9BOHQHevjeewff95FFj0odV0vh6AG7aeyg+T4MAA7poAbpDEYHHcnlEhrERu8rMtVustjtIVAHJc7NDyFsjOwMNEjrFPl9KD9/rZ8kSSYjLMjyZYjFANr9sBhPJNprMIbZ7EZyDTsUzKCzYuzOdzPKcMRdsaK/tiAIwS8gyrk8tFnTF4lW0wEMQpjbVywWA4VG7HCjXmjk6zx4m1ioXQ011VmUAD0vvIAAYAHQMbZjJTUFBWqHGPSnFQcLgbVYOMkUlHU1Ue4xq4FgmP4xwMQM+Wil8goQORTVSyz+8i0YMADnDPvGNGjePjq0TahTfDTB0zttsebSIPBCvOWNsDhLZYrVZrYzrZgbTdbknbka72J72wWGAHADEoBB8K7oUP25Tsu7AePyJO9YrZ4CHA/Y0Y1Sv22uFF3QthR7IxAhvDN22+bNrWhJ8vyLIwvX/MYI3oKNC1A8D00sO8EgQ+CYOgZCkQsEYgA=

Accessing attributes within a class and outside of a class

Main method with some tree objects:
namespace Forest
{
class Program
{
static void Main(string[] args)
{
Tree Fir = new Tree();
Fir.species = "Fir";
Fir.height = 100.0;
Fir.trunkDiameter = 10.0;
Tree Oak = new Tree();
Oak.species = "Oak";
Oak.height = 120.0;
Fir.trunkDiameter = 12.5;
}
}
}
A tree class:
namespace Forest
{
class Tree
{
public string species;
public double height;
public double trunkDiameter;
}
}
I want to add an attribute as such: public double trunkCircumference = trunkDiameter * 3.14
But when I do that, the trunkDiameter variable isn't recognized. When adding a static modifier, it fixes, but I cannot access trunkDiameter.
I would just like to add a trunkCircumference attribute.
Since trunkCircumference appears to always return trunkDiameter * 3.14, you could define it as a property, instead of a field.
namespace Forest
{
class Tree
{
public string species;
public double height;
public double trunkDiameter;
public double trunkCircumference
{
get => return trunkDiameter * 3.14;
}
}
}

C# Access Struct using String

I am a bit stuck with my game. I have a class called Upgradebuttons. From this class I want to access some variables stored in a struct from another class. I can easily access the variables by typing classname.structname.preferedvar but the structname depends on which upgrade as been clicked. So I want to call the struct using a string. I have tried:
MethodInfo method = typeof(Classname).GetMethod(structname);
But this only works if it is a void and not a struct. What do I need to do in order to get this working?
public class UpgradeButtons : MonoBehaviour {
public void somefunction{
// here i want to have access
}
}
This is an example of the class I want to have access to:
public class Upgrades: MonoBehaviour {
public struct Upgrade1{
public const int Cost = 10;
public const float Value = 0.1f;
public static string Naam = "Autoclicker";
}
}
While this is possible, it sounds like poorly thought out design. Perhaps you could use one common struct Upgrade and use the Name property to find it at runtime?
Example:
public struct Upgrade
{
public string Name;
public int Cost;
public float Value;
public Upgrade(string name, int cost, float value)
{
this.Name = name;
this.Cost = cost;
this.Value = value;
}
}
public class UpgradeButtons : MonoBehavior
{
List<Upgrade> Upgrades = new List<Upgrade>();
public void CreateButtons()
{
Upgrades.Add(new Upgrade("Autoclicker", 10, 0.1f));
//etc...
}
public void somefunction()
{
Upgrade autoclickUpgrade = Upgrades.Where(p => p.Name == "Autoclicker").FirstOrDefault();
if(autoclickUpgrade == null)
throw new Exception("Could not find Autoclicker upgrade.");
//do something with autoclickUpgrade
}
}
just remove static from string Naam:
public class Upgrades: MonoBehaviour {
public struct Upgrade1{
public const int Cost = 10;
public const float Value = 0.1f;
public string Naam = "Autoclicker";
}
}
When an object ( class, variable, method) is defined as static it can not be referenced through an instance.
If I understand your question, you are on the right track, probably. Since the struct (type) that your add-on depends on may or may not exist, Reflection is the best way to go here.
Try Assembly.GetType(), or a related method, to attempt to load the type, check its existence, and iterate its members.
http://msdn.microsoft.com/en-us/library/y0cd10tb(v=vs.110).aspx

How to avoid assignments of multiple arguments passed to constructor

If i have a class in c# containing many variables that needs to be initialised in a constructor e.g.
public class AnyClass
{
private int Var1;
private int Var2;
...
private int varN;
public AnyClass(int InVar1,int InVar2,...,InVarN)
{
Var1=InVar1;
Var2=InVar2;
...
VarN=InVarN;
//
//Code
//
}
}
Is there a way to avoid the intermediate variables InVar1, InVar2 etc in such a way that the arguments passed to the constructor are automatically mapped to the variables contained in the class.
Not at present, C# 6 may include it.
This is what is may look like
Before
public class Point {
private int x, y;
public Point(int x, int y)
this.x = x;
this.y = y;
}
}
After
public class Point(private int x, private int y) {
}
If you don’t mind having properties with a public setter, you can use Object initializers. E.g.
Cat cat = new Cat { Age = 10, Name = "Fluffy" };

Creating a generic list of objects in C#

By way of an intro, I'm creating a basic Quadtree engine for personal learning purposes. I'm wanting this engine to have the capability of working with many different types of shapes (at the moment I'm going with circles and squares) that will all move around in a window and perform some sort of action when collision occurs.
Here are my shape objects as I have them so far:
public class QShape {
public int x { get; set; }
public int y { get; set; }
public string colour { get; set; }
}
public class QCircle : QShape {
public int radius;
public QCircle(int theRadius, int theX, int theY, string theColour) {
this.radius = theRadius;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
public class QSquare : QShape {
public int sideLength;
public QSquare(int theSideLength, int theX, int theY, string theColour) {
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
Now my question is, how do I create a generic list (List<T> QObjectList = new List<T>();) in C# so I can have one list containing all these various shapes that may have different properties (e.g., QCircle has the "radius" property while QSquare has the "sideLength" property)? An example of implementation would be helpful as well.
I just know that there is a stupidly obvious answer to this question but I'd appreciate any help anyway. I'm trying to get back into C#; it has obviously been a while...
You need to use downcasting
Store the objects in a list with the base class
List<QShape> shapes = new List<QShape>
You can then upcast the object safely if you know what it is e.g.
if(shapes[0] is QSquare)
{
QSquare square = (QSquare)shapes[0]
}
You can also implicitly downcast objects
QSquare square = new Square(5,0,0,"Blue");
QShape shape = square
For more information read the Upcasting and Downcasting sections here
You should implement an Interface. For example
public interface IHasLength
{
int Length;
}
Then in the implementation you can do
public class QSquare : QShape, IHasLength {
public int sideLength;
public QSquare(int theSideLength, int theX, int theY, string theColour) {
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
public int Length { get { return sideLength; } }
}
public class QCircle : QShape, IHasLength {
public int radius;
public QSquare(int theSideLength, int theX, int theY, string theColour) {
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
public int Length { get { return radius; } }
}
FInally, in your list:
List<IHasLength> shapesWithSomeLength = new List<IHasLength>();
Now your list can hold ANYTHING that implements IHasLength whether it's a QCircle, QShape, or even a QDuck if you want as long as it implements IHasLength.
Is this what you want?
public class QShape
{
protected QShape() { }
public int x { get; set; }
public int y { get; set; }
public string colour { get; set; }
}
public class QCircle : QShape
{
public int radius;
public QCircle(int theRadius, int theX, int theY, string theColour)
{
this.radius = theRadius;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
public class QSquare : QShape
{
public int sideLength;
public QSquare(int theSideLength, int theX, int theY, string theColour)
{
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
class Program
{
static void Main(string[] args)
{
List<QShape> list = new List<QShape>();
list.Add(new QCircle(100, 50, 50, "Red"));
list.Add(new QCircle(100, 400, 400, "Red"));
list.Add(new QSquare(50, 300, 100, "Blue"));
foreach (var item in list.OfType<QCircle>())
{
item.radius += 10;
}
foreach (var item in list.OfType<QSquare>())
{
item.sideLength += 10;
}
}
}
You could store them in a List<QShape> but this would mean that you could not access type-specific properties.
Generally, you might approach this by providing a common interface in your base class, and overriding behaviour in subclasses. In this way, a common interface can hide a diverse bunch of behaviours. For instance a Grow method could hide the complexities of growing items of different shape and could be called without explicit knowlege of the shape upon which it is operating.
public abstract class QShape {
public abstract void Grow(int amt);
}
public class QSquare : QShape {
private int sideLength;
public override void Grow(int amt)
{
sideLength+=amt;
}
}
public class QCircle : QShape {
private int radius;
public override void Grow(int amt)
{
radius+=amt;
}
}
I feel like i'm missing something but...
List<QCircle> circleObjects = new List<QCircle>();
and
List<QSquare> squareObjects = new List<QSquare>();
will work perfectly well.
EDIT:
Ah, I didn't understand what was being asked.
Yes, as your QCircle and QSquare classes inherit from QShape, you can just do.
List<QShape> shapes= new List<QShape>();
It's worth noting that if you want to access the radius property of all the QCircle's in that list, then you are going to have to filter the list based on type.
You can use Ian Mercer's comment List<QShape>
And here's how you would fill it:
List<QShape> shapes = new List<QShape>();
QCircle circle = new QCircle();
shapes.Add(circle);
To unbox it:
QCircle circle = (QCircle) shapes[0];
If you need to call a method off the base class, no need to unbox, just use it.
Storing
You're already on the right track with your class definitions. What you have to do is make a List of the superclass (in this case, QShape), which will be able to hold all of your shapes.
Here's an example of how you would make it:
List<QShape> objects = new List<QShape>();
objects.add(new QCircle(...));
objects.add(new QSquare(...));
Accessing
The problem here is differentiating what is what once everything is in the list. That's done with the getType() and typeof() methods of C#. (Jon Skeet has an excellent answer about how to do this). Basically, it looks like this:
if(objects.get(some_position).getType() == typeof(QCircle))
QCircle circle = objects.get(some_position);
else if(/* like above with QSquare */)
QSquare square = objects.get(some_position);
After you do this, you can resume using your objects like normal. But if you try accessing them from the list, you can only use the methods and variables that QShape has, as every object put in the list will be cast to it.
public Class abstract Base<T>
{
public abstract List<T>GetList();
}
then do this
public class className:Base<ObjectName>
{
public override List<T>GetList()
{
//do work here
}
}

Categories

Resources