Can I extend the dut_error() method? - specman

I would like to extend dur_error() method in order to write the name of the package from which the error is reported.

The dut_error() is not really a method (it is a macro that calls multiple methods), so cannot be extended.
But you can extend the dut_error_struct, and then add the code that you want. Using source_struct() you can know what struct called dut_error(), and using reflection - you can tell in which package it was defined.
For example -
extend dut_error_struct {
write() is first {
out(source_struct() is a any_unit ? "UNIT " : "STRUCT ",
source_struct_name(), " reporting of error: ");
// Special output for errors coming from the ahb package:
// Using reflection, can get lots of info about the reporting struct.
// For example - in which package it was defined
// If using annotation - can use them as well.
// For example - different messages for annotated features
var reporter_rf : rf_struct =
rf_manager.get_struct_of_instance(source_struct());
if reporter_rf.get_package().get_name() == "ahb" {
out(append("xxxxxx another bug in AHB package, ",
"\nreported ", source_location()));
};
};
I recommend looking for dut_error_struct in the help, to see this struct's methods.

Related

NetSuite SuiteScript - Constants And Inclusion

I have a NetSuite SuiteScript file (2.0) in which I want to include a small library of utilities I've built. I can do that fine, and access the functions in the included library. But I can't access the constants I've defined in that library - I have to re-declare them in the main file.
Here's the main file:
define(['N/record', 'N/search', './utils.js'],
function (record, search, utils) {
function pageInit(scriptContext) {
isUserAdmin = isCurrentUserAdmin(contextRecord);
if (isUserAdmin) {
alert('Administrator Role ID is ' + ADMINISTRATOR_ROLE);
// Do something for Admin users
}
return;
}
return {
pageInit: pageInit
};
});
You can see I include the file ./utils.js in it. Here's utils.js:
const ADMINISTRATOR_ROLE = 11;
function isCurrentUserAdmin(currentRecord) {
return ADMINISTRATOR_ROLE == nlapiGetRole();
}
That's the entire file - nothing else.
In the main file, the call to the function isCurrentUserAdmin works fine. It correctly tells me whether the current user is an admin. Note that I don't have to preface the call to isCurrentUserAdmin with utils. (utils.isCurrentUserAdmin doesn't work - it gives me the error JS_EXCEPTION TypeError utils is undefined). But when the code gets to the line that uses ADMINSTRATOR_ROLE, I get the error JS_EXCEPTION ReferenceError ADMINISTRATOR_ROLE is not defined. BTW, if I put the constant definition of ADMINISTRATOR_ROLE in the main file instead of utils.js, I get the same error when utils.js tries to use it. The only way I can get it to work is if I have the line defining the constant in both files.
Why does the inclusion work for the function, but not the constant? Am I including the library wrongly? I thought I'd have to use it as utils.isCurrentUserAdmin rather than just isCurrentUserAdmin, but to my surprise that's not the case, as I say above.
If you have utils.js like below, you can use utils.ADMINISTRATOR_ROLE and utils.isCurrentUserAdmin() in your main file.
/**
*#NApiVersion 2.0
*/
define ([],
function() {
const ADMINISTRATOR_ROLE = 11;
function isCurrentUserAdmin() {
// check here
}
return {
ADMINISTRATOR_ROLE: ADMINISTRATOR_ROLE,
isCurrentUserAdmin: isCurrentUserAdmin
};
});
Try
define(['N/record', 'N/search', 'SuiteScripts/utils']
You need to make sure any member you need to access in another module needs to be exported in the source module using the return statement

Multicast Delegates - C++

I would like to receive a multicast event from the LeapMotion plugin in C++. From their documentation, they mention the following things:
> On Hand Grabbed Event called when a leap hand grab gesture is
> detected. Signature: const FLeapHandData&, Hand, see FLeapHandData
>
> FLeapHandSignature OnHandGrabbed;
So in my .cpp file I added the following:
ALeapMotionGesture::ALeapMotionGesture()
{
PrimaryActorTick.bCanEverTick = true;
Leap = CreateDefaultSubobject<ULeapComponent>(TEXT("Leap"));
}
void ALeapMotionGesture::BeginPlay()
{
Super::BeginPlay();
if (Leap != nullptr) {
FScriptDelegate Delegate;
Delegate.BindUFunction(this, FName("HandGrabbed"));
Leap->OnHandGrabbed.Add(Delegate);
}
}
void ALeapMotionGesture::HandGrabbed(const FLeapHandData& Hand) {
UE_LOG(LogTemp, Warning, TEXT("Hand Grabbed"));
}
As it is the first time I'm using delegates in Unreal/C++, I would like to know how I could make it work?
It compiles fine however I do not receive any events.
Add UFUNCTION() on your function HandGrabbed
Short Answer
Replace:
void ALeapMotionGesture::BeginPlay()
{
Super::BeginPlay();
if (Leap != nullptr) {
FScriptDelegate Delegate;
Delegate.BindUFunction(this, FName("HandGrabbed"));
Leap->OnHandGrabbed.Add(Delegate);
}
}
with:
void ALeapMotionGesture::BeginPlay()
{
Super::BeginPlay();
if (Leap != nullptr) {
Leap->OnHandGrabbed.AddDynamic(this, &ALeapMotionGesture::HandGrabbed);
}
}
Long Answer
ULeapComponent::OnHandGrabbed is a FLeapHandSignature which is declared with DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam.
The LeapMotion README says to consult the Multi-cast documentation, but they are using dynamic delegates, so you actually need to read the Dynamic Delegates documentation. There you will see you should use the AddDynamic helper macro which generates the function name string for you.
Dynamic Delegates make use of helper macros that take care of generating the function name string for you.
From the Dynamic Delegates doc:
Dynamic Delegate Binding
BindDynamic( UserObject, FuncName )
Helper macro for calling BindDynamic() on dynamic delegates.
Automatically generates the function name string.
AddDynamic( UserObject, FuncName )
Helper macro for calling AddDynamic() on dynamic multi-cast delegates.
Automatically generates the function name string.
RemoveDynamic( UserObject, FuncName )
Helper macro for calling RemoveDynamic() on dynamic multi-cast
delegates. Automatically generates the function name string.
Side Note
Dynamic delegates are serialized, which sometimes results in unexpected behavior. For example, you can have delegate functions being called even though your code is no longer calling AddDynamic (because a serialized/saved actor serialized the results of your old code) or you might call AddDynamic even though the deserialization process already did that for you. To be safe, you probably should call RemoveDynamic before AddDynamic. Here's a snippet from FoliageComponent.cpp:
// Ensure delegate is bound (just once)
CapsuleComponent->OnComponentBeginOverlap.RemoveDynamic(this, &AInteractiveFoliageActor::CapsuleTouched);
CapsuleComponent->OnComponentBeginOverlap.AddDynamic(this, &AInteractiveFoliageActor::CapsuleTouched);

Unity3D & YamlDotNet Deserializing Data into Monobehaviour-derived classes

I'm trying to serialize data into / from my classes, derived from MonoBehaviour, which cannot be created from client code (e.g., with the new keyword), but rather must be created by a Unity3D-specific method, GameObject.AddComponent<T>(). How can I use the YamlDotNet framework to populate my classes with values without having to create an adapter for each one? Is there some sort of built-in adapter that I can configure, such that YamlDotNet doesn't instantiate the class it's trying to serialize to?
A typical file might contain a mapping of items, e.g.,
%YAML 1.1
%TAG !invt! _PathwaysEngine.Inventory.
%TAG !intf! _PathwaysEngine.Adventure.
---
Backpack_01: !invt!Item+yml
mass: 2
desc:
nouns: /^bag|(back)?pack|sack|container$/
description: |
Your backpack is only slightly worn, and...
rand_descriptions:
- "It's flaps twirl in the breeze."
- "You stare at it. You feel enriched."
MagLite_LR05: !invt!Lamp+yml
cost: 56
mass: 2
time: 5760
desc:
nouns: /^light|flashlight|maglite|lr_05$/
description: |
On the side of this flashlight is a label...
(Type "light" to turn it on and off.)
...
Where the tags are the fully specified class names of my Items, e.g., PathwaysEngine.Inventory.Lamp+yml, PathwaysEngine is the namespace I use for my game engine code, Inventory deals with items & whatnot, and Lamp+yml is how the compiler denotes a nested class, yml inside Lamp. Lamp+yml might look like this:
public partial class Lamp : Item, IWearable {
public new class yml : Item.yml {
public float time {get;set;}
public void Deserialize(Lamp o) {
base.Deserialize((Item) o);
o.time = time;
}
}
}
I call Deserialize() on all objects that derive from Thing from Awake(), i.e., once the MonoBehaviour classes exist in the game. Elsewhere, I've already created a pretty complicated Dictionary filled with objects of type Someclass+yml, and then Deserialize takes an instance of the real, runtime class Someclass and populates it with values. There's got to be a cleaner way to do this, right?
How can I:
Tell the Deserializer what my classes are?
See the second edit for a good solution for the above issue
Get the data without it attempting to create my MonoBehaviour-derived classes?
Edit: I've since worked at the problem, and have found out a good way of dealing with custom data (in my particular case of trying to parse regexes out of my data, and having them not be considered strings & therefore, un-castable to regex) is to use a IYamlTypeConverter for that particular string. Using YamlDotNet with Unity3D MonoBehaviours, however, is still an issue.
Another Edit: The above examples use a pretty ugly way of determining types. In my case, the best thing to do was to register the tags first with the deserializer, e.g.,
var pre = "tag:yaml.org,2002:";
var tags = new Dictionary<string,Type> {
{ "regex", typeof(Regex) },
{ "date", typeof(DateTime) },
{ "item", typeof(Item) }};
foreach (var tag in tags)
deserializer.RegisterTagMapping(
pre+tag.Key, tag.Value);
Then, I use the !!tag notation in the *.yml file, e.g.,
%YAML 1.1
---
Special Item: !!item
nouns: /thing|item|object/
someBoolean: true
Start Date: !!date 2015-12-17
some regex: !!regex /matches\s+whatever/
...
You can pass a custom implementation of IObjectFactory to the constructor of the Deserializer class. Every time the deserializer needs to create an instance of an object, it will use the IObjectFactory to create it.
Notice that your factory will be responsible for creating instances of every type that is deserialized. The easiest way to implement it is to create a decorator around DefaultObjectFactory, such as:
class UnityObjectFactory : IObjectFactory
{
private readonly DefaultObjectFactory DefaultFactory =
new DefaultObjectFactory();
public object Create(Type type)
{
// You can use specific types manually
if (type == typeof(MyCustomType))
{
return GameObject.AddComponent<MyCustomType>();
}
// Or use a marker interface
else if (typeof(IMyMarkerInterface).IsAssignableFrom(type))
{
return typeof(GameObject)
.GetMethod("AddComponent")
.MakeGenericMethod(type)
.Invoke();
}
// Delegate unknown types to the default factory
else
{
return DefaultFactory(type);
}
}
}

Scala - unbound wildcard exception (Play Framework 2.3 Template)

I am using Play Framework 2.3 I am using the scala template engine to create my views and Java elsewhere.
My model extends an abstract parameterised object like so... (pseudo code)
Abstract object:
public abstract class MyObject<T> {
// various bits
public class MyInnerObject {
// more stuff
}
}
Model object (singleton)
public class SomeModel extends MyObject<SomeBean> {
public static SomeModel getInstance() {
if (instance == null)
instance = new SomeModel();
return instance;
}
// more bits
}
I then pass the model to the view from another view helper:
#MyHelper(SomeModel.getInstance())
MyHelper scala view template:
#*******************************************
* My helper
*******************************************#
#(myObj: some.namespace.MyObject[_])
#import some.namespace.MyObject
#doSomething(myInnerObj: MyObject[_]#MyInnerObject) = {
#* do some stuff *#
}
#for(myInnerObj <- myObj.getInnerObjects()) {
#doSomething(myInnerObj)
}
However I get an error on the line #doSomething(myInnerObj: MyObject[_]#MyInnerObject) stating
unbound wildcard exception
I am not sure the correct Scala syntax to avoid this error I had naively assumed that I could use the _ to specify arbitrary tyope but it won't let me do this.
What is the correct syntax?
UPDATE 1
Changing the method definition to:
#doSomething[T](myInnerObj: MyObject[T]#MyInnerObject)
gives further errors:
no type parameters for method doSomething: (myInnerObj:[T]#MyInnerObject)play.twirl.api.HtmlFormat.Appendable exist so that it can be applied to arguments (myObj.MyInnerObject)
--- because ---
argument expression's type is not compatible with formal parameter type;
found : myObj.MyInnerObject
required: MyObject[?T]#MyInnerObject
It would seem that the Twirl templating engine does not support this syntax currently, although I'm not 100% sure.
I can solve the problem by removing the doSomething method completely...
#*******************************************
* My helper
*******************************************#
#(myObj: some.namespace.MyObject[_])
#import some.namespace.MyObject
#for(myInnerObj <- myObj.getInnerObjects()) {
<div>#myInnerObj.getSomeProperty()</div>
}
But I am bout 10% happy with the solution... It works at least but it feels very restricting that I cannot delegate to methods to help keep my code maintainable. By the look of the comments the problem seems to be a limitation in Twirl, not allowing type arguments for functions in views.
Note: I have accepted this answer as it removes the original problem of the exception however this is only because the solution I want doesn't exist... yet.

Dynamically evaluating code at runtime

Is it possible to take a string/AST of source code and evaluate it (like eval()) at runtime in Fantom? I found some suggesting features in the documentation but not obvious evidence.
It's not as easy as calling an eval() function, but it is possible. You need to first compile your Fantom code into a class before you can execute it.
Plastic, a library from Alien-Factory, does just that. Example:
using afPlastic
class Example {
Void main() {
eval("2 + 2") // --> 4
}
Obj? eval(Str code) {
model := PlasticClassModel("MyClass", true)
model.addMethod(Obj?#, "eval", "", code)
myType := PlasticCompiler().compileModel(model.toFantomCode)
return myType.make->eval()
}
}
The PlasticCompiler class does the job of compiling Fantom code into a usable Type.
It uses the Fantom compiler library and is based on code found in Fansh - a Fantom shell, part of the Fantom distribution.