Accessing Q_ENUM in QML - enums

Quick note: I have checked other topics and could not identify the correct syntax.
class Pet : public QObject
{
Q_OBJECT
Q_ENUMS(PetStatus)
public:
enum PetStatus { Stun, Rooted };
...
}
qmlRegisterType<Pet>(); //In other class.
This class is used in a QList within PetTeam which is used in a QList within PetStage. The two higher classes do not have enums. The PetStage object alone is sent to the QML and from there everything else is accessed from within QML as it is aware of the hierarchy.
petStage.team[1].pet[2].name //Works in QML
The problem I'm having is I want to use the enum in QML and I am unaware of the correct syntax to use in QML so that
console.log(X.Rooted) //prints 1; I thought Pet.Rooted would work but it does not
functions correctly.

Solution is to to create another qmlRegisterType
qmlRegisterType<Pet>("PetStatus", 1, 0, "PetStatus");
from there you would import into the QMLscript
import PetStatus 1.0
and call it from QML using
PetStatus.Rooted //Or whatever naming convention you used for your elements

Related

How do I reference a Typescript enum inside a definition file

I am using Visual Studio 2013 with update 4 and Typescript 1.3 installed.
If I have a typescript file, like so:
MyEnums.ts:
export = MyEnumModule;
module MyEnumModule {
export enum AnEnum { RED, BLUE, GREEN }
}
And I have a definitions file like so:
MyDefinitions.d.ts:
declare module MyDefinitions {
interface ISomeInterface {
aProperty: string;
aMethod: () => void;
aColor: MyEnumModule.AnEnum;
}
}
I basically get an error of "Cannot find name 'MyEnumModule'"
This enum file works fine when referenced from typescript files. For instance:
SomeCode.ts:
export = MyCode;
import MyEnums = require('MyEnums');
module MyCode{
export class MyClass implements ISomeInterface {
public aColor: MyEnums.AnEnum = MyEnums.AnEnum.RED;
...and so on
My understanding is that adding either /// <reference ... or an import will not work for a .d.ts file (I tried just to be sure and it didn't appear to work either way).
Does anyone know how to reference an enum in a definition file like this?
Thanks in advance.
--Update:
Here is the error I see after trying Steve Fenton recommendations below (with a sample project I just made).
MyDefinitions.ts:
import MyEnumModule = require('../App/MyEnums');
declare module MyDefinitions {
interface ISomeInterface {
aProperty: string;
aMethod: () => void;
aColor: MyEnumModule.AnEnum;
}
}
MyEnums.ts:
export = MyEnumModule;
module MyEnumModule {
export enum AnEnum { RED, BLUE, GREEN }
}
MyClass.ts:
export = MyCode;
import MyImport = require('MyEnums');
module MyCode {
export class MyClass implements MyDefinitions.ISomeInterface {
public aColor: MyImport.AnEnum = MyImport.AnEnum.RED;
constructor() { }
aProperty: string = "";
aMethod: () => void = null;
}
}
Folder structure:
App
-MyClass.ts
-MyEnums.ts
Defintions
-MyDefintions.d.ts
Inside MyClass.ts MyDefinitions.ISomeInterface is underlined in red with hover warning "Cannot find name MyDefinitions".
I have AMD set for the project
Does anyone know how to reference an enum in a definition file like this?
There are workaround as Steve Fenton pointed out, but the system isn't designed for this. You should reference other definition files in your definition file and not reference an *implementation file * (MyEnum.ts) in a definition file.
I had a check on this and the following definition works for me, although I must admit I have never referenced "actual" code from "definition" code - but I can't think of any reason not to.
import MyEnumModule = require('MyEnumModule');
declare module MyDefinitions {
interface ISomeInterface {
aProperty: string;
aMethod: () => void;
aColor: MyEnumModule.AnEnum;
}
}
On mixing definitions and real implementations...
The type system in TypeScript is a design time and compile-time tool. When the type information is constructed at design time it makes no difference whether the type information is inferred from implementation code, taken from annotations that decorate implementations or come from an ambient declaration.
There are many use cases for mixing implementation code and ambient declarations - if you are migrating a million-line JavaScript program to TypeScript, you may not be able to migrate it from the bottom-most dependency upwards. Also, you can place ambient declarations inside of normal files - not just definition files - if you have a large program, you may not even know whether a type you place in an ambient declaration is "real" or "ambient".
The only difference between implementation code types and ambient declaration types is that the type information is right next to the implementation in real code files, and in a separate file for ambient declarations.
So... if you are having a problem using real implemented types in your ambient declaration, it is most likely caused by something that can be fixed. The example I supplied above works in a project I have in Visual Studio 2013, Update 4 - with TypeScript build configuration set to compile AMD modules. If you can share the exact details of the problem, I'm happy to help you get it working.
Having said this - if you are creating a type definition for trivial amounts of code, pasting them into a .ts file may even be faster than writing the definition - so you should make a case-by-case decision on where to spend the effort.

Is it possible to provide UI selectable options to custom msbuild tasks?

I have built a custom msbuild task that I use to convert 3D models in the format I use in my engine. However there are some optional behaviours that I would like to provide. For example allowing the user to choose whether to compute the tangent array or not, whether to reverse the winding order of the indices, etc.
In the actual UI where you select the Build action for each file, is it possible to define custom fields that would then be fed to the input parameters of the task? Such as a "Compute Tangents" dropbox where you can choose True or False?
If that is possible, how? Are there any alternatives besides defining multiple tasks? I.e. ConvertModelTask, ConvertModelComputeTangentTask, ConvertModelReverseIndicesTask, etc.
Everything in a MsBuild Custom Task, has to have "settable properties" to drive behavior.
Option 1.
Define an ENUM-esque to drive you behavior.
From memory, the MSBuild.ExtensionPack.tasks and MSBuild.ExtensionPack.Xml.XmlFile TaskAction="ReadElementText" does this type of thing.
The "TaskAction" is the enum-esque thing. I say "esque", because all you can do on the outside is set a string. and then in the code, convert the string to an internal enum.
See code here:
http://searchcode.com/codesearch/view/14325280
Option 2: You can still use OO on the tasks. Create a BaseTask (abstract) for shared logic), and then subclass it, and make the other class a subclass, and the msbuild task that you call.
SvnExport does this. SvnClient is the base class. And it has several subclasses.
See code here:
https://github.com/loresoft/msbuildtasks/blob/master/Source/MSBuild.Community.Tasks/Subversion/SvnExport.cs
You can probably dive deep with EnvDTE or UITypeEditor but since you already have a custom task why not keep it simple with a basic WinForm?
namespace ClassLibrary1
{
public class Class1 : Task
{
public bool ComputeTangents { set { _computeTangents = value; } }
private bool? _computeTangents;
public override bool Execute()
{
if (!_computeTangents.HasValue)
using (var form1 = new Form1())
{
form1.ShowDialog();
_computeTangents = form1.checkBox1.Checked;
}
Log.LogMessage("Compute Tangents: {0}", _computeTangents.Value);
return !Log.HasLoggedErrors;
}
}
}

Win32/C++ Class Inheritance problem

I am writing an GL effect system in my application so i have a superclass called
cEffect - which handles loading/parsing configuration file for each effect
and other inherited classess
cFX<name> - for every effect i add ( blur, bloom, chaos,... ).
The code is simplified here but looks like this:
Class cEffect
{
public:
bool ParseString(...);
private:
int m_nStartFrame;
int m_nEndFrame;
float m_fSpeed;
};
// Blur effect
Class cFXBlur : public cEffect
{
public:
bool RenderFrame(...);
};
// Bloom effect
Class cFXBloom : public cEffect
{
public:
bool RenderFrame(...);
};
// Scene drawing effect
Class cFXScene : public cEffect
{
public:
bool RenderFrame(...);
};
// Clear the depth/color buffer
Class cFXClearBuffers : public cEffect
{
public
bool RenderFrame(...);
}
Now, the demo engine handles a
std::vector<cEffect *> m_pvEffects;
Vector that has a list of effects added.
And when an effect is added to the current time (let's say i add a blur)
i add it like:
// Blur to be added
cEffect *newEffect = new cFXBlur;
newEffect->SetStartTime(x);
newEffect->SetEndTime(y);
newEffect->SetPower(13.0f);
newEffect->SetTexture(...);
// Now add the effect to the effects list.
m_pvEffects.push_back(newEffect);
Now, when i render i iterate through m_pvEffects list - but also i would like to call
an RenderFrame method ( which is public in every CFX<name> effect).
(*it)->RenderFrame(...)
But compiler says:
error C2039: 'RenderFrame' : is not a member of 'CEffect'
I kinda understand why it happens but can't really think of a way how can i fix this,
can you guys help me out please - it seems like i lost the plot ...
Thanks for any suggestion, what can i do to add CFX to a cEffect vector and later
use -> RenderFrame method?
You should change your class cEffect to:
Class cEffect
{
public:
bool ParseString(...);
virtual bool RenderFrame(...) = 0;
private:
int m_nStartFrame;
int m_nEndFrame;
float m_fSpeed;
};
You need the keyword virtual, if you want to redefine a method in a subclass. The = 0 makes the class cEffect abstract (i.e. you cannot create an object directly of the type cEffect), therefore subclasses must implement the method RenderFrame(...)
The error occurs, because cEffect has no member function called RenderFrame. What you want is a virtual function, a fundamental concept of object oriented programming. Basically you need to add a function
virtual bool RenderFrame(...);
to your cEffect definition. The virtual keyword basically tells the compiler to resolve it at runtime. This means if you call this method on a cEffect pointer or a reference, the corresponding method of the concrete derived class this pointer or reference point to is called. In this case you should also declare the method as virtual in all derived classes (although this is not neccessary, it makes your code clearer).
If you do not want the base class method to do anything and you want to require all derived classes to override it with their own implementation, then you can make this method pure virtual in the base class, by decralring it like
virtual bool RenderFrame(...) = 0;
This basically tells the compiler, that this is an abstract method, which doesn't have a concrete implementation and is only implemented by derived classes.
This is a very simplified explanation (appologies to every expert who thinks my wordings not 100% exact). You should read some more material on object oriented programming, especially in conjunction with C++.

typedef struct syntax for C++ Windows Forms?

i'm having trouble with syntax regarding c++ Windows Forms..
this is how you obviously do it in a regular cpp project: http://www.cplusplus.com/doc/tutorial/structures/
but its not the same in windows forms :/
any help??
THANKS!
btw, i figured it out!
you must create a new class in the project...
call it, Player.h
in the new class, you must instantiate the class like below
to make it a managed class so it fits well with the managed code
in the forms (notice ref class keyword)
struct markedPos
{
int xPos;
int yPos;
};
ref class Player
{
public:
Player()
{
}
protected:
private:
};
then simply in the forms.h file, you must include the new class like any other class:
#include "Player.h"
and all you have to do is make an instance of the player in your forms and it'll work like magic! What i've learned: Do all your heavy lifting in the managed classes outside of the forms... which work just like your regular c++ classes...
cheers!
** You don't need to use managed code! if your getting problems with it, just remove 'ref' before class name

Customizing MEF

I have this situation where I want to use MEF in a chess project I'm workin on. Let's say I have a class constructor as in:
public class MoveManager
{
private Piece _piece;
public MoveManager(Piece piece)
{
_piece = piece;
}
Mode code here...
}
In this context I would have several classes that would derive from Piece like, Pawn, Rook, etc. If I put export attributes on all the classes the derive from Piece, the object being passed into the constructor is null. MEF loops through all classes the have the [Export(typeof(Piece))] and if it exceeds 1, it passes in null. So I cannot use MEF in this way. I'm going to use an Abstact Factory for getting the correct piece. Seems like the DI part of MEF can only take a single class that has the [Export(typeof(some base class))].
Can anyone shed some light on this?
I think you might be looking for the [Importing Constructor] arrtibute, which tells MEF how to use an exported class's constructor.
[Export(typeof(IPiece))]
class Pawn : IPiece
{
[ImportingConstructor]
public Pawn(ISomeDependency dep, [ImportMany] IEnumerable<IOtherDependency> depList)
{
//... do stuff with dependencies
}
}
This requires that an ISomeDependency is exported elsewhere (exactly once) and accepts any number of IOtherDependency's that might be exported too.
Supposing you did this with each piece, you could then:
[Export(typeof(IPieceList))]
class PieceList : IPieceList
{
[ImportingConstructor]
public PieceList([ImportMany] IEnumerable<IPiece> pieces)
{
// pieces now contains one of each piece that was exported above
}
}

Resources