How do I pass a class as an argument to a function in UnrealScript? - unrealscript

I want to do
result = TraceActors(class'QuadForcePawn', HitEnemy, hitLocation, HitNorm, weaponStart, m_oldWeaponStartLocation[iHand], vExtent);
but I want to substitute a variable for the class'QuadForcePawn' part. I haven't been able to figure out how to do this.
This is so I can have a function that calls TraceActors, and that function takes an argument telling it which kinds of Actors to look for.

Technically, TraceActors is actually an iterator function and is meant to be used with the foreach keyword, so you wouldn't actually assign the result to a variable.
To answer your question, what you want to use is a class reference variable. An example function might look like this (TraceActors actually requires many more parameters, but I've left them out for brevity.):
function TraceFor (class<Actor> traceClass)
{
local Actor A;
foreach TraceActors(traceClass, A)
{
// do work here
}
}
Class reference variables are declared with the class keyword, and optionally you can use the <> syntax to limit the classes which can be assigned to it. class<Actor> declares a class reference variable which can only have Actor or subclasses of Actor assigned to it. In the example function above, a call to TraceFor(class'Pawn') would work fine, but a call to TraceFor(class'Object') would fail to compile.
If you want to return the result of the TraceActors call, one way to do it might be to build an array of the results and return that:
// Returns an array of Actors of the passed in type.
function TraceFor (class<Actor> traceClass, out array<Actor> results)
{
local Actor A;
foreach TraceActors(traceClass, A)
{
results.AddItem(A);
}
}

Related

How to call a single argument from a function with multiple argument in C?

Say you have a several function like this:
void Inventory(int index, char input[], int qty)
void AddItem(){
int index = Inventory(index);
if (int i = 0; i < index; i++){
...
}
}
But it gave me an error 'A value of type "Void" cannot be used to initialize an entity of type "int"'
Can someone explain to me in detail since im new to programming too.
You're trying to initialize index as an int whose value is returned by calling Inventory(index). But the Inventory function you provided has a return type of void, not the expected int, so there's no way to get that value.
Also, your call to Inventory is missing an argument to the chat input[] and int qty parameters. Additionally, index is uninitialized at the time that you're trying to use it (within the definition of index).
The function Inventory does not return anything (which is void) and you are trying to affect 'nothing' to a variable of type int. That's why the compiler is complaining.
The solution is to have your Inventory function return an int value instead of void.
First of all, your question and code snippet that you have provided are misleading.
Secondly, You are getting this error because the return type of function Inventory is Void, which means it returns nothing. And you are trying to assign nothing to variable index, which is of type int.
And, if you are trying to call multi-argument function without having to pass all arguments, make rest of the argument optional.
void foo(/.../) means that the function foo does not return anything. So you cant assign nothing to something.
In C you need to pass all the parameters. In other languages (like C++) some parameters might have default values and you do not have to pass them when call the function. But it is not possible in the C language and you need to pass all the parameters (arguments)

How to access value passed into void tmin(void) function and then alter it?

I am working on an assignment. My teacher has given me this function
void tmin(void){
return 2;
}
I need to take whatever value is passed into this function, manipulate it, and return it. Where I am stuck is the tmin(void) part. How do I work on the value that is passed in if it just says void? Is there a way to assign it to a new variable?
A function void f(void) { ... } does not accept a anything to pass into the function, nor does it return anything. You need to change the signature of the function (return type and parameters and its types) and its body according to the task your teacher gave to you.

How can i call lua function that takes self as a parameter from C?

For example, If I have function like
foo = function(self) print ("Foo") end
to call this function, I would say, foo:()
How do I call this kind of function from C?
foo:() is not legal.
That function would need to be in a table for the : call syntax to work.
tab = {
foo = function(self)
print "Foo"
end
}
tab:foo()
The important thing to know is that tab:foo() is just syntactic sugar for tab.foo(tab) (only tab is only evaluated once).
So to call that manually you just need to pass the object as the first argument yourself.

Call a proc in Ruby C extension

I have the following struct:
typedef struct{
int a;
int (*init)(void);
} tObj;
I am wrapping this into an object 'ObjExt' in Ruby. Ruby initialization method gets a Proc 'cb' that shall be run anytime 'init' function is called somewhere to generate an integer.
something like:
cb = Proc.new { 1 }
ruby_obj = ObjExt.new(cb)
My first shot at this was I passed the 'cb' proc to a global VALUE type variable and run rb_funcall on it in a wrapper function "int (*wrapper)(void)" that I define, and literally assign init = wrapper. but this won't work if I have multiple object instances of ObjExt class as the global variable is shared between instances and gets overwritten when initializing the second and third objects.
Any hints would be appreciated. I am probably approaching the problem in a wrong way.

CLI array initialization in value class

I know that value classes don't have an default constructor as the compiler initializes all elements in this class with zero. But arrays are in a value class are not initialized:
value class c_LocationVal
{
public:
double x, y, z;
c_LocationVal(double i_x, double i_y, double i_z) {x = i_x; y = i_y; z = i_z;}
};
typedef cli::array<c_LocationVal> arrloc;
value class c_Managed
{
public:
arrloc^ m_alocTest;
//c_Managed() { m_alocTest = gcnew arrloc(3); } --> not permitted
double funcManaged ()
{
return m_alocTest[0].x; --> error: Object reference not set to an instance of an object
}
};
I just could cheat and use:
c_Managed(int i) { m_alocTest = gcnew arrloc(3); }
but there must be another solution.
Can someone please tell me how to solve this?
The CLR only supports code inside of methods. Compilers emulate the behavior of a member initialization expression by creating a constructor, if necessary, and moving the code for the expression into the constructor.
Which explains why this isn't permitted, your expression requires a parameterless constructor and that's not legal for a value type.
Sure, your trick will work. But in general, you need to de-tune C++ assumptions a bit when you write C++/CLI code. There are no practical differences between a struct and a class in C++. But that's definitely not the case in managed code. Only ever use a value class for very simple types. Requiring initialization heavily tips the choice to a ref class. As does a value type having an array, you'd normally need a deep copy to make that work without accidents. Never fear the heap in C++/CLI, it is very fast.
A value class is always initialized with "null/0". So a managed reference in a value class will also always be initialized to "null". If you want to have a special initialization, then you only have the solution, you were pointing out: You need to create a special constructor which has some parameters to "initialize" the value class correctly.
The question is: Do you really need a value class which contains a managed reference??? Normally this should also be a ref class.
Also, what happens, if the value class is copied? What should happen with the reference? It will also directly copied! Is this intended? The goal of a value class is to provide a "real" copy! In your case it will not "fully copied"...
Pleas re-think if a value class is the best solution for your data storage...
Switch the public field to a property, and do lazy initialization when the property is retrieved.
value class c_Managed
{
private:
arrloc^ m_alocTest;
public:
arrloc^ AlocTest
{
arrloc^ get()
{
if(m_alocTest == nullptr)
{
msclr::lock(c_Managed::typeid)
if(m_alocTest == nullptr)
m_alocTest = gcnew arrloc(3);
}
return m_alocTest;
}
}
double funcManaged ()
{
return AlocTest[0].x;
}
};
The lock for the lazy initialization isn't ideal, but it's just about the only thing to lock on: this is a value type, so locking would box it and the lock would be on the box, not on the object itself. Since it's a value type, providing any reference type as a field to lock on would give a null reference, just like the array, so there's no help there. The only thing I can think to lock on is the type object itself for this type.

Resources