coming from c family language (i use c#) makes Javascript model confusing somehow.
in c# you have to have a class. then instantiate the object from that class to use it.
in Javascript there is no class . it is all about functions. Function in itself is an object and it can be used directly without instantiating .
for example:
function sayHi(name){
alert ("hiiiii " + name);
}
sayHi("John");
So the function sayHi is already an object and instantiated and working !!
Now if you want to access its property prototype you can do that like following:
function sayHi(name){
alert ("hiiiii " + name);
}
sayHi.prototype.nn = 20;
sayHi("John");
alert(sayHi.nn);
but the above code will fail to alert the nn as 20; it will give undefined !!
however if you make the sayHi function a constructor function to another variable then this prototype property will be accessable like the followin:
function sayHi(name){
alert ("hiiiii " + name);
}
sayHi.prototype.nn = 20;
sayHi("John");
alert(sayHi.nn);
var hi2 = new sayHi("May");
alert(hi2.nn);
now alert(hi2.nn) give you 20 ; which means the prototype of the sayHi was not accessible till we instantiate it using the word new assigning it to another variable.
My question:
Isn't this similar to the c# class instantiation?
and since the function sayHi is already a Function object ; what
is the purpose of making its prototype not accessible unless it
is a constructor function to another variable?
CODE DEMO
Related
We use ClearScript to extend our apps. We expose various C# objects into JavaScript, using ClearScript's AddHostType and AddHostObject methods.
Recently we've started using Typescript in our Google Apps Script projects and thought it would be good to use it to manage our ClearScript scripts as well.
This has proved to be an interesting experience. We know know about such things as external.d.ts and have started to write one to handle the various symbols that we're injecting in from the C# side.
Some things we've been able to work out. For example, in this code
function SchTasks(instruction:string) {
var proc = CSProcess.Start("C:\\Windows\\System32\\schtasks.exe", instruction);
return proc;
}
this declaration seems to work
declare namespace CSProcess {
function Start(a:string, b:string): any;
}
Likewise, with this block
that.getMyIP = function () {
var request = new CSRestRequest();
request.AddParameter("user", username);
request.AddParameter("pass", password);
request.AddParameter("command", "getmyip");
var response = client.Execute(request);
return response.Content.trim();
};
this declaration appears to work
declare class CSRestRequest {
constructor (str?:any) ;
AddParameter(a:string, b:string) : any;
}
What's puzzling us at the moment is how to declare the following. The symbol is called CSSettings and it's an instance of Dictionary<string,object>, so it has some methods hanging off it, like .ContainsKey. What's the best way to declare this? It can't be newed so it's not a class with a constructor, but it does have methods like a class.
var taskName = "\XChecker\M_XChecker_" + (function () {
if (CSSettings.ContainsKey("/TEST")) {
return "TEST";
}
if (CSSettings.ContainsKey("/PRODUCTION")) {
return "PRODUCTION";
}
return "UNKNOWN";
}
()) + "_" + CSSettings("/TASKRULESETGROUPLUTFKS") + "_" + CSSettings("/INSTANCENUMBER") + "_" + CSSettings("/INSTANCECOLUMN");
LATER
The following appears to work. What's curious is that VSCode is not reporting a clash of symbol names. Can CSSetting really be a function and a namespace at the same time? Apparently, yes.
declare function CSSettings(s:string):any;
declare namespace CSSettings {
function ContainsKey(s:string):boolean;
}
declare your dictionary class. and then variable CSSettings with this type
declare class IDictionary {
constructor();
public ContainsKey(key: string): boolean;
}
declare const CSSettings: IDictionary;
CSSettings.ContainsKey('key');
// edit
so what about to create 2 type and merge it? so you will be able to use CSSettings as function and even as object
declare type functionType = (key: string) => boolean;
declare const CSSettings: functionType & { ContainsKey: (key: string) => boolean };
CSSettings.prototype.ContainsKey = 1;
CSSettings('key');
CSSettings.ContainsKey('key');
I'm creating some UI for a game I'm currently working on in C#, and want to expose everything down to Lua so that my artist can make small tweaks without needing to do anything in code. I'm using MoonSharp for integrating Lua scripts into my project.
Here is what I currently have for my UIElement wrapper class:
UIElement = {};
UIElement.__index = UIElement;
setmetatable( UIElement, {
__index = function( self, key )
local codeElement = rawget( self, "__codeElement" );
local field = codeElement and codeElement[key];
if type( field ) == "function" then
return function( obj, ... )
if obj == self then
return field( codeElement, ... );
else
return field( obj, ... )
end
end;
else
return field;
end
end,
__call = function( cls, ... )
return cls.new( ... );
end,
} );
function UIElement.new()
local self = setmetatable( {}, UIElement );
self.__codeElement = BLU_UIElement.__new();
return self;
end
BLU_UIElement is my C# class which is exposed to Lua via the MoonSharp API. It works properly when working directly with the object, and has functions like SetPos, SetColor, etc.
UIElement is intended to be my "class" in Lua to wrap and extended my C# object.
When I instantiate a UIElement elsewhere in script and attempt to call a function (SetPos for example), it does correctly get into the __index function. However, the rawget call always returns nil. It doesn't seem specific to the BLU_UIElement either. I have already tried something very simple like adding a string ID value in the constructor and trying to rawget it in the __index function, but it also returns nil.
I'm assuming I'm just doing something incorrectly setting up the metastable on either the class or the object itself, but I'm not exactly sure where the problem lies. I've been looking here: http://lua-users.org/wiki/ObjectOrientationTutorial for an idea on what I'm doing wrong, but nothing jumps out on me.
I appreciate any guidance on this, I've been looking at this for a couple days without figuring it out, and searching online generally just shows similar code to what I am already doing.
I got to admit that I am not entirely sure, what you are trying to achieve by writing your wrapper class in LUA and not C# and then expose that type but I noticed this:
For me NativeClass.__new() never worked out in MoonSharp like you are trying to do it at
self.__codeElement = BLU_UIElement.__new();
For this reason I create custom constructor-functions for my native classes and pass them to to the global namespace as delegates (Its type has to be registered though). It looks a lot like you would normally construct an object. Just without the new keyword:
In C#
public NativeClass{
public static NativeClass construct()
{
return new NativeClass();
}
}
Pass the static method as delegate to the script:
script["NativeClass"] = (Func<NativeClass>)NativeClass.construct;
Then you can create a new Instance like this in MoonSharp:
x = NativeClass()
EDIT: So didn't read that you have tried to do this with a string. Maybe you should consider not writing a wrapper class in LUA but in C# or is there a reason that forbids this?
I had a friend who is far more experienced with Lua metatables than I am take a look. Posting the answer here in case it helps anyone else.
The issue was that I was trying to use the UIElement table as both the "class" table as well as the "object" metatable. When calling rawget inside the __index function, it was attempting to find things in the UIElement table instead of the self table created in UIElement.new(). Splitting these two into distinct tables (one for the class, one for the object metatable) fixed things.
Here is my updated and working code:
UIElement = {};
setmetatable( UIElement, {
__call = function( cls, ... )
return cls.new( ... );
end,
} );
UIElement.objectMetaTable = {
__index = function( self, key )
local objectValue = rawget(self, key);
if objectValue ~= nil then
return objectValue;
end
local classValue = UIElement[key];
if classValue ~= nil then
return classValue;
end
local codeElement = rawget(self, "__codeElement");
if codeElement then
return codeElement[key];
end
end,
};
function UIElement.new()
local newInstance = setmetatable( { id = "blah" }, UIElement.objectMetaTable );
newInstance.__codeElement = BLU_UIElement.__new();
return newInstance;
end
I am using Unity WebGL for my project and want to communicate from browser JavaScript to C#. One way is to call C# function from JavaScript using SendMessage. I am easily making call using this code snippet in javascript:
gameInstance.SendMessage("MyObjectName","MyFunctionName",myParameter);
But there is a problem it is not returning any value. For getting a value I have to implement a separate function that run another function. Can I return value directly? Send Message docs clearly stating it don’ t return any value, so other than sendMessage is there any way available to get return value from directly function calling?
Use your custom class as a parameter - for example:
public class CustomData
{
public string Input;
public string Output;
}
...
CustomData data = new CustomData();
data.Input = "Something";
gameInstance.SendMessage("MyObjectName", "MyFunctionName", data);
//use data.Input inside MyFunctionName like a parameter
//change data.Output inside MyFunctionName
//use data.Output
Debug.Log(data.Output);
I am receiving the "Reference to a non-shared member requires an object reference." error when I try to call a struct in C# from VB.net.
I am writing the VB side of this, the C# side was previously written.
I have setup the reference to the C# project in my solution and can see everything from the C# project just fine.
Code I am calling
public ContourPt[] CalcContour(
double LatDegr,
double LonDegr,
int NPts,
double dBuBaseline,
double ERP,
double AntHAMSL,
WHICHCHART_ENUM WhichChart,
double AntAz,
int AntennaId)
{
double dBu = dBuBaseline + 9.0 - 10.0 * Math.Log10(ERP / 1000.0);
if(NPts < MinNPts) throw new ArgumentOutOfRangeException("NPts", NPts, "must be at least "+MinNPts);
double dAz = 360.0 / (double)NPts;
LatLonDegr llDegr = new LatLonDegr(LatDegr, LonDegr);
LatLonSec llSec = llDegr;
return CalcContour(llSec.LatSecN, llSec.LonSecW, dAz, dBu, AntHAMSL, WhichChart, AntAz, AntennaId);
}
I've tried mutiple ways of calling the method but I am consistenly getting the same error. But even the simple snippet below won't work.
Dim np() As ContourPt
np(i) = CalcContour(plat, plon, nPts, ddBu, dERP, dAnthAMSL, WhichChart, dAntAz, iAntId)
Thanks for any assistance you can provide. If I need to provide additional code to better help solve the issue I have, please let me know.
Thank you
It looks like the function itself needs to be declared static, so that it can be called without an object reference.
public static ContourPt[] CalcContour(...)
If you can't change the definition of that, then you need an instance of whatever class it is in.
public class ClassName{ // Is this in the ContourPt class?
public ContourPt[] CalcContour(...)
}
Dim obj = new ClassName()
Dim np() As ContourPt
np(i) = obj.CalcContour(...)
The fact that some of the code was written in C# and some in VB is irrelevant - It's all IL by the time it runs.
The error simply means that you can't call a non-shared member unless you have an object instance. You need to instantiate the object you wish to use before you can use it:
Dim o As New Object
o.toString()
As opposed to calling a shared member, which you do directly on the class:
Convert.toInt16(someValue);
PHP has a function called print_r() and var_dump() that will display all the contents of an item. It makes it very easy to figure out what things are.
Is there something like that in C#?
I know there is a Console.WriteLine("Hello"); in C#, but does this work in the MVC? Can I do some type of debug.trace() like flash does into a debug console while I run the application?
System.Diagnostics.Debug.WriteLine("blah");
and in order to show all variables in the object you would have to override its ToString() method or write a method which returns all the info you need from the object.
i.e.
class Blah{
string mol = "The meaning of life is";
int a = 42;
public override string ToString()
{
return String.Format("{0} {1}", mol, a);
}
}
System.Diagnostics.Debug.WriteLine(new Blah().ToString());
In short there is nothing in built but it can be done.
If you must print ALL the objects info without overriding or adding logic on a class by class level then you are in the realms of reflection to iterate the objects PropertInfo array