Let's say I have a class like so:
class Gerbil{
int id;
float x,y,z;
}
Let's further say this is part of a real-time simulation where I have a server/client setup and I change a property on the server-side:
//...
gerbil.x = 9.0;
//...
Now I want to send over this change to the client to synchronize the world state. However, the problem is I have potentially vast amounts of gerbils, and these gerbils also potentially have long lists of properties—not just x,y,z as depicted here.
My question is: Is there a way we can intercept these property assignments, transparently, and compile a diff from them?
From reading the D reference I got the impression opAssign might be the right thing, only there's actually no examples of how to use it? (D Ref. / opAssign) I suppose it would look something like this, but I'm just shooting from the hip:
void opAssign(string name)(float val){ //Just guessing here
if(name in floatProps){
if(isServer){
changedProps.push(this.id, name, val);
}
floatProps[name] = val;
}
}
And then opAssign would be called when we do:
gerbil.x = 9.0; //Same as gerbil.opAssign!("x")(9.0) ??
Apart from possibly wrong syntax, is this a step in the right direction? What is the right syntax? What about performance? It looks like it could be quite slow? Is there a faster, more "direct" way of this?
What I'd really like to avoid here are elaborate setups like:
gerbil.incProp(Prop.X, 9.0);
Thanks for your time.
Building on Jonathan's answer, I use code like this in a number of my libraries:
public template property(string name, T) {
mixin(`protected T _`~name~`;` ~
propertyGetter!(name, T) ~ propertySetter!(name, T));
}
public template property(string name, T, T def)
{
mixin(`protected T _`~name~` = `~def.stringof~`;` ~
propertyGetter!(name, T) ~ propertySetter!(name, T));
}
template propertyGetter(string name, T) {
enum propertyGetter = `public T `~name~`(){ return _`~name~`; }`;
}
template propertySetter(string name, T) {
enum propertySetter = `public typeof(this) `~name~`(T value){ _`~name~` = value;`~
`/* notify somebody that I've changed here */`~
`return this; }`;
}
The mixin strings are a bit ugly, but they preserve the proper line count.
I add properties to my classes like this:
class Gerbil {
mixin property!("id", int);
mixin property!("x", float);
mixin property!("y", float, 11.0); // give this one a default value
}
If you wanted, you could add some code to the propertySetter template that notified some sort of monitor that it had changed (passing id, property name, and new value). Then the monitor could transmit this info to a corresponding monitor on the server side who would find the object with proper id and set the specified property to the new value.
Overloading opAssign() is like overloading the assignment operator in C++. It's for assigning to the object itself, not one of its members. It's really not going to do what you want. I believe that the closest that you're going to get is properties:
class Gerbil
{
public:
#property int id()
{
return _id;
}
#property id(int newID)
{
//... Do whatever interception you want.
_id = newID;
}
#property float x()
{
return _x;
}
#property x(float newX)
{
//... Do whatever interception you want.
_x = newX;
}
#property float y()
{
return _y;
}
#property y(float newY)
{
//... Do whatever interception you want.
_y = newY;
}
#property float z()
{
return _z;
}
#property z(float newZ)
{
//... Do whatever interception zou want.
_z = newZ;
}
private:
int _id;
float _x, _y, _z;
}
#property enables property syntax so that you can use the function as if it were a variable. So,
//...
auto copyOfGerbilX = gerbil.x; //translates to gerbil.x()
gerbil.x = 9.0; //translates to gerbile.x(9.0)
//...
is now legal even though x is a function rather than a variable. You can insert whatever special handling code you want in the functions. And because the syntax used to access the variables is just as if they were public member variables, you can freely refactor your code to switch between having them be properties or public member variables in your class definition (assuming that you haven't tried to do something like take their address, since that doesn't mean the same thing for a variable as a function).
However, if what you're looking for is a generic way to not have to do all of those functions yourself, there is no direct construct for it. I believe that you could do it with compile-time reflection and string mixins or template mixins which would look at the list of your variables and then generate each of the property functions for you. However, then the extra handling code would have to be essentially the same for each function, and you'd have to be careful that the generated code was really what you wanted. I'm sure that it's feasible, but I'd have to work on the problem for a bit to produce a workable solution.
To generate such code, you'd need to look at __traits and std.traits for the compile-time reflection and at template mixins and string mixins for the code generation. I'd think twice about generating the code like that though rather than writing it by hand. It should be quite doable, but it won't necessarily be easy, debugging it could be entertaining, and if you're going to have to be fairly good with D templates and mixins to get it right.
But essentially, what you're looking for is to use #property functions so that you can add your handler code and then possibly use compile-time reflection along with mixins to generate the code for you, but generating code like that is a fairly advanced technique, so you may want to wait to try that until you're more experienced with D.
Related
Imagine a part of your state machine looks like this:
How do you properly implement the choice part in Qt? I know there are guarded transitions, but that would mean that I need to:
Create a subclass of a QAbstractTransition which accepts e.g. an std::function<bool()> and a flag which determines if the transition happens when that boolean result is true, or when it is false
Create two instances of this class with the same boolean function, but opposite transition guards
Add two transitions from S1 using these two instances.
That approach seems kind of clumsy and error prone for something as simple as a choice.
Is there a more maintainable approach to implement this?
License Notice:
Alternatively to the default StackOverflow license you are hereby allowed to use this code through the MIT License.
I've created a BooleanChoiceTransition class with a constructor like this (might contain errors, the code is not on this machine, so I typed it by heart):
BooleanChoiceTransition::BooleanChoiceTransition(std::function<bool()> choiceFunc, QState* targetForTrueCase, QState* targetForFalseCase)
: QState{}
{
this->addTransition(this, &BooleanChoiceTransition::transitionToTrueTarget, targetForTrueCase);
this->addTransition(this, &BooleanChoiceTransition::transitionToFalseTarget, targetForFalseCase);
(void)QObject::connect(this, &QAbstractState::entered, [this]() {
if(choiceFunc())
{
emit transitionToTrueTarget();
}
else
{
emit transitionToFalseTarget();
}
});
}
with transitionToTrueTarget and transitionToFalseTarget being signals of course.
For the case of the example in the question, the class can be used like so:
auto choiceState = new BooleanChoiceTransition([this](){ return _someConditionFullfilled; }, s2, s3);
s1->addTransition(this, &MyClass::someTrigger, choiceState);
Since BooleanChoiceTransition is a QState, this can even be nested easily:
auto outerChoiceState = new BooleanChoiceTransition([this](){ return _someOtherConditionFullfilled; }, s4, choiceState);
I have the following scenario (https://run.dlang.io/is/19OOW9):
import std.stdio;
void main(string[] args)
{
inter1 c1 = new foo();
foo c2 = new foo();
writeln("Origin=interface: ", typeof(c1).stringof);
writeln("Origin=class: ", typeof(c2).stringof);
}
interface inter1 {
}
class foo : inter1 {
}
I work with interfaces and have different implementations for them. Now I need to know which concrete implementation is currently being used. So in the example above, I would like to know from c1 that it is an instance of the class foo.
Is this possible in the language D?
I have already tried the possibilities of object (e.g. TypeInfo_Class) and std.traits. Unfortunately without success.
A workaround is, of course, to provide the interface with a suitable meta method (https://run.dlang.io/is/Xnt0TO):
import std.stdio;
void main(string[] args)
{
inter1 c1 = new foo();
foo c2 = new foo();
writeln("Origin=interface: ", c1.strategyName);
writeln("Origin=class: ", c2.strategyName);
}
interface inter1 {
#property string strategyName() const;
}
class foo : inter1 {
#property string strategyName() const {
return "foo";
}
}
However, this is cumbersome and unusual for D. I can well imagine that there is a better implementation of this.
Best regards
Thorsten
It is quite simple actually: first cast to Object, then fetch the typeid, after a null check:
Object o = cast(Object) your_object;
if(o is null) { /* i don't think this ever happens but you should check anyway */ }
writeln(typeid(o)); // will tell the class name
If you want to call a method on a specific class, you can just cast directly to your class, and again, null check it.
The intermediate cast to Object allows the typeid (aka classinfo) to succeed, whereas calling it directly on an interface always returns the typeid of the interface itself. This is because a D interface is defined to be very thin for maximum compatibility with other languages and doesn't automatically assume run time type information is actually present through it. But the cast to Object tells it you are assuming the RTTI is present, and then typeid will pull it.
Note that the typeid data doesn't provide a whole lot of information... it is mostly just what's needed for dynamic cast, comparison, and other features of the language runtime. But one convenience method it has is a class name and toString methods, which is why the writeln succeeds. But if you're looking for more detailed runtime reflection, you'll have to do it with a CT bridge function, or probably better yet, just write your own methods in the interface.
But if all you need is the class name, use that toString. It gives the fully-qualified name, including module name, so instead of foo, you will get like yourmodule.foo. You can just cut that off if you like by slicing at the dot.
My struct class:
public struct PinAndRadius
{
public string pinID { get; set; }
public string radiusID { get; set; }
public string getPinID()
{
return pinID;
}
public string getRadiusID()
{
return radiusID;
}
}
the method with a problem:
void mapArea_VE_PinDragged(double latitude, double longitude, object id)
{
foreach (var pin in pinRadiusCollection)
{
string ID = id.ToString();
//string newID = ID.Substring(0, 18);
if (!pin.Key.pinID.Equals(ID))
{
continue;
}
else if (pin.Key.pinID.Equals(ID))
{
var newLoc = createNewSearchLocation(latitude, longitude);
mapArea.VE_DeleteRadius(pin.Key.radiusID);
drawPoly(newLoc, pin.Value.xar_Radius);
pin.Key.radiusID = pollyID;
break;
}
}
}
The problem is that when I try to set pin.key.radiusID to pollyID, I get an error saying
Cannot modify the return value of 'System.Collections.Generic.KeyValuePair.Key' because it is not a variable...
Any ideas?
Structure in .net is value-type. This mean you can't get reference to PinAndRadius using pin.Key. You will get copy of pin.Key of type PinAndRadius. Then you haven't access to this copy and compiler tell you about this. In C++ terms it not l-value.
If you create struct always try make it immutable. Mutable structs are evil.
Simplest way to solve this problem is to make PinAndRadius as class.
By the looks of it, your pinRadiusCollection is a generic dictionary keyed by PinAndRadius; the error you're getting is letting you know you can't modify that object because it's being used as the key in your dictionary.
If your pins are supposed to be mutable, you should probably revisit how you're storing them.
Collections in .net are not set up to allow convenient modification of struct-type items contained therein. Despite this, mutable structs still offer cleaner semantics than any other kind of data type. To edit a struct held in a collection, simply copy it to a variable, edit that variable, and store it back:
var temp = myList[someIndex];
temp.SomeVield = whatEver;
myList[someIndex] = temp;
Note that it's generally better to have mutable structs expose their contents as fields than as properties. Some people may say mutable structs are evil because their semantics differ from classes, but that's like saying screwdrivers are evil because they make lousy hammers. Exposed-field structs don't work like class types, but structs where all fields are exposed all have the same semantics as each other. Those semantics differ from classes, but for cases where they're useful, they have no equal.
Incidentally, much of the bad reps "mutable structs" got was a result of the fact that mutating struct members other than exposed fields would often generate bogus code if applied to read-only structures. If you avoid having struct members which modify fields of this [it's perfectly safe for static struct methods to modify fields of structures received as ref parameters], those dangers don't apply.
I simply just changed the struct definition to a class.
I refer to this site link text
Using the wrong event name in the
[Bindable] tag can cause your
application to not bind your property,
and you will not even know why. When
you use the [Bindable] tag with a
custom name, the example below looks
like a good idea:
public static const EVENT_CHANGED_CONST:String = "eventChangedConst";
private var _number:Number = 0;
[Bindable(event=EVENT_CHANGED_CONST)]
public function get number():Number
{
return _number;
}
public function set number(value:Number) : void
{
_number = value;
dispatchEvent(new Event(EVENT_CHANGED_CONST));
}
The code above assigns a static
property to the event name, and then
uses the same assignment to dispatch
the event. However, when the value
changes, the binding does not appear
to work. The reason is that the event
name will be EVENT_CHANGED_CONST and
not the value of the variable.
The code should have been written as
follows:
public static const EVENT_CHANGED_CONST:String = "eventChangedConst";
private var _number:Number = 0;
[Bindable(event="eventChangedConst")]
public function get number():Number
{
return _number;
}
public function set number(value:Number) : void
{
_number = value;
dispatchEvent(new Event(EVENT_CHANGED_CONST));
}
I agree, the wrong example does look like a good idea and I would do it that way because I think it's the right way and avoids the possibility of a typing error. Why is the name of the constant used instead of it's value? Surely this can't be right?
I appreciate your insights
Because the standard Flex compiler isn't that clever at times... and I feel your pain! I've complained about this exact problem more than a few times.
If I remember correctly, it's because the compiler does multiple passes. One of the early passes changes the Metadata into AS code. At this point in the compiler it hasn't parsed the rest of the AS code, so its not capable of parsing Constants or references to static variables in other files.
The only thing I can suggest is sign up to the Adobe JIRA, vote for the bug, and hope that the compiler fixes in 4.5 bring some relief.
I'm using Python+PyAMF to talk back and forth with Flex clients, but I've run into a problem with the psudo-Enum-Singletons I'm using:
class Type {
public static const EMPTY:Type = new Type("empty");
public static const FULL:Type = new Type("full");
...
}
When I'm using locally created instances, everything is peachy:
if (someInstance.type == Type.EMPTY) { /* do things */ }
But, if 'someInstance' has come from the Python code, it's instance of 'type' obviously won't be either Type.EMPTY or Type.FULL.
So, what's the best way to make my code work?
Is there some way I can control AMF's deserialization, so when it loads a remote Type, the correct transformation will be called? Or should I just bite the bullet and compare Types using something other than ==? Or could I somehow trick the == type cohesion into doing what I want?
Edit: Alternately, does Flex's remoting suite provide any hooks which run after an instance has been deserialized, so I could perform a conversion then?
Random thought: Maybe you could create a member function on Type that will return the canonical version that matches it?
Something like:
class Type {
public static const EMPTY:Type = new Type("empty");
public static const FULL:Type = new Type("full");
...
// I'm assuming this is where that string passed
// in to the constructor goes, and that it's unique.
private var _typeName:String;
public function get canonical():Type {
switch(this._typeName) {
case "empty": return EMPTY;
case "full": return FULL;
/*...*/
}
}
}
As long as you know which values come from python you would just convert them initially:
var fromPython:Type = /*...*/
var t:Type = fromPython.canonical;
then use t after that.
If you can't tell when things come from python and when they're from AS3 then it would get pretty messy, but if you have an isolation layer between the AS and python code you could just make sure you do the conversion there.
It's not as clean as if you could control the deserialization, but as long as you've got a good isolation layer it should work.