Looking for some direction and help. I am new to JavaScript and NodeJS and have not been able to find anything online on how to do this. I've written a minesweeper game in JavaScript and would like to be able to inject user written code into the game loop instead of taking inputs.
The main problem I am running into is getting access to the methods I've built into the game class. Here's the code.
class Game {
constructor() {
this.GameBoard = new MineSweeperBoard(true);
autoBind(this);
}
pop(x ,y){
this.GameBoard.pop(x, y);
}
flag(x, y){
this.GameBoard.flag(x,y);
}
removeFlag(x,y){
this.GameBoard.RemoveFlag(x,y);
}
checkWin(){
this.GameBoard.CheckForWin();
}
getGameBoard(){
return this.GameBoard.GetRevealedGameBoard()
}
}
function StartGame() {
let CurrentGame = new Game();
let win = false;
while(CurrentGame.GameBoard.RunGame) {
//User Code here
*User written code should run right about here.*
// Check win condition
if(CurrentGame.checkWin()){
win = true;
}
}
Any help or direction would be appreciated.
*** Edit ***
To answer some question that have been asked.
1: This isn't secure: Yes I understand there are potential security implications to running user generated code. As of right now that is not a concern as this is mostly a proof of concept.
2: Why do I want to do this: Because I want to see if it's possible and I know others have found ways to securely run user code (i.e. Screeps). Right now I would like to see what is possible.
Edit: I've redacted actual numbers and replaced them with pseudoswears because I've been told sharing performance data is against Netsuite's TOS.
I'm integrating our accounting system with NetSuite using restlets, and overall it has gone pretty well with the glaring exception of performance. I have figured out that nlapiLoadRecord is Satan's own child from a performance perspective, so I avoid it whenever possible favoring the search api and now my read restlets are pretty snappy. However, whenever I ask a restlet to write anything it is as slow as a tortoise stuck in cold tar. I'm generally profiling the nlapiSubmitRecord itself at between SLOW and REALLY DAMN SLOW seconds. This seems insane to me. No one would use NetSuite if the performance were always this poor for writing. I'll include a couple of code examples below. Any tips on speeding up NetSuite restlet write performance would be appreciated.
In this first one receivedInvoice is the incoming data, and findCurrencyCode and findCustomerByCustomerNumber are well performing functions that do those things. I just clocked this at a nearly unbelievable HOLY MONKEYS THAT IS SLOW seconds for a simple invoice with one line item, nearly all of the time passing while I waited for nlapiSubmitRecord to finish.
var createdInvoice = nlapiCreateRecord('invoice');
createdInvoice.setFieldValue('customform', Number(receivedInvoice.transactionType));
createdInvoice.setFieldValue('memo', receivedInvoice.message);
createdInvoice.setFieldValue('duedate', receivedInvoice.dateDue);
createdInvoice.setFieldValue('currency', findCurrencyCode(receivedInvoice.currencyUnit));
createdInvoice.setFieldValue('location', Number(receivedInvoice.location));
createdInvoice.setFieldValue('postingperiod', findPostingPeriod(receivedInvoice.datePosted));
var customer = findCustomerByCustomerNumber(receivedInvoice.customerNumber);
createdInvoice.setFieldValue('entity', customer.customerId );
createdInvoice.setFieldValue('custbody_end_user', customer.customerId );
createdInvoice.setFieldValue('department', customer.departmentId);
var itemCount = receivedInvoice.items.length;
for(var i = 0; i < itemCount; i++)
{
createdInvoice.selectNewLineItem('item');
createdInvoice.setCurrentLineItemValue('item', 'item',receivedInvoice.items[i].item);
createdInvoice.setCurrentLineItemValue('item', 'quantity', receivedInvoice.items[i].quantity);
createdInvoice.setCurrentLineItemValue('item', 'rate',receivedInvoice.items[i].price);
createdInvoice.setCurrentLineItemValue('item', 'custcol_list_rate',receivedInvoice.items[i].price);
createdInvoice.setCurrentLineItemValue('item', 'amount',receivedInvoice.items[i].totalAmount);
createdInvoice.setCurrentLineItemValue('item', 'description',receivedInvoice.items[i].description);
createdInvoice.commitLineItem('item');
}
var recordNumber = nlapiSubmitRecord(createdInvoice,false,true);
In this one I think I'm committing a performance heresy by opening the record in dynamic mode, but I'm not sure how else to get the possible line items. Simply opening a new record in dynamic mode clocks in at around SLOW seconds. Again, the submit is where most time is being eaten (often around OH DEAR SWEET MOTHER OF HORRIBLE seconds), although this one eats a decent amount of time as I mess with the line items, again presumably because I have opened the record in dynamic mode.
var customerPayment = nlapiCreateRecord('customerpayment',{recordmode: 'dynamic'});
customerPayment.setFieldValue('customer', parseInt(customerId));
customerPayment.setFieldValue('payment', paymentAmount);
customerPayment.setFieldValue('paymentmethod', paymentMethod);
customerPayment.setFieldValue('checknum', transactionId);
customerPayment.setFieldValue('currency', currency);
customerPayment.setFieldValue('account', account);
var applyCount = customerPayment.getLineItemCount('apply');
if(applyCount>0)
{
for(var i=1;i<=applyCount;i++)
{
var thisInvoice = customerPayment.getLineItemValue('apply','refnum',i);
if(thisInvoice == invoiceToPay)
{
customerPayment.selectLineItem('apply', i);
customerPayment.setCurrentLineItemValue('apply','apply','T');
customerPayment.setCurrentLineItemValue('apply', 'amount',paymentAmount);
customerPayment.commitLineItem('apply');
}
}
}
nlapiSubmitRecord(customerPayment,false,true);
A few thoughts:
(just to get it off my chest) Integrating your accounting system with Netsuite just sounds odd. Netsuite is an accounting system and generally is the accounting system of record for the orgs that use it. If you are not using Netsuite for accounting you might want to consider what utility it has for the price and get off it.
When I integrate an external system with Netsuite I generally try to make it async. I do this by getting the raw info into a custom record and then kick off a scheduled script to process the queued update. This lets my api return quickly. When I process the queue I store errors in the queue record so that if anything comes up I can fix the data or code and re-submit it.
One apparently major source of slow transaction submit (aside from slow UE scripts) is the state of your books. I had a startup customer who did really well but they never closed their books and they were using IIRC Average Costing. Every time they saved a posting transaction Netsuite was recalculating the whole period (which at the point where things were grinding to a halt was about 2 years of records for a very busy site). When they started closing periods transaction save times went way down. When they converted to standard costing transaction save times went down again (I imagine LIFO would be faster than Avg and slower than standard but YMMV)
Also notes on your code.
The normal way to create an invoice is
nlapiTransformRecord('customer', customer.customerId, 'invoice'); or
nlapiTransformRecord('customer', customer.customerId, 'invoice', {recordmode:'dynamic'});
I've never tested whether this has an effect on submit times but it might help since NS will start the save from a slightly better place (grasping at straws but with NS sometimes non-obvious changes have speed benefits)
Also not sure how changing the customform in dynamic mode works. When you know the form you can also add that to the init defaults:
{recordmode:'dynamic', customform:receivedInvoice.transactionType}
One of the reasons why you Submit is slow might be there are a lot of User Event scripts attached to the record. Since it is the Restlet that saves the record, it will trigger the User Event scripts.
I really stuck at this stage. I do not know how to implement this feature. What i thought was to hide the whole divs which contain the appropriate statuses (online, offline, all). I know that there are a lot intelligent ways to do it. However, because i'm beginner i cannot get it done. Please experienced programmers help me out or please give me your valuable tips.
Code which kind of "responsible" this feature.
$('#myForm input').on('change', function() {
var spanStatus = document.querySelector("span");
var status = $('input[name=status]:checked', '#myForm').val();
for (var i=0; i<spanStatus.length; i++) {
if (status=="offline") {
//$("div").not("#status-toggle").hide();
jQuery('span').parent().parent().hide();
}
console.log(spanStatus);
}
I know my code it total mess. Nevertheless this is link to my pen. Do not be scared please i promise to improve my coding every day.
I am actually really hoping this is a noob question. Have looked around and tried for about an hour for a solution to this but I'm getting nowhere.
Real simple. I am using Cordova to build Android App. I am going through my code and trying to clean it up and make it more reusable.
I have several views/pages that play audio files. I am using the Cordova media api as HTML5 audio is not well supported.
Anyway, I use JQuery to get the ID of heading tag and then combine it with another string to make a variable. Then I am trying to use that variable to be the source for a "new Media" object. I am definitely missing something here, because it is not working and is returning null. My code is pasted below:
var playing = 0;
var myMedia = null;
var mySound = $("h3").attr("id");
var soundPath = "/android_asset/www/audio/"+mySound+".mp3";
myMedia = new Media('"'+soundPath+'"', stopAudio);
function playAudio() {
switch (playing) {
case 0:
myMedia.play();
document.getElementById('play').src = "../icons/pause-btn-grey#2x.png";
playing = 1;
break;
case 1:
myMedia.pause();
document.getElementById('play').src = "../icons/play-btn-grey#2x.png";
playing = 0;
break;
}
I would really appreciate if someone could point me in the right direction. I am sure it is something I have overlooked but cannot "see the wood from the trees".
I'm playing with the webkit Audio API and I'm trying to create an Echo effect, to accomplish that I've connected a DelayNode with a GainNode in a loop (The output of one is the input of the other, and viceversa).
The effect works fine, but now I want to create an EchoNode Object that I can just plug-in and connect with the other AudioNode objects.
Something like:
myEchoNode = new EchoNode();
myConvolverNode = context.createConvolver();
myConvolverNode.connect(myEchoNode);
I think that I should make my EchoNode inherit from AudioNode, so that the connect function of every other AudioNode would work, but I don't know how to do that in Javascript with the web Audio API.
Can anyone give me a hint, or if you think that there is a better way to accomplish that I would greatly appreciate it.
Thanks
Oskar's solution should do the trick, but I want to point out that it will require you to connect to your EchoNode in a nonstandard way (using EchoNode.input rather than simply connecting to the EchoNode itself). For simple effects such as feedback delay, this can be avoided by creating the EchoNode via a factory function that returns a native DelayNode mixed with some extra properties. Here's an example from SynthJS:
function FeedbackDelayNode(context, delay, feedback){
this.delayTime.value = delay;
this.gainNode = context.createGainNode();
this.gainNode.gain.value = feedback;
this.connect(this.gainNode);
this.gainNode.connect(this);
}
function FeedbackDelayFactory(context, delayTime, feedback){
var delay = context.createDelayNode(delayTime + 1);
FeedbackDelayNode.call(delay, context, delayTime, feedback);
return delay;
}
AudioContext.prototype.createFeedbackDelay = function(delay, feedback){
return FeedbackDelayFactory(this, delay, feedback);
};
As you can see, the result is a native DelayNode that can be connected to other nodes in the standard fashion, but it has an attached gain node that provides the feedback effect.
Have a look at this article I wrote, it might give you some ideas: http://www.html5rocks.com/en/tutorials/casestudies/jamwithchrome-audio/ (which explains the basic idea behind tuna.js that Taoist recommended).