ラベル

ラベル Lua の投稿を表示しています。 すべての投稿を表示
ラベル Lua の投稿を表示しています。 すべての投稿を表示

2010年7月21日水曜日

C++プログラマがLuaを勉強してみる第14回

テーブルは常に参照型です(キリッ
数値は参照型ではありません。
文字列は参照型かもしれませんが文字列を直接編集する事はできないので特に意識する事は無いと思います。

2010年7月20日火曜日

C++プログラマがLuaを勉強してみる第13回

◆C/C++からLuaを呼び出すためのライブラリをコンパイルしてみる
さて、今回はLua5.1.4とVisual Studio 2008を使ってライブラリをコンパイルしてみます。

STEP 1:ソースをダウンロード
まずはここからソースをダウンロードして解凍します。

STEP 2:Visual Studio 2008でプロジェクト作成
VC++でWin32プロジェクトを作成します。

 次にアプリケーションの設定をスタティックライブラリに設定します。

 完了します。

 STEP 3:srcの取り込み
ダウンロードしたlua-5.1.4.tar.gzを解凍してsrcフォルダSTEP 2で作成したプロジェクトの有るフォルダにコピーします。
srcフォルダ内の.cファイルと.hファイルをプロジェクトに取り込みます。
このとき下記のファイルは必要有りません。
  • lua.c
  • luac.c
  • print.c




STEP 4:プロジェクトの設定
プリプロセッサの定義に_CRT_SECURE_NO_DEPRECATEを追加します。

えーっとプロジェクトの設定とかあまり詳しくないので過不足あったらすいません。

STEP 4:ビルド

2010年7月19日月曜日

C++プログラマがLuaを勉強してみる第12回

◆C/C++からLuaを実行する
C++からLuaのコードを実行するサンプルをつくりました。
C++からLuaのコードを実行するためのライブラリ(lib)のコンパイルは後日紹介します。

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

int main(int argc, char* argv[])
{

 // LuaのVMを生成
 lua_State *const L = lua_open();

 // Luaの標準ライブラリを開く
 luaL_openlibs(L);

 while (true) {
  // luaファイルを指定して実行する
  if (luaL_dofile(L, "test.lua")) {
   // エラー内容の取得
   printf("error:%s\n", lua_tostring(L, -1));
   lua_pop(L, 1);
   return 0;
  }

  // 直接コードを指定する
  if (luaL_dostring(L, "print('hello lua world')")) {
   // エラー内容の取得
   printf("error:%s\n", lua_tostring(L, -1));
   lua_pop(L, 1);
   return 0;
  }

  printf("\n");
  printf("hit any key...\n");
  printf("0 is exit\n");
  const char c = getchar();
  if (c == '0') {
   break;
  }
 }

 // LuaのVMを閉じる
 lua_close(L);

 return 0;
}
getchar()のところでtest.luaを編集ご実行すると編集内容が反映されます。

2010年7月10日土曜日

C++プログラマがLuaを勉強してみる第11回

◆コルーチンによるタイマスレッドみたいなの
を作ってみました。
で、こんなの使うのだろうか。。。よくわかりませんw

isTimeout = false

--タイムアウトハンドラ
function timeOutHandler(_limit)
 isTimeout = true
end

--タイマコルーチン用関数
function timer(_limit, callBack)
 local limit = _limit --リミット
 local startTime = os.time() --開始時間
 local latest = os.time() --前回の時間
 local countDown = _limit --カウントダウン用

 print(countDown)
 while true do
  local time = os.time()
  if startTime + limit <= os.time() then
   break
  elseif latest < time then
   print(coroutine.status(co))
   latest = time
   countDown = countDown - 1
   print(countDown)
  end
  coroutine.yield() --コルーチンを中断して処理をもどす
 end
 callBack(limit) --コールバック関数を呼ぶ

end

co = coroutine.create(timer) --コルーチンの生成
print(coroutine.status(co)) --ステータスの表示

--メインループ
repeat
 coroutine.resume(co, 10, timeOutHandler) --コルーチンの開始と再開
until isTimeout

print(coroutine.status(co))
print("time out")

2010年7月9日金曜日

C++プログラマがLuaを勉強してみる第10回

◆Luaでテンプレートメソッドパターン
今回はLua初心者のくせにテンプレートメソッドパターンに挑戦してしまいました。
テンプレートメソッドパターンについてはここ参照
無理矢理感が否めないので、ぜんぜんちっげーよ!ってコメント待ってます!

まずは、簡単にクラス図の説明を書きます。
なんかどっかでみたよーな命名ですが気にしない気にしない
   CaffeineBeverageクラス(Superクラス)
               △
                |
   ----------------
   |                        |
Coffeeクラス      Teaクラス


以下ソースコード
CaffeineBeverage.lua
----------------------------------------
--CaffeineBeverageクラス
----------------------------------------
CaffeineBeverage = {}

-- new
function CaffeineBeverage:new(_caffeineBeverage)
 local obj = {}
 -- field
 if _caffeineBeverage then
  obj.name = _caffeineBeverage.name
 else
  obj.name = ""
 end

 self.__index = self
 setmetatable(obj, self)
 return obj
end

-- property
function CaffeineBeverage:set(_name)
 self.name = _name
end


-- __tostring over ride
function CaffeineBeverage:__tostring()
 return "name:"..self.name
end

-- clone
function CaffeineBeverage:clone()
 return CaffeineBeverage:new(self)
end

-- prepareRecipe
function CaffeineBeverage:prepareRecipe()
 CaffeineBeverage:boilWater()
 CaffeineBeverage:brew()
 CaffeineBeverage:pourInCup()
 CaffeineBeverage:addCondiments()
end

-- boilWater
function CaffeineBeverage:boilWater()
 print("お湯を沸かす。。。")
end

-- brew()
function CaffeineBeverage:brew()
 error("have to override")
end

-- pourInCup
function CaffeineBeverage:pourInCup()
 print("カップに注ぐ。。。")
end

-- addCondiments
function CaffeineBeverage:addCondiments()
 error("have to override")
end


Coffee.lua
dofile("CaffeineBeverage.lua") -- C/C++で言うところの#include

----------------------------------------
--Coffeeクラス
----------------------------------------
Coffee = {}

-- new
function Coffee:new(_coffee)
  obj = {}
 -- field
 if _coffee then
  obj = CaffeineBeverage:new(_coffee)
 else
  obj = CaffeineBeverage:new()
 end

 -- clone (override)
 obj.__index.brew = function()
  return Coffee:new(self)
 end

 -- brew (overrice)
 obj.__index.brew = function()
  print("コーヒーをドリップする")
 end

 -- addCondiments (override)
 obj.__index.addCondiments = function()
  print("砂糖とクリープを加える")
 end

 return obj
end


Tea.lua
dofile("CaffeineBeverage.lua")
----------------------------------------
--Teaクラス
----------------------------------------
Tea = {}

-- new
function Tea:new(_tea)
  obj = {}
 -- field
 if _tea then
  obj = CaffeineBeverage:new(_tea)
 else
  obj = CaffeineBeverage:new()
 end

 -- clone
 obj.__index.brew = function()
  return Tea:new(self)
 end

 -- brew
 obj.__index.brew = function()
  print("ティーバッグをお湯に浸す")
 end

 -- addCondiments
 obj.__index.addCondiments = function()
  print("砂糖とレモン")
 end

 return obj
end

main.lua
dofile("Coffee.lua")
dofile("Tea.lua")

----------------------------------------
-- main
----------------------------------------
function main()
 print("--コーヒーの生成")
 a = Coffee:new()
 a:set("コーヒー")
 print(a)
 a:prepareRecipe()

 print("\n")

 print("--紅茶の生成")
 b = Tea:new()
 b:set("紅茶")
 print(b)

 b:prepareRecipe()

 print("\n")

 print("--コピーコンストラクタの使用")
 c = Tea:new(b)
 print(c)
 c:set("レモンティ")
 print(c)
 print(b)

 print("\n")

 print("クローン")
 d = c:clone()
 print(d)
 d:set("レモンの紅茶")
 print(d)
 print(c)
end

-- call main
-- try catchみたいなの使ってます。
-- error()ってメソッドがthrowに相当します。
local status, err = pcall(main)
if status then
 -- do nothing
else
 print(err)
end

2010年7月8日木曜日

C++プログラマがLuaを勉強してみる第9回

◆関数定義時のピリオド「.」とコロン「:」の違い
コロンで定義した場合はselfが使用できます
ピリオドで定義した場合は引数にself(C++でいうところのthis)を取るとselfに自信が代入されます

test = {
 name = "yamada"
}

-- コロン
function test:printName() 
 print(self.name) -- selfにtestが入っている
end

-- ピリオドでselfの引数をもつ
function test.printName2(self)
 print(self.name) -- selfにtestが入っている
end

-- ピリオドでselfなし
function test.printName3()
-- print(self.name) -- selfは使用できない
 print("yamada")
end

2010年7月7日水曜日

C++プログラマがLuaを勉強してみる第8回

◆クラス

---------------------------------------
--Characterクラスの定義
---------------------------------------
Character = {} --Characterクラス

--newメソッド
function Character:new(_character)

 obj = {}
 --メンバ変数の定義と初期化
 if _character then
  --コピーコンストラクタ的な処理
  obj.name = _character.name
  obj.age = _character.age
 else
  --デフォルトコンストラクタ適な処理
  obj.name = ""
  obj.age = 0
 end

 --Characterのメソッドをobjに設定
 --継承みたいな感じ
 self.__index = self
 setmetatable(obj, self)
 return obj
end

--setメソッド
function Character:set(_name, _age)
 self.name = _name
 self.age = _age
end

--__tostringメタメソッドのオーバーライド
function Character:__tostring()
 return "name:"..self.name.."\n".."age:"..self.age
end

--cloneメソッド
function Character:clone()
 return Character:new(self)
end

----------------------------------------
--クラスの使用
----------------------------------------
c = Character:new() --オブジェクトの生成
c:set("suzuki", 12) --データの設定
d = Character:new(c) --コピーコンストラクタの使用

print("--c--")
print(c)
print("--d--")
print(d)
print("\n")

c:set("suzuki_2", 24)
d:set("yamada", 55)
print("==c==")
print(c)
print("==d==")
print(d)
print("\n")

e = d:clone()
d:set("takeda", 77)
print("##d##")
print(d)
print("##e##")
print(e)

2010年7月6日火曜日

C++プログラマがLuaを勉強してみる第7回

◆関数

--基本
function f(_arg)
    print(_arg)
end
f("Hello World")

f2 = function()
   print("Hello World2")
end
f2()

--数の合わない引数
function fu(_arg1, _arg2)
    print("_arg1:", _arg1)
    print("_arg2:", _arg2)
end
fu("Hello")
fu("Hello", "World")
fu("Hello", "World", "Hi")

--可変長引数
function fun(...)
    args = {...}
    for index, value in ipairs(args) do
        print(index, ":", value)
    end
end
fun("Hello", "World")

2010年7月5日月曜日

C++プログラマがLuaを勉強してみる第6回

◆制御構文

fouループ
for i = 1, 10 do
    print(i)
end

whileループ
while true do
    str = io.read()
    if str == "exit" then
        break
    else
        print(str)
    end
end

repeatループ
repeat
    i = i + 1
    print(i)
until 5 < i
if分岐
a = io.read() 
if a == 1 then
    a = a + 10
    print(a) 
elseif a == 2 then
    a = a + 20
    print(a) 
else
    print(a)
end

2010年7月3日土曜日

C++プログラマがLuaを勉強してみる第5回

◆連装配列

生成
t = {}
t = {["name"] = "apple", ["class"] = "mage", ["job"] = "blacksmith"}
t = {name = "apple", class = "mage", job = "blacksmith"}

追加
t = {}
t.name = "apple"
t.class = "mage"
t.job = "blacksmith"

削除
t.name = nil

反復(なめる)
for key, value in pairs(t) do
    print(value)
end

2010年7月2日金曜日

C++プログラマがLuaを勉強してみる第4回

◆配列

生成
t = {}
t = {"apple", "orange", "banana"}

追加
t[1] = "apple"
t[2] = "orange"
t[3] = "banana"
※Luaの添え字は「1」から始まります。

末尾に追加(push)
table.insert(t, "apple")
table.insert(t, "orange")
table.insert(t, "milk")

挿入
table.insert(t, 1, "apple")
table.insert(t, 2, "orange")
table.insert(t, 3, "orange")

削除
table.remove(t, index)

末尾から削除(pop)
table.remove(t)

サイズ(アイテム数)を取得する
#t
table.getn(t)

区切り文字で連結
table.concat(t) --> appleorangebanana
table.concat(t, ",") --> apple,orange,banana
table.concat(t, ",", 2, 3) --> orange,banana

ソート
function s(_a, _b)
    return _a < _b
end
table.sort(t, s)

反復(なめる)
t = { "apple", "orange", "banana"}
for index, value ipairs(t) do
    print(value)
end

for i = 1, #t do
    print(t[i])
end

2010年6月30日水曜日

C++プログラマがLuaを勉強してみる第3回

Luaのコメントは3種類あります

まずC++の//に相当する
-- コメント

続いて/**/に相当する
--[
    コメント
--]

最初の「--」の後ろに任意の文字を入れるとコメント解除扱いとなります。
 --![
    コメント
--]

最後は内部にコメントを含めることが出来る
--[=[
    コメント
]=]

「=」の数は一つでなくともかまいませんが、開始と終了の数を等しくする必要があります。

C++プログラマがLuaを勉強してみる第2回


Luaの演算子
演算子概要C++
+加算+
-減算-
*積算*
/除算/
%剰余%
^累乗^
..文字列連結+(STL)
and論理積&&
or論理和||
not否定!
<演算子の左より右が大きい<
<=演算子の左より右が同じか大きい<=
>演算子の左より右が小さい>
>=演算子の左より右が同じか小さい>=
==演算子の左と右が等しい==
~=演算子の左と右が異なる!=
#配列のサイズを求める該当演算子なし

2010年6月29日火曜日

C++プログラマがLuaを勉強してみる第1回

予約語

andbreakdoelseelseif
endfalseforfunctionif
inlocalnilnotor
repeatreturnthentrueuntil
while

and
論理積
C++:and、&&
例)A and B
注:A and Bが真となるときBの値が返されます。
hoge = A and B
の場合、hogeにはBの値が代入されます。

break
for、whileなどのループを抜ける
C++:break

do
do~whileのdo とはちょっと違います。
do~endでブロックとなります。
C++:{}の{

else
if~elseのelse
C++:else

elseif
if~elseifのelseif
C++:elseif

end
 ループの終了、ブロックの終了
C++:{}の}
例)for i = 0, 10 do hoge = hoge + i end

false

C++:false

for
ループ
C++:for

function
関数
C++:関数ポインタみたいな感じ。名無しの関数を定義できる

if
条件式
C++:if

in
 配列や連想配列を反復するのにつかう
C++:イテレータみたいなもの
例)
dict = { name = "snow", job="programer" }
for key, value in pairs(dict) do
    print(key..":"..value);

end
ループやブロックの終端
C++:}

local
ローカル変数Luaでは基本グローバル変数なのでローカル変数としたい場合はlocalをつける
C++:なし
例)local hoge

nil
未定義
C++:NULLとは違う

not
否定
C++:!ビックリマーク

or
 論理輪
C++:||、or
注:A or BにおいてAが真となるときAの値が返されます。
hoge = A or B
でAがtrue又はnil以外の全ての値の場合、hogeにはAの値が代入されます。

repeat
ループ
C++:なし
例)iが10になったらループを抜ける
repeat
    i = i + 1
    print(i)
until i == 10

return
 復帰
C++:return

then
if文で使用する
C++:{}の{
例)
if a == 3 then
    print(a)
end

true
 真
C++:true

until
 repeat文の条件式で成立したらループをぬける
C++:なし
例)iが10になったらループを抜ける
repeat
    i = i + 1
    print(i)
until i == 10

while
ループ
C++:while