Ti.Include to CommonJS for a beginner - titanium

So now that Ti.include is deprecated, I am forced to face the fact that I do not know the correct way to handle commonJS and require.
I have read and re-read many of the posts on SO and elsewhere but still cannot make sense of the syntax. I suspect it is because my original code is somewhat hackish to begin with.
Can anybody help by looking at the small code below and helping me translate it into commonJS?
In the document that contains the current Ti.Include I need to get to the variables dp and ff.
var dp = "";
if (Titanium.Platform.Android) {
dp = (Ti.Platform.displayCaps.dpi / 160);
} else {
dp = 1;
}
var version = Titanium.Platform.version.split(".");
version = version[0];
if (Titanium.Platform.displayCaps.platformWidth == '320') {
ff = 0;
} else if (Titanium.Platform.displayCaps.platformWidth == '768') {
ff = 3;
} else {
ff = 1;
}
Thank you all.

something like this will do.
Create a file named dpAndFfModule.js and place under the lib folder inside your project.
exports.getDp = function () {
var dp = "";
if (Titanium.Platform.Android) {
dp = (Ti.Platform.displayCaps.dpi / 160);
} else {
dp = 1;
}
return dp;
};
exports.getFf = function () {
var version = Titanium.Platform.version.split(".");
version = version[0];
var ff;
if (Titanium.Platform.displayCaps.platformWidth == '320') {
ff = 0;
} else if (Titanium.Platform.displayCaps.platformWidth == '768') {
ff = 3;
} else {
ff = 1;
}
return ff;
};
now inside .js files you need to require the module like this:
var dpAndFf = require('dpAndFfModule'); //you pass the filename (without extention) to require funciton.
dpAndFf.getDp(); // this executes the getDp function and returns your dp.
dpAndFf.getFf(); // same, executes getFf function and returns the result.

Related

Photoshop Scripting: Relink Smart Object

I'm working on a script that should go through a photoshop document and relink all visible linked objects to a new specified file. I've gotten the loop working so that it cycles through every layer and collects only the visible layers, but for the life of me I can't find if there's a method available to relink a smart object. The closest I've found is this script:
https://gist.github.com/laryn/0a1f6bf0dab5b713395a835f9bfa805c
but when it gets to desc3.putPath(idnull, new File(newFile));, it spits out an error indicating that the functionality may not be present in the current Photoshop version. The script itself is 4 years old so it may be out of date.
Any help would be appreciated!
MY script as it stands is below:
// SELECT FILE //
var files = File.openDialog("Please select new linked file");
var selectedFile = files[0];
// GET ALL LAYERS //
var doc = app.activeDocument;
var allLayers = [];
var allLayers = collectAllLayers(doc, allLayers);
function collectAllLayers (doc, allLayers)
{
for (var m = 0; m < doc.layers.length; m++)
{
var theLayer = doc.layers[m];
if (theLayer.typename === "ArtLayer")
{
allLayers.push(theLayer);
}
else
{
collectAllLayers(theLayer, allLayers);
}
}
return allLayers;
}
// GET VISIBLE LAYERS //
var visibleLayers = [];
for (i = 0; i < allLayers.length; i++)
{
var layer = allLayers[i];
if (layer.visible && layer.kind == LayerKind.SMARTOBJECT)
{
visibleLayers.push(layer);
}
}
// REPLACE LAYERS
for (i = 0; i < visibleLayers.length; i++)
{
var layer = visibleLayers[i];
//--> REPLACE THE FILE HERE
}
Note: I am aware that this script currently may be error-prone if you don't know exactly how it works; I'm not intending to publish it at this time so I'm not super concerned with that at the moment. Mostly I just need the core functionality to work.
I used an AM function for getting visible smart objects — it works much faster. But if you want you can use yours. The important bit is relinkSO(path);: it'll also work in your script (just don't forget to select a layer: activeDocument.activeLayer = visibleLayers[i];)
Note that it works similar to Photoshop Relink to File command — if used on one instance of Smart Object all the instances are going to be relinked. If you want to relink only specific layers you'll have to break instancing first (probably using the New Smart Object via Copy command)
function main() {
var myFile = Folder.myDocuments.openDlg('Load file', undefined, false);
if (myFile == null) return false;
// gets IDs of all smart objects
var lyrs = getLyrs();
for (var i = 0; i < lyrs.length; i++) {
// for each SO id...
// select it
selectById(lyrs[i]);
// relink SO to file
relinkSO(myFile);
// embed linked if you want
embedLinked()
}
function getLyrs() {
var ids = [];
var layers, desc, vis, type, id;
try
{
activeDocument.backgroundLayer;
layers = 0;
}
catch (e)
{
layers = 1;
}
while (true)
{
ref = new ActionReference();
ref.putIndex(charIDToTypeID('Lyr '), layers);
try
{
desc = executeActionGet(ref);
}
catch (err)
{
break;
}
vis = desc.getBoolean(charIDToTypeID("Vsbl"));
type = desc.getInteger(stringIDToTypeID("layerKind"));
id = desc.getInteger(stringIDToTypeID("layerID"));
if (type == 5 && vis) ids.push(id);
layers++;
}
return ids;
} // end of getLyrs()
function selectById(id) {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID('Lyr '), id);
desc.putReference(charIDToTypeID('null'), ref);
executeAction(charIDToTypeID('slct'), desc, DialogModes.NO);
} // end of selectById()
function relinkSO(path) {
var desc = new ActionDescriptor();
desc.putPath( charIDToTypeID('null'), new File( path ) );
executeAction( stringIDToTypeID('placedLayerRelinkToFile'), desc, DialogModes.NO );
} // end of relinkSO()
function embedLinked() {
executeAction( stringIDToTypeID('placedLayerConvertToEmbedded'), undefined, DialogModes.NO );
} // end of embedLinked()
}
app.activeDocument.suspendHistory("relink SOs", "main()");

Run last Photoshop script (again)

This seems like a trivial issue but I'm not sure Photoshop supports this type of functionality:
Is it possible to implement use last script functionality?
That is without having to add a function on each and every script that writes it's filename to a text file.
Well... It's a bit klunky, but I suppose you could read in the scriptlistener in reverse order and find the first mention of a script file:
// Switch off any dialog boxes
displayDialogs = DialogModes.NO; // OFF
var scripts_folder = "D:\\PS_scripts";
var js = "C:\\Users\\GhoulFool\\Desktop\\ScriptingListenerJS.log";
var jsLog = read_file(js);
var lastScript = process_file(jsLog);
// use function to call scripts
callScript(lastScript)
// Set Display Dialogs back to normal
displayDialogs = DialogModes.ALL; // NORMAL
function callScript (ascript)
{
eval('//#include "' + ascript + '";\r');
}
function process_file(afile)
{
var needle = ".jsx";
var msg = "";
// Let's do this backwards
for (var i = afile.length-1; i>=0; i--)
{
var str = afile[i];
if(str.indexOf(needle) > 0)
{
var regEx = str.replace(/(.+new\sFile\(\s")(.+\.jsx)(.+)/gim, "$2");
if (regEx != null)
{
return regEx;
}
}
}
}
function read_file(inFile)
{
var theFile = new File(inFile);
//read in file
var lines = new Array();
var l = 0;
var txtFile = new File(theFile);
txtFile.open('r');
var str = "";
while(!txtFile.eof)
{
var line = txtFile.readln();
if (line != null && line.length >0)
{
lines[l++] = line;
}
}
txtFile.close();
return lines;
}

realm react-native: how to query correctly an array of strings

can someone show me how to query an array of strings with realm in react-native?
assume i have an array like the following:
const preferences = ["automatic","suv","blue",eco]
What I want is to get realm results where ALL strings in the attribute "specifications" of Cars is in "preferences".
E.g.: If an instance of Cars.specifications contains ["automatic","suv"]
a result should be returned.
But if an instance of Cars.specifications contained ["automatic,"suv","green"] this instance shouldn't be returned.
The length of preferences can vary.
Thank you very much.
Update:
What i tried is the following:
const query = realm.objects("Cars").filtered('specifications = preferences[0] OR specifications = preferences[1]')
As you see it is an OR operator which is surely wrong and it is hardcoded. Looping with realm really confuses me.
This code will work!
const collection = realm.objects('Cars');
const preferences = ["automatic","suv","blue","eco"];
let queryString = 'ANY ';
for (let i = 0; i < preferences.length; i++) {
if (i === 0) {
queryString += `specifications CONTAINS '${preferences[i]}'`;
}
if (i !== 0 && i + 1 <= preferences.length) {
queryString += ` OR specifications CONTAINS '${preferences[i]}'`;
}
}
const matchedResult = collection.filtered(queryString);
example of function to test if a word is inside an array of word
function inArray(word, array) {
var lgth = array.length;
word = word.toLowerCase();
for (var i = 0; i < lgth; i++) {
array[i] = (array[i]).toLowerCase();
if (array[i] == word) return true;
}
return false;
}
const preferences = ["automatic","suv","blue","eco"];
const specifications = ["automatic","suv"] ;
const specifications2 = ["automatic","suv", "boat"] ;
function test(spec,pref){
for (var i in spec){
if(!inArray(spec[i],pref)){
return false ;
}
}
return true;
}
console.log(test(specifications,preferences));
console.log(test(specifications2,preferences));
https://jsfiddle.net/y1dz2gvu/

Variable Assignment Issues

Good Day Everyone, I am working on a script and it works really well, but there is just this one error that i just cannot figure out. What am i overlooking? I will post the error and code below.
Here is the error:
UnassignedReferenceException: The variable gameOverScore of Score has not been assigned.
You probably need to assign the gameOverScore variable of the Score script in the inspector.
Score.Start () (at Assets/2dspaceshooter/Scripts/Score.js:10)
Here is the script:
#pragma strict
var gameOverScore:GUIText;
var gameGUI:GameObject;
private var score:int = 0;
private var isGameOver = false;
function Start () {
gameOverScore.guiText.enabled = false;
guiText.text = "Score: " + score.ToString();
}
function addScore () {
if(!isGameOver){
score += 10;
guiText.text = "Score: " + score.ToString();
}
}
function doGameOver () {
isGameOver = true;
gameGUI.SetActive(false);
guiText.text = null;
gameOverScore.guiText.enabled = true;
gameOverScore.guiText.text = "Score: "+score;
}
Not that I really recognize your script as simple JavaScript, but it may be that you confuse an object Score with the lower case version score

JScript.NET private variables

I'm wondering about JScript.NET private variables. Please take a look on the following code:
import System;
import System.Windows.Forms;
import System.Drawing;
var jsPDF = function(){
var state = 0;
var beginPage = function(){
state = 2;
out('beginPage');
}
var out = function(text){
if(state == 2){
var st = 3;
}
MessageBox.Show(text + ' ' + state);
}
var addHeader = function(){
out('header');
}
return {
endDocument: function(){
state = 1;
addHeader();
out('endDocument');
},
beginDocument: function(){
beginPage();
}
}
}
var j = new jsPDF();
j.beginDocument();
j.endDocument();
Output:
beginPage 2
header 2
endDocument 2
if I run the same script in any browser, the output is:
beginPage 2
header 1
endDocument 1
Why it is so??
Thanks,
Paul.
Just a guess, but it appears that JScript.NET doesn't support closures the same way as EMCAScript, so the state variable in endDocument() isn't referencing the private member of the outer function, but rather an local variable (undeclared). Odd.
You don't have to use new when calling jsPDF here since you're using a singleton pattern. jsPDF is returning an object literal so even without new you'll have access to the beginPage and endDocument methods. To be perfectly honest I don't know what the specifications call for when using new on a function that returns an object literal so I'm not sure if JScript.NET is getting it wrong or the browser. But for now try either getting rid of the new before jsPDF() or change your function to this:
var jsPDF = function(){
var state = 0;
var beginPage = function(){
state = 2;
out('beginPage');
};
var out = function(text){
if(state == 2){
var st = 3;
}
MessageBox.Show(text + ' ' + state);
};
var addHeader = function(){
out('header');
};
this.endDocument = function(){
state = 1;
addHeader();
out('endDocument');
};
this.beginDocument: function(){
beginPage();
};
}
That will allow you to use the new keyword and create more than one jsPDF object.
I've come across the same problem. In the following code, the closure bound to fun should contain only one variable called result. As the code stands, the variable result in the function with one parameter seems to be different to the result variable in the closure.
If in this function the line
result = [];
is removed, then the result in the line
return result;
refers to the result in the closure.
var fun = function() {
var result = [];
// recursive descent, collects property names of obj
// dummy parameter does nothing
var funAux = function(obj, pathToObj, dummy) {
if (typeof obj === "object") {
for (var propName in obj) {
if (obj.hasOwnProperty(propName)) {
funAux(obj[propName], pathToObj.concat(propName), dummy);
}
}
}
else {
// at leaf property, save path to leaf
result.push(pathToObj);
}
}
return function(obj) {
// remove line below and `result' 3 lines below is `result' in closure
result = []; // does not appear to be bound to `result' above
funAux(obj, [], "dummy");
return result; // if result 2 lines above is set, result is closure is a different variable
};
}();