JScript/HTML5 用自作ライブラリ Senko の紹介

ライブラリ制作
スポンサーリンク

はじめに

こんにちはー!なたでです!
以前から作っているライブラリを紹介したいと思います。

ソースコードを作ってだけだと何のライブラリか分からないですし、ドキュメントとして何かしら残しておくのも大事ですし。たまには、ライブラリの紹介というのも良いですよね!

というわけで、Senkoを熱く語りたいと思います。

※この記事を書いてから、ライブラリ自体が大きくなってきたため分岐しています。

2018/5/25に、Windowsで開発用のライブラリSenkoWSH、Node.js/HTML5用開発用のライブラリSenkoJSに分岐しました。さらに、2019/8/3にSenkoJSから数学専用ライブラリのkonpeito、日本語の文字列処理ライブラリのMojiJSに分岐しました。2019/11/14に、SenkoWSHはVer2系をリリースし、開発目的をVSCodeで開発できることを目指したライブラリとしました。

これらの事情からここに書いてあることは、古い情報となりますが、開発中の熱い思いが記載しているため残すこととします。

JScript向けライブラリSenkoWSHについての記事は、以下の記事を参照してください。元々はこの記事に記載していたように、Javaを意識した設計でしたが、変わりました(^O^)

Senkoライブラリとは

はじめに

どんなコードが書けるのか、雰囲気を伝えるために例をいくつか記載します(笑)

JScirptとして利用した場合の例

function main(args) {

	System.out.println("System.out.printlnで1行出力します");
	
	System.out.print("System.out.printで改行なしで出力します");

	System.out.println("System.currentTimeMillis で今の時間のミリ秒");
	System.out.println(System.currentTimeMillis() + "ms");
	
	System.out.println("System.sleep で指定した時間(ミリ秒)を待ちます");
	for(var i = 0; i < 10; i++) {
		System.sleep(100);
		System.out.println(System.currentTimeMillis() + "ms");
	}
	
	System.out.println("引数順指定");
	System.out.println(String.format("%%1$d %%2$d %%3$d [%1$d %2$d %3$d]" ,1 ,2 ,3 ));
	
	System.out.println("int型の乱数を 10個出力する");
	for(var i = 0;i < 10; i++) {
		System.out.println((new Random()).nextInt());
	}

	System.out.println("setText メソッドでテキストを保存します。");
	var text = "1234";
	var filename = "test.txt";
	var file = new File(filename);
	file.setText(text, "shift-jis");

	System.out.println("setScale による四捨五入のテスト");
	var x = new BigDecimal("0.5925");
	System.out.println(x);
	System.out.println("小数第一位で四捨五入:" + x.setScale(0, BigDecimal.ROUND_HALF_UP));

	System.out.println("ビット演算");
	var s1 = new BigInteger("1234ffffff0000000000", 16);
	var s2 = s1.negate();

}

HTML5として利用した場合の例1

function main(args) {
	
	System.out.println("SComponent クラスのサンプル");
	
	System.out.println("HTML での部品用のクラスです。");
	
	// パネルを作って、指定した ID の要素内に入れる。
	var panel = new SPanel();
	panel.putMe("component_test", SComponent.putype.IN);
	
	// ラベルを作って、パネルの中に入れる。
	var label1 = new SLabel("SComponentPutType.IN");
	panel.put(label1, SComponent.putype.IN);
	
	// obj2 は、 obj1 の右に配置する
	var label2 = new SLabel("SComponentPutType.RIGHT");
	label1.put(label2, SComponent.putype.RIGHT);
}

HTML5として利用した場合の例2

function main(args) {
	System.out.println("S3D クラスのサンプル");
	
	// 縦スクロール防止
	IDTools.noScroll();
	
	var panel;
	// パネルを作って、指定した ID の要素内に入れる。
	panel = new SCanvas();
	panel.putMe("scomponent", SComponent.putype.IN);
	panel.setUnit(SComponent.unittype.PX);
	panel.setPixelSize(640, 480);
	panel.setSize(640, 480);
	
	{
		var canvas = panel.getCanvas();
		
		var s3 = new S3System();
		var controller = new CameraController();
		var camera = s3.createCamera();
		s3.setCanvas(canvas);
		controller.setCanvas(canvas);
		s3.setSystemMode(S3System.SYSTEM_MODE.OPEN_GL);

		System.out.println("MQOでの入力テスト");
		var mesh = s3.createMesh();
		mesh.inputData("../resource/teapod.mqo", S3Mesh.DATA_MQO);

		var model = s3.createModel();
		model.setMesh(mesh);
		model.setScale(5);

		camera.setEye(new S3Vector( 20,  30,  50));
		camera.setCenter(new S3Vector( 0,  0,  0));
		controller.setCamera(camera);

		var scene = s3.createScene();
		scene.setCamera(camera);
		scene.addModel(model);

		var redraw = function() {
			scene.setCamera(controller.getCamera());
			s3.clear();
			model.addRotateY(3);
			s3.drawAxis(scene);
			s3.drawScene(scene);
		};

		setInterval(redraw, 50);

	}
}

HTML5として利用した場合の例3

function testInterpolation(panel) {
	
	panel.clear();
	
	var srcWidth  = 16;
	var srcHeight = 16;
	var dstWidth  = 256;
	var dstHeight = 256;
	
	// Button
	var gene = new SButton("画像作成");
	var genefunc = function() {
		var data = new ImgDataY();
		data.putImageData(inputcanvas.getImageData());
		data.forEach(function(color, x, y) {
			data.setPixelInside(x, y, color.random());
		});
		inputcanvas.putImageData(data.getImageData());
	};
	gene.addListener(genefunc);
	panel.put(gene, SComponent.putype.IN);
	
	// Canvas
	var inputcanvas = new SCanvas();
	var outputcanvas = new SCanvas();
	
	inputcanvas.setPixelSize(srcWidth, srcHeight);
	inputcanvas.setUnit(SComponent.unittype.PX);
	inputcanvas.setSize(srcWidth, srcHeight);
	genefunc();
	gene.put(inputcanvas, SComponent.putype.NEWLINE);
	
	
	var wrapmode = [
		ImgData.wrapmode.REPEAT,
		ImgData.wrapmode.CLAMP
	];
	var filtermode = [
		ImgData.filtermode.NEAREST_NEIGHBOR,
		ImgData.filtermode.BILINEAR,
		ImgData.filtermode.COSINE,
		ImgData.filtermode.HERMITE4_3,
		ImgData.filtermode.HERMITE4_5,
		ImgData.filtermode.HERMITE16,
		ImgData.filtermode.BICUBIC,
		ImgData.filtermode.BICUBIC_SOFT,
		ImgData.filtermode.BICUBIC_NORMAL,
		ImgData.filtermode.BICUBIC_SHARP
	];
	
	var cb_selectertype = new SComboBox(wrapmode);
	inputcanvas.put(cb_selectertype, SComponent.putype.NEWLINE);
	cb_selectertype.setWidth(16);
	
	var cb_interpolationtype = new SComboBox(filtermode);
	cb_selectertype.put(cb_interpolationtype, SComponent.putype.NEWLINE);
	cb_interpolationtype.setWidth(16);
	
	// Button
	var button = new SButton("拡大");
	cb_interpolationtype.put(button, SComponent.putype.NEWLINE);
	button.addListener(function() {
		var srcdata = new ImgDataY(inputcanvas.getImageData());
		srcdata.setWrapMode(cb_selectertype.getSelectedItem());
		srcdata.setFilterMode(cb_interpolationtype.getSelectedItem());
		var dstdata = new ImgDataY(dstWidth, dstHeight);
		dstdata.drawImgData(srcdata, 0, 0, dstWidth, dstHeight);
		outputcanvas.putImageData(dstdata.getImageData());
	});
	
	outputcanvas.setUnit(SComponent.unittype.PX);
	outputcanvas.setPixelSize(dstWidth, dstHeight);
	outputcanvas.setSize(dstWidth, dstHeight);
	button.put(outputcanvas, SComponent.putype.NEWLINE);
	outputcanvas.getContext().fillStyle = "rgb(0, 0, 0)";
	var size = outputcanvas.getPixelSize();
	outputcanvas.getContext().fillRect(0, 0, size.width, size.height);
	
};

なっ、なんじゃこりゃー!!

といった形のライブラリです。ててーん!

開発の歴史

初公開日は、2013年4月となります。当初は、「JScript サンプル」として紹介していました。

今でも作成目的の1つとなっておりますが、JScriptの勉強が行えること、よく利用されるようなスクリプトを公開しておけば、どこからでもコードを確認できるといったことが始まりです。

私は、もともとJava大好き人間でした。Javaは、どこの環境でも動くということと、C++みたいな自由度が高すぎて危険なコードをかけないこと、そしてEclipseが非常に使いやすかったことがあるためです。

ただ1つ問題がありまして、Javaで作ったものを実行するためには実行環境をインストールする必要があります。これが、結構厄介でして、旅先かどこかでちょっとしたプログラムを走らせたいといったときや、バッチ処理をちょっと行いたいというときに障害になっていました。

そこで、何か良いものがないのかなと目につけたのがJScriptです。当時、PowerShellという選択肢もあったのですが、文法が謎だったので、JScirptを極めるぞーというわけで使うことにしました。

まずやってみたのが、JScriptでJavaのような文法が、使えないのかなということを目標に調査を始めました。

それで、Javaでよく利用されるような HashMap、ArrayList に似たものを、JavaScriptで書くにはどうしたらいいのか勉強がてら、ライブラリを構築していきました。

数学系ライブラリの追加

作成していますと、JavaScriptにはまっていきました。コンパイルしなくてもすぐに実行できて、途中の値も簡単に編集や表示が可能で、お手軽なんです。

昔から作ってみたかったRandom や BigDecimal などの数学系のライブラリも充実させてみました。

とりあえず、これぐらいにはとどめていますが、虚数演算、行列演算、機械学習なども作っていきたいんですよね。

GitHubへ

5年前ほどからソースコード管理ソフトを使うようになりました。管理ソフトは非常に便利でして、どういった理由でこのコードの何行目を修正したのか簡単に過去に遡ることができるのです。というわけで、ライブラリの公開場所を2017年5月にGitHubに変更しました。

この時点で、バッチ処理でよく利用するような、ファイル処理に関しては大体できており、実用的ではあると思います。

HTML5機能の充実へ

JScript用でやってきたものの、実はJScriptにも残念な問題がありまして、デバッグ環境が貧相なんです。例えばエラーが発生しても、エラー行が見えずにすぐに閉じてしまったりするんです・・・。そのため、作成中はブラウザから実行して試験や確認してみました。ChromeとかIEだと、JSciprtの実行速度よりかなり早いですし、コンソールでちょっと実行して値に何が入るかもすぐに確認できます。

さらにGitHubには、GitHub Pagesというウェブサーバーを公開する機能もありまして、作成したサンプルコードがすぐに動くということもあり、Web機能用(HTML5)のライブラリへシフトしていきました。

というわけで、画像処理系や、GUI、3DCG、コントローラ系のライブラリも追加しています。

機能と特徴

書き方の雰囲気は、上のサンプルコードでつかめているとは思いますが、一応、2018年9月時点でSenkoWSHが持っている機能と特徴を解説します。

GitHub Pagesのサンプルコードを試してみれば、もっとわかると思います。

利用するためには

現状、JavaSciprtはECMAScript 6より古いコードで記載しています。つまり、import/exportなどは利用できず、使うためには、HTMLのヘッダで指定が必要です。この理由は、JScirptでの利用の互換性を考えているためです。いつか、JScirptは切るかもしれませんが、現状そのような制約があると覚えておいてください。

機能一覧

以下、主なファイルです。

基本的には、内部にファイル名と同一のクラスが記載されています。ファイル内でしか使用しないクラスは、ファイル内に定義されている場合もあります。

内容 ファイル名 解説
基本クラス System.js JScriptとして利用する場合は、これをincludeして下さい。
HTML5であれば、includeは任意です。
文字列操作 String.js 文字列操作です。
すでにあるStringを強化します。
基本的には、Javaにあるようなメソッドを追加します。
HTML5が登場して、別にすでにあるので不要かもしれません。
配列操作 ArrayList.js
HashMap.js
Byte.js
ArrayListと、HashMapは、コレクションとハッシュです。
Byteは、バイナリ型を扱うために作っていました。
HTML5が登場して、別にすでにあるので不要かもしれません。
ファイル操作 File.js ファイルの読み書きが可能です。
JScriptで利用する場合はブロッキング関数となります。また、JScriptでは1MB未満のファイルを扱うことを想定しています。それより大きなファイルを扱うと重たいので別の処理をさせましょう。
HTML5ではノンブロッキング用関数が用意されています。
Color.js 色を扱うクラスです。
GUI用のクラスなどで必要なクラスです。
数学用 BigInteger.js
BigDecimal.js
Random.js
任意精度演算、多倍長整数演算、ランダム生成用クラスです。
HTML5 UI SComponent.js
InputDevice.js
SComponent は、簡単にGUIを作れます。
実際に使用する場合は、CSSを組み合わせるのがよいでしょう。
InputDevice は、クリック/タッチなどを管理できます。
HTML5 画像処理 ImageProcessing.js 画像処理用クラスです。
オレンジビューアのコードをベースにしています。
HTML5 3DCG描写 S3D.js
S3DMath.js
S3DTools.js
S3DGL.js
S3DGL.fs
S3DGL.vs
S3DGLData.js
3DCG描写用クラスです。
S3DGLを利用すると、WebGLを使用した描写が可能となります。
アニメーションの対応予定はありません。

数学ライブラリは、konpeitoというライブラリ名で分離し、npmで公開しています。

文字列ライブラリは、MojiJSというライブラリ名で分離し。npmで公開しています。

ファイル構成

ファイル名 解説
README 説明書
toHTML5.wsf 現在のソースコードをHTML5用に変換する
toJScript.wsf 現在のソースコードをJScript用に変換する
docs GitHub Pages用
docs/applications SenkoWSHを利用したアプリケーション置き場
docs/library GitHub Pagesで利用するライブラリ置き場
docs/library/SenkoWSH SenkoWSH(実体)
docs/samples SenkoWSHを利用したサンプル集

SenkoWSHは、デフォルトではHTML5用のコードとなっています。HTML5用というのは、BOM付きutf-8コード(改行コードは\r)です。もしJScriptとして利用したい場合は、toJScript.wsfを実行してください。toJScript.wsfを実行すると、LittleEndianのutf-16コード(改行コードは\r\n)、UTF-16LEに変換されます。

utf-8がBOM付きというのは違和感があるかもしれませんが、wsfで正しく変換するためにはBOM付きでなければいけないのです。

ご了承ください。

ライセンス

docs/library内のSenkoWSHがライブラリ本体となっています。ライブラリ本体自体は、2018年9月現在で、zlibライセンスとなっています。

zlibライセンスは、Wikipediaに詳しく記載されています。表示義務はないですが、ライセンスの部分を故意に消してはいけないといった形のライセンスです。

なお、「docs/samples」内はサンプルコードなので、NYSL 0.9982としています。

コードの書き方について

一応、サンプルコードで全ての機能を羅列させようと考えておりますので、とりあえずは、サンプルコードを確認してください。使用方法は、また別記事で紹介できればいいかなと思います。

おわりに

最後まで読んでいただきありがとうございます!

現状安定版といったものを作成する予定はありませんが、興味がありましたらサンプルを見てみて、使ってみていただけると嬉しいです!

以上、おつかれさまでしたー!

現在は、別のライブラリとして開発しています。詳細はこの記事の上を参照してください。

コメント

タイトルとURLをコピーしました