I hear that UnityScript is pretty close to JavaScript. Does UnityScript support the Object Literal syntax of JavaScript?
e.g.
var x = {
y: 12
};
Strangely, searching google for UnityScript "Object Literal" yields no useful results.
UnityScript versus JavaScript have very different semantics.
Creating a new JavaScript file in Unity with this syntax will not compile.
#pragma strict
var x = {
y: 12 // error: BCE0005
};
function Start () {
Debug.Log (x.y); // error: BCE0019
}
This will give build errors:
NewBehaviourScript(4,5): BCE0005: unknown identifier: 'y'.
NewBehaviourScript(8,17): BCE0019: 'y' is not a member of 'Boo.Lang.Hash'.
However, you could implement a Hashtable:
#pragma strict
var x:Hashtable = new Hashtable();
x["y"] = 12;
function Start () {
Debug.Log (x["y"]);
}
Related
The DLL file was developed in Delphi. The Function was described as bellow:
Function name: GetMsg
Function description: It is used to get error
info.
Function prototype: procedure GetMsg(ret: Integer; var Msg:
PChar); stdcall;
Parameter description: ret: It indicates error code. Msg: It is used
to output the corresponding error info.
Firstly, you need to allocate
memory. The memory is greater than or equal to 255.
According to the description, I know Msg parameter is a pointer, then I use node-ffi to invoke the GetMsg procedure as bellow:
var ffi = require('ffi');
var ref = require('ref');
var TheLib = ffi.Library('TheLib.dll', {
GetMsg: ['void', ['int', ref.types.CString]]
});
const outNameBuffer = Buffer.alloc(255);
TheLib.GetMsg(-25, outNameBuffer);
console.log(outNameBuffer, ref.readCString(outNameBuffer));
I always get this response:
Note that, I i use ctypes in Python, I could get a Chinese message corresponding to the value -25.
Any suggestion on this?
I had about the same problem, try my solution:
var ffi = require('ffi');
var ref = require('ref');
var ArrayType = require('ref-array');
var charPtrArray = ArrayType('char *', 64);
var charPtrArrayPtr = ref.refType(charPtrArray);
var TheLib = ffi.Library('TheLib.dll', {
GetMsg: ['void', ['int', charPtrArrayPtr]
});
console.log(charPtrArrayPtr);
I'm having real trouble trying to access the symbol dynamically, I have 9 buttons that all call this method, and they pass in their location (tl, t, tr, etc.) I've tried this method before on another program and it works without a problem, but in this program it fails.
I am attempting to access a symbol call s_tl (example location), but all I'm getting is undefined (see results).
function turn(btn : String):Function {
return function(e:MouseEvent) {
var players_turn : int;
var chosen : String = "s_" + btn;
trace(this);
trace(this[chosen]);
trace(chosen);
trace(this[chosen]);
// if crosses turn 0 else 1
if (s_c.currentFrame == 1) {
players_turn = 0;
} else {
players_turn = 1;
}
// check who's turn it is if it's been pressed before
if (players_turn == 0 && this[chosen].visible == false) {
this[chosen].gotoAndStop(1);
this[chosen].visible = true;
} else {
this[chosen].gotoAndStop(2);
this[chosen].visible = true;
}
};
}
Results:
[object global]
undefined
s_br
undefined
TypeError: Error #1010: A term is undefined and has no properties.
at MethodInfo-6()
Your problem is the bad code style. You define unnamed unbind function inside function turn() and that's where the root of your problem is. Unbind function exist, as your trace shows, in global addressing context and, unlike function turn(), is not bind to any specific display object. Your buttons probably exist on the same addressing context with turn(). Argument btn is available inside unnamed function because ECMA standard instructs so (if function A creates function B then local variables, including arguments, of A are available as local variables in B), but it is a very very very bad practice that makes code messy and induce headaches.
Please explain what you tried to achieve with that code so we could untangle it and rewrite in not-so-twisted way.
Okey, I basically figured you're doing Tic Tac Toe. Now, guideline. A cell must contain 3 frames: 1st frame for the button graphics, 2nd and 3rd for X and O. Name them your way: s_1, s_2, etc.
for (var i:int = 1; i < 10; i++)
{
var aCell:MovieClip = getChildByName("s_" + i) as MovieClip;
aCell.addEventListener(MouseEvent.CLICK, onTic);
}
function onTic(e:MouseEvent):void
{
var playersTurn:int = s_c.currentFrame;
var aCell:MovieClip = e.currentTarget as MovieClip;
trace(aCell.name);
// Now, the magic.
aCell.gotoAndStop(playersTurn + 1);
aCell.removeEventListener(MouseEvent.CLICK, onTic);
}
I want to get all arguments names of a function inside the function
example:
function fct(var1:string,var2:string){
var names:Array=...
trace(names);
}
must trace : var1,var2
Thanks!
Simply put, this is not possible. The closest you can get is the argument number and value. See below:
function fct( ... args ):void {
for ( var v:Object in args ) {
trace( v + ": " + args[v] );
}
}
var str1:String = "this is a test";
var str2:String = "this is another test";
fct( str1, str2 );
//output
//0: this is a test
//1: this is another test
For future reference, you can use ... + a variable name to allow for as many arguments as you need. Regardless, you should just need to access args[ INDEX ] rather than the actual variable name, which you wouldn't be able to access anyway because there would be no way to apply scope (such as variableName[ "propertyName" ])
It is impossible like native method, but you can use metadata tag to set arguments names. I create simple example. But i don't understand how it can help you in real projects:
[Arguments(param1="arg1",param2="arg2")]
public function test(arg1:Number, arg2:Number):void {
var desc_xml:XML = describeType(Object(this).constructor);
var metas_xml:XMLList = desc_xml.factory.method.(#name == "test");
var args_xml:XMLList = metas_xml.metadata.(#name == "Arguments");
for each (var argx:XML in args_xml.arg)
{
trace(argx.#value.toXMLString());
}
};
I use flex 4.6. Don't forget add each existing Metadata tags to the compiler argument with “-keep-as3-metadata+=Arguments”. It need for compile release versions.
I'm just testing typescript in VisualStudio 2012 and have a problem with its type system. My html site has a canvas tag with the id "mycanvas". I'm trying to draw a rectangle on this canvas. Here's the code
var canvas = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
Unfortunately VisualStudio complains that
the property 'getContext' does no exist on value of type
'HTMLElement'
It marks the second line as an error. I thought this would be merely a warning but the code does not compile. VisualStudio says that
there were build errors. Would you like to continue and run the last
successful build ?
I didn't like this error at all. Why is there no dynamic method invocation ? After all the method getContext definitely exists on my canvas element. However I thought this problem would be easy to solve. I just added a type annotiation for canvas:
var canvas : HTMLCanvasElement = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
But the type system still wasn't satisfied. Here's the new error message, this time in the first line:
Cannot convert 'HTMLElement' to 'HTMLCanvasElement': Type
'HTMLElement' is missing property 'toDataURL' from type
'HTMLCanvasElement'
Well, I'm all out for static typing but this makes the language unusable. What does the type system want me to do ?
UPDATE:
Typescript has indeed no support for dynamic invocation and my problem can be solved with typecasts. My question is basically a duplicate of this one TypeScript: casting HTMLElement
var canvas = <HTMLCanvasElement> document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
or using dynamic lookup with the any type (no typechecking):
var canvas : any = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
You can look at the different types in lib.d.ts.
const canvas = document.getElementById('stage') as HTMLCanvasElement;
While other answers promote type assertions (that's what they are — TypeScript doesn't have type casts that actually change the type; they are merely a way of suppressing type checking errors), the intellectually honest way to approach your problem is to listen to the error messages.
In your case, there are 3 things that can go wrong:
document.getElementById("mycanvas") might return null, because no node of that id is found (it might have been renamed, not injected to the document yet, someone might have tried running your function in an environment without access to DOM)
document.getElementById("mycanvas") might return a reference to a DOM element, but this DOM element is not a HTMLCanvasElement
document.getElementById("mycanvas") did return a valid HTMLElement, it is indeed an HTMLCanvasElement, but the CanvasRenderingContext2D is not supported by the browser.
Instead of telling the compiler to shut up (and possibly finding yourself in a situation where a useless error message like Cannot read property 'getContext' of null is thrown), I recommend taking control over your application boundaries.
Make sure the element contains a HTMLCanvasElement
const getCanvasElementById = (id: string): HTMLCanvasElement => {
const canvas = document.getElementById(id);
if (!(canvas instanceof HTMLCanvasElement)) {
throw new Error(`The element of id "${id}" is not a HTMLCanvasElement. Make sure a <canvas id="${id}""> element is present in the document.`);
}
return canvas;
}
Make sure the rendering context is supported by the browser
const getCanvasRenderingContext2D = (canvas: HTMLCanvasElement): CanvasRenderingContext2D => {
const context = canvas.getContext('2d');
if (context === null) {
throw new Error('This browser does not support 2-dimensional canvas rendering contexts.');
}
return context;
}
Usage:
const ctx: CanvasRenderingContext2D = getCanvasRenderingContext2D(getCanvasElementById('mycanvas'))
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
See TypeScript Playground.
It seems this is being corrected in the .9 version of TypeScript:
http://blogs.msdn.com/b/typescript/archive/2013/03/25/working-on-typescript-0-9-generics-overload-on-constants-and-compiler-performance.aspx
See the section on "Overload on Constants" where the canvas tag is explicitly shown.
I had the same problem, but with SVGSVGElement instead of HTMLCanvasElement. Casting to SVGSVGElement gave a compile-time error:
var mySvg = <SVGSVGElement>document.getElementById('mySvg');
Cannot convert 'HTMLElement' to 'SVGSVGElement':
Type 'HTMLElement' is missing property 'width' from type 'SVGSVGElement'.
Type 'SVGSVGElement' is missing property 'onmouseleave' from type 'HTMLElement'.
If fixed it by first casting to 'any':
var mySvg = <SVGSVGElement><any>document.getElementById('mySvg');
or this way (it has the identical effect)
var mySvg: SVGSVGElement = <any>document.getElementById('mySvg');
Now mySvg is strongly typed as SVGSVGElement.
You may have to add DOM to compilerOptions.lib in your tsconfig.json.
// 'tsconfig.json'
{
"compilerOptions": {
"target": "ES2017",
"module": "commonjs",
"lib": [
"es5",
"DOM",
"esnext"
]
}
}
This is an old topic... maybe dead to 2012, but exciting and new to VS Code and typescript.
I had to do the following to get this to work in VS Code with the following package references.
const demoCanvas: HTMLCanvasElement = document.getElementById('rfrnCanvas') as any;
if(demoCanvas.getContext) {
const context = demoCanvas.getContext('2d');
if(context) {
reactangle(context);
}
}
Typescript Version:
{
"#typescript-eslint/eslint-plugin": "^2.29.0",
"#typescript-eslint/parser": "^2.29.0",
"typescript": "^3.7.5"
}
I'd recommend
let canvas = document.getElementById('canvas') as
HTMLCanvasElement;
Can someone tell me what the difference is between the 2 JSON parsers?
https://github.com/douglascrockford/JSON-js/blob/master/json.js
https://github.com/douglascrockford/JSON-js/blob/master/json2.js
I have a JSON file from 2007-04-13 (It has methods such as parseJSON). I don't see these methods in any of the new versions.
From their code:
// Augment the basic prototypes if they have not already been augmented.
// These forms are obsolete. It is recommended that JSON.stringify and
// JSON.parse be used instead.
if (!Object.prototype.toJSONString) {
Object.prototype.toJSONString = function (filter) {
return JSON.stringify(this, filter);
};
Object.prototype.parseJSON = function (filter) {
return JSON.parse(this, filter);
};
}
I guess parseJSON is obsolete, therefore the new version (json2) doesn't even use it anymore. However if your code uses parseJSON a lot you could just add this piece of code somewhere to make it work again:
Object.prototype.parseJSON = function (filter) {
return JSON.parse(this, filter);
};
Quoting here:
"JSON2.js - Late last year Crockford quietly released a new version of his JSON API that replaced his existing API. The important difference was that it used a single base object."
I also noticed that json2 stringified arrays differently than json2007.
In json2007:
var array = [];
array[1] = "apple";
array[2] = "orange";
alert(array.toJSONString()); // Output: ["apple", "orange"].
In json2:
var array = [];
array[1] = "apple";
array[2] = "orange";
alert(JSON.stringify(array)); // Output: [null, "apple", "orange"].