Skip to main content
Commonmark migration
Source Link
  1. Either you implement some sort of simplified scripting system with your own syntax and fitting your needs, that would receive the necessary context, parsing the expression and executing it accordingly.

    Either you implement some sort of simplified scripting system with your own syntax and fitting your needs, that would receive the necessary context, parsing the expression and executing it accordingly.

    This system would need to be able to handle a set of basic data types (int, float, string, boolean, Vector2, Vector3), would need to be able to access properties on the parent component (which would be translated to Reflection calls), and know how to perform the basic arithmetic operations between data types. I don't think this would be an easy task.

  2. Or another alternative I can think about is maybe using C# runtime compilation (I talk a little about it here and show an example) and put C# code directly in the template.

    Then you would go through the template file at load time and prepare/compile one method for each initialization entry, taking the parent entity as a parameter. This way you can put C# code directly in the template, which would be executed later when instantiating the entities. The biggest advantage is not having to create your own scripting language though.

This system would need to be able to handle a set of basic data types (int, float, string, boolean, Vector2, Vector3), would need to be able to access properties on the parent component (which would be translated to Reflection calls), and know how to perform the basic arithmetic operations between data types. I don't think this would be an easy task.

  1. Or another alternative I can think about is maybe using C# runtime compilation (I talk a little about it here and show an example) and put C# code directly in the template.

Then you would go through the template file at load time and prepare/compile one method for each initialization entry, taking the parent entity as a parameter. This way you can put C# code directly in the template, which would be executed later when instantiating the entities. The biggest advantage is not having to create your own scripting language though.

  1. Either you implement some sort of simplified scripting system with your own syntax and fitting your needs, that would receive the necessary context, parsing the expression and executing it accordingly.

This system would need to be able to handle a set of basic data types (int, float, string, boolean, Vector2, Vector3), would need to be able to access properties on the parent component (which would be translated to Reflection calls), and know how to perform the basic arithmetic operations between data types. I don't think this would be an easy task.

  1. Or another alternative I can think about is maybe using C# runtime compilation (I talk a little about it here and show an example) and put C# code directly in the template.

Then you would go through the template file at load time and prepare/compile one method for each initialization entry, taking the parent entity as a parameter. This way you can put C# code directly in the template, which would be executed later when instantiating the entities. The biggest advantage is not having to create your own scripting language though.

  1. Either you implement some sort of simplified scripting system with your own syntax and fitting your needs, that would receive the necessary context, parsing the expression and executing it accordingly.

    This system would need to be able to handle a set of basic data types (int, float, string, boolean, Vector2, Vector3), would need to be able to access properties on the parent component (which would be translated to Reflection calls), and know how to perform the basic arithmetic operations between data types. I don't think this would be an easy task.

  2. Or another alternative I can think about is maybe using C# runtime compilation (I talk a little about it here and show an example) and put C# code directly in the template.

    Then you would go through the template file at load time and prepare/compile one method for each initialization entry, taking the parent entity as a parameter. This way you can put C# code directly in the template, which would be executed later when instantiating the entities. The biggest advantage is not having to create your own scripting language though.

added 31 characters in body
Source Link
David Gouveia
  • 25k
  • 5
  • 88
  • 127

Disclaimer: The ideas on this post are untested.

One solution that comes to my mind, is perhaps to use a Factory Method together with Reflection. Your external template file (XML or JSON) would provide a description of each type of entity, listing all of its components and their initial parameters. Then:

  1. The Factory Method takes care of instantiating the components knowing only their names. Similar to what you already seem to have but with a string key.

  2. Reflection would then be used to access the component's properties by name and set their initial values. IIRC, relevant methods are Object.GetType(), Type.GetProperty(name), PropertyInfo.SetValue(object, value, null).

If your initial property values were simple values without dependencies this would probably be enough. But your example seems to need a lot more complexity than this, because it depends on the parent's values, and is in the form of an expression, not a simple value.

That certainly makes things more complicated. I can foresee two roads for incorporating that behavior:

  1. Either you implement some sort of simplified scripting system with your own syntax and fitting your needs, that would receive the necessary context, parsing the expression and executing it accordingly.

This system would need to be able to handle a set of basic data types (int, float, string, boolean, Vector2, Vector3), would need to be able to access properties on the parent component (which would be translated to Reflection calls), and know how to perform the basic arithmetic operations between data types. I don't think this would be an easy task.

  1. Or another alternative I can think about is maybe using C# runtime compilation (I talk a little about it here and show an example) and put C# code directly in the template.

Then you would go through the template file at load time and prepare/compile one method for each initialization entry, taking the parent entity as a parameter. This way you can put C# code directly in the template, which would be executed later when instantiating the entities. The biggest advantage is not having to create your own scripting language though.

Something like this on your template (take all that follows as a sort of pseudocode, I have not considered all the possibilities):

<component name="Bullet">
    <property name="Position" value="parent.physicalComponent.Position + parent.physicalComponent.Direction * parent.physicalComponent.Radius;" />
</component>

Which would be wrapped and compiled at runtime inside a method such as (notice the use of the dynamic keywordnotice the use of the dynamic keyword to disable static checking):

public static object GetBulletPositionInitialValue(dynamic parent)
{
    return parent.physicalComponent.Position + parent.physicalComponent.Direction * parent.physicalComponent.Radius;
}

Notice that the method also follows a naming convention Get + ComponentName + PropertyName + InitialValue so that you can access it later by name using reflection.

I'm just shooting out a few ideas though, I'm not entirely sure whether this would actually work though. :-)

Disclaimer: The ideas on this post are untested.

One solution that comes to my mind, is perhaps to use a Factory Method together with Reflection. Your external template file (XML or JSON) would provide a description of each type of entity, listing all of its components and their initial parameters. Then:

  1. The Factory Method takes care of instantiating the components knowing only their names. Similar to what you already seem to have but with a string key.

  2. Reflection would then be used to access the component's properties by name and set their initial values. IIRC, relevant methods are Object.GetType(), Type.GetProperty(name), PropertyInfo.SetValue(object, value, null).

If your initial property values were simple values without dependencies this would probably be enough. But your example seems to need a lot more complexity than this, because it depends on the parent's values, and is in the form of an expression, not a simple value.

That certainly makes things more complicated. I can foresee two roads for incorporating that behavior:

  1. Either you implement some sort of simplified scripting system with your own syntax and fitting your needs, that would receive the necessary context, parsing the expression and executing it accordingly.

This system would need to be able to handle a set of basic data types (int, float, string, boolean, Vector2, Vector3), would need to be able to access properties on the parent component (which would be translated to Reflection calls), and know how to perform the basic arithmetic operations between data types. I don't think this would be an easy task.

  1. Or another alternative I can think about is maybe using C# runtime compilation (I talk a little about it here and show an example) and put C# code directly in the template.

Then you would go through the template file at load time and prepare/compile one method for each initialization entry, taking the parent entity as a parameter. This way you can put C# code directly in the template, which would be executed later when instantiating the entities. The biggest advantage is not having to create your own scripting language though.

Something like this on your template (take all that follows as a sort of pseudocode, I have not considered all the possibilities):

<component name="Bullet">
    <property name="Position" value="parent.physicalComponent.Position + parent.physicalComponent.Direction * parent.physicalComponent.Radius;" />
</component>

Which would be wrapped and compiled at runtime inside a method such as (notice the use of the dynamic keyword):

public static object GetBulletPositionInitialValue(dynamic parent)
{
    return parent.physicalComponent.Position + parent.physicalComponent.Direction * parent.physicalComponent.Radius;
}

Notice that the method also follows a naming convention Get + ComponentName + PropertyName + InitialValue so that you can access it later by name using reflection.

I'm just shooting out a few ideas though, I'm not entirely sure whether this would actually work though. :-)

Disclaimer: The ideas on this post are untested.

One solution that comes to my mind, is perhaps to use a Factory Method together with Reflection. Your external template file (XML or JSON) would provide a description of each type of entity, listing all of its components and their initial parameters. Then:

  1. The Factory Method takes care of instantiating the components knowing only their names. Similar to what you already seem to have but with a string key.

  2. Reflection would then be used to access the component's properties by name and set their initial values. IIRC, relevant methods are Object.GetType(), Type.GetProperty(name), PropertyInfo.SetValue(object, value, null).

If your initial property values were simple values without dependencies this would probably be enough. But your example seems to need a lot more complexity than this, because it depends on the parent's values, and is in the form of an expression, not a simple value.

That certainly makes things more complicated. I can foresee two roads for incorporating that behavior:

  1. Either you implement some sort of simplified scripting system with your own syntax and fitting your needs, that would receive the necessary context, parsing the expression and executing it accordingly.

This system would need to be able to handle a set of basic data types (int, float, string, boolean, Vector2, Vector3), would need to be able to access properties on the parent component (which would be translated to Reflection calls), and know how to perform the basic arithmetic operations between data types. I don't think this would be an easy task.

  1. Or another alternative I can think about is maybe using C# runtime compilation (I talk a little about it here and show an example) and put C# code directly in the template.

Then you would go through the template file at load time and prepare/compile one method for each initialization entry, taking the parent entity as a parameter. This way you can put C# code directly in the template, which would be executed later when instantiating the entities. The biggest advantage is not having to create your own scripting language though.

Something like this on your template (take all that follows as a sort of pseudocode, I have not considered all the possibilities):

<component name="Bullet">
    <property name="Position" value="parent.physicalComponent.Position + parent.physicalComponent.Direction * parent.physicalComponent.Radius;" />
</component>

Which would be wrapped and compiled at runtime inside a method such as (notice the use of the dynamic keyword to disable static checking):

public static object GetBulletPositionInitialValue(dynamic parent)
{
    return parent.physicalComponent.Position + parent.physicalComponent.Direction * parent.physicalComponent.Radius;
}

Notice that the method also follows a naming convention Get + ComponentName + PropertyName + InitialValue so that you can access it later by name using reflection.

I'm just shooting out a few ideas though, I'm not entirely sure whether this would actually work though. :-)

added 54 characters in body
Source Link
David Gouveia
  • 25k
  • 5
  • 88
  • 127
  1. Either you implement some sort of simplified scripting system with your own syntax and fitting your needs, that would receive the necessary context and parse the expression and executing it accordingly.

  2. Or another alternative I can think about is maybe using C# runtime compilation (I talk a little about it here and show an example) and put C# code directly in the template.

    Either you implement some sort of simplified scripting system with your own syntax and fitting your needs, that would receive the necessary context, parsing the expression and executing it accordingly.

This system would need to be able to handle a set of basic data types (int, float, string, boolean, Vector2, Vector3), would need to be able to access properties on the parent component (which would be translated to Reflection calls), and know how to perform the basic arithmetic operations between data types. I don't think this would be an easy task.

  1. Or another alternative I can think about is maybe using C# runtime compilation (I talk a little about it here and show an example) and put C# code directly in the template.

Then you would go through the template file at load time and prepare/compile one method for each initialization entry, taking the parent entity as a parameter. This way you can put C# code directly in the template, which would be executed later when instantiating the entities. The biggest advantage is not having to create your own scripting language though.

Which would be wrapped and compiled at runtime inside a method such as (notice the use of the dynamic keyword):

public static object GetBulletPositionInitialValue(dynamic parent)
{
    return parent.physicalComponent.Position + parent.physicalComponent.Direction * parent.physicalComponent.Radius;
}

Notice that the method also follows a naming convention Get + ComponentComponentName + PropertyPropertyName + InitialValue so that you can access it later by name using reflection.

  1. Either you implement some sort of simplified scripting system with your own syntax and fitting your needs, that would receive the necessary context and parse the expression and executing it accordingly.

  2. Or another alternative I can think about is maybe using C# runtime compilation (I talk a little about it here and show an example) and put C# code directly in the template.

Then you would go through the template file at load time and prepare/compile one method for each initialization entry, taking the parent entity as a parameter. This way you can put C# code directly in the template, which would be executed later when instantiating the entities. The biggest advantage is not having to create your own scripting language though.

Which would be wrapped inside a method such as (notice the use of the dynamic keyword):

object GetBulletPositionInitialValue(dynamic parent)
{
    return parent.physicalComponent.Position + parent.physicalComponent.Direction * parent.physicalComponent.Radius;
}

Notice that the method also follows a naming convention Get + Component + Property + InitialValue so that you can access it later by name using reflection.

  1. Either you implement some sort of simplified scripting system with your own syntax and fitting your needs, that would receive the necessary context, parsing the expression and executing it accordingly.

This system would need to be able to handle a set of basic data types (int, float, string, boolean, Vector2, Vector3), would need to be able to access properties on the parent component (which would be translated to Reflection calls), and know how to perform the basic arithmetic operations between data types. I don't think this would be an easy task.

  1. Or another alternative I can think about is maybe using C# runtime compilation (I talk a little about it here and show an example) and put C# code directly in the template.

Then you would go through the template file at load time and prepare/compile one method for each initialization entry, taking the parent entity as a parameter. This way you can put C# code directly in the template, which would be executed later when instantiating the entities. The biggest advantage is not having to create your own scripting language though.

Which would be wrapped and compiled at runtime inside a method such as (notice the use of the dynamic keyword):

public static object GetBulletPositionInitialValue(dynamic parent)
{
    return parent.physicalComponent.Position + parent.physicalComponent.Direction * parent.physicalComponent.Radius;
}

Notice that the method also follows a naming convention Get + ComponentName + PropertyName + InitialValue so that you can access it later by name using reflection.

added 54 characters in body
Source Link
David Gouveia
  • 25k
  • 5
  • 88
  • 127
Loading
added 829 characters in body
Source Link
David Gouveia
  • 25k
  • 5
  • 88
  • 127
Loading
added 829 characters in body
Source Link
David Gouveia
  • 25k
  • 5
  • 88
  • 127
Loading
Source Link
David Gouveia
  • 25k
  • 5
  • 88
  • 127
Loading