Răsfoiți Sursa

Added Lua Chat sample.

Aster Jian 12 ani în urmă
părinte
comite
472a2b9bd9
2 a modificat fișierele cu 257 adăugiri și 31 ștergeri
  1. 217 0
      Bin/Data/LuaScripts/16_Chat.lua
  2. 40 31
      Source/Extras/LuaScript/pkgs/Core/Variant.pkg

+ 217 - 0
Bin/Data/LuaScripts/16_Chat.lua

@@ -0,0 +1,217 @@
+-- Chat example
+-- This sample demonstrates:
+--     - Starting up a network server or connecting to it
+--     - Implementing simple chat functionality with network messages
+
+require "LuaScripts/Utilities/Sample"
+
+-- Identifier for the chat network messages
+local MSG_CHAT = 32
+-- UDP port we will use
+local CHAT_SERVER_PORT = 2345
+
+local chatHistory = {}
+local chatHistoryText = nil
+local buttonContainer = nil
+local textEdit = nil
+local sendButton = nil
+local connectButton = nil
+local disconnectButton = nil
+local startServerButton = nil
+
+local context = GetContext()
+
+local cache = GetCache()
+local input = GetInput()
+local graphics = GetGraphics()
+local network = GetNetwork()
+local renderer = GetRenderer()
+local ui = GetUI()
+
+function Start()
+    -- Execute the common startup for samples
+    SampleStart()
+
+    -- Enable OS cursor
+    input.mouseVisible = true
+
+    -- Create the user interface
+    CreateUI()
+    
+    -- Subscribe to UI and network events
+    SubscribeToEvents()
+end
+
+function CreateUI()
+    SetLogoVisible(false) -- We need the full rendering window
+
+    local uiStyle = cache:GetResource("XMLFile", "UI/DefaultStyle.xml")
+    -- Set style to the UI root so that elements will inherit it
+    ui.root.defaultStyle = uiStyle
+
+    local font = cache:GetResource("Font", "Fonts/Anonymous Pro.ttf")
+    chatHistoryText = ui.root:CreateChild("Text")
+    chatHistoryText:SetFont(font, 12)
+
+    buttonContainer = ui.root:CreateChild("UIElement")
+    buttonContainer:SetFixedSize(graphics.width, 20)
+    buttonContainer:SetPosition(0, graphics.height - 20)
+    buttonContainer.layoutMode = LM_HORIZONTAL
+    
+    textEdit = buttonContainer:CreateChild("LineEdit")
+    textEdit:SetStyleAuto()
+    
+    sendButton = CreateButton("Send", 70)
+    connectButton = CreateButton("Connect", 90)
+    disconnectButton = CreateButton("Disconnect", 100)
+    startServerButton = CreateButton("Start Server", 110)
+
+    UpdateButtons()
+
+    -- chatHistory.Resize((graphics.height - 20) / chatHistoryText.rowHeight)
+
+    -- No viewports or scene is defined. However, the default zone's fog color controls the fill color
+    renderer.defaultZone.fogColor = Color(0.0, 0.0, 0.1)
+end
+
+function SubscribeToEvents()
+    -- Subscribe to UI element events
+    SubscribeToEvent(textEdit, "TextFinished", "HandleSend")
+    SubscribeToEvent(sendButton, "Released", "HandleSend")
+    SubscribeToEvent(connectButton, "Released", "HandleConnect")
+    SubscribeToEvent(disconnectButton, "Released", "HandleDisconnect")
+    SubscribeToEvent(startServerButton, "Released", "HandleStartServer")
+
+    -- Subscribe to log messages so that we can pipe them to the chat window
+    SubscribeToEvent("LogMessage", "HandleLogMessage")
+    
+    -- Subscribe to network events
+    SubscribeToEvent("NetworkMessage", "HandleNetworkMessage")
+    SubscribeToEvent("ServerConnected", "HandleConnectionStatus")
+    SubscribeToEvent("ServerDisconnected", "HandleConnectionStatus")
+    SubscribeToEvent("ConnectFailed", "HandleConnectionStatus")
+end
+
+function CreateButton(text, width)
+    local font = cache:GetResource("Font", "Fonts/Anonymous Pro.ttf")
+    
+    local button = buttonContainer:CreateChild("Button")
+    button:SetStyleAuto()
+    button:SetFixedWidth(width)
+
+    local buttonText = button:CreateChild("Text")
+    buttonText:SetFont(font, 12)
+    buttonText:SetAlignment(HA_CENTER, VA_CENTER)
+    buttonText.text = text
+    
+    return button
+end
+
+function ShowChatText(row)
+    --chatHistory:Erase(0)
+    --chatHistory:Push(row)
+    table.remove(chatHistory, 0)
+    table.insert(chatHistory, row)
+    
+    -- Concatenate all the rows in history
+    local allRows = ""
+    for i, r in ipairs(chatHistory) do
+        allRows = allRows .. r .. "\n"
+    end
+    chatHistoryText.text = allRows
+end
+
+function UpdateButtons()
+    local serverConnection = network.serverConnection
+    local serverRunning = network.serverRunning
+    
+    -- Show and hide buttons so that eg. Connect and Disconnect are never shown at the same time
+    sendButton.visible = serverConnection ~= nil
+    connectButton.visible = (serverConnection == nil) and (not serverRunning)
+    disconnectButton.visible = (serverConnection ~= nil) or serverRunning
+    startServerButton.visible = (serverConnection == nil) and (not serverRunning)
+end
+
+function HandleLogMessage(eventType, eventData)
+    ShowChatText(eventData:GetString("Message"))
+end
+
+function HandleSend(eventType, eventData)
+    local text = textEdit.text
+    if text == "" then
+        return -- Do not send an empty message
+    end
+
+    local serverConnection = network.serverConnection
+    if serverConnection ~= nil then
+        -- A VectorBuffer object is convenient for constructing a message to send
+        local msg = VectorBuffer()
+        msg:WriteString(text)
+        -- Send the chat message as in-order and reliable
+        serverConnection:SendMessage(MSG_CHAT, true, true, msg)
+        -- Empty the text edit after sending
+        textEdit.text = ""
+    end
+end
+
+function HandleConnect(eventType, eventData)
+    local address = textEdit.text
+    if address == "" then
+        address = "localhost" -- Use localhost to connect if nothing else specified
+    end
+        
+    -- Empty the text edit after reading the address to connect to
+    textEdit.text = ""
+    
+    -- Connect to server, do not specify a client scene as we are not using scene replication, just messages.
+    -- At connect time we could also send identity parameters (such as username) in a VariantMap, but in this
+    -- case we skip it for simplicity
+    network:Connect(address, CHAT_SERVER_PORT, nil)
+    
+    UpdateButtons()
+end
+
+function HandleDisconnect(eventType, eventData)
+    local serverConnection = network.serverConnection
+    -- If we were connected to server, disconnect
+    if serverConnection ~= nil then
+        serverConnection:Disconnect()
+    -- Or if we were running a server, stop it
+    else
+        if network.serverRunning then
+            network:StopServer()
+        end
+    end
+    
+    UpdateButtons()
+end
+
+function HandleStartServer(eventType, eventData)
+    network:StartServer(CHAT_SERVER_PORT)
+    
+    UpdateButtons()
+end
+
+function HandleNetworkMessage(eventType, eventData)
+    local msgID = eventData:GetInt("MessageID")
+    if msgID == MSG_CHAT then
+        local msg = eventData:GetBuffer("Data")
+        print(tolua.type(msg))
+        local text = msg:ReadString()
+        -- If we are the server, prepend the sender's IP address and port and echo to everyone
+        -- If we are a client, just display the message
+        if network.serverRunning then
+            local sender = eventData:GetPtr("Connection", "Connection")
+            local text = sender:ToString() .. " " .. text
+            local sendMsg = VectorBuffer()
+            sendMsg:WriteString(text)
+            -- Broadcast as in-order and reliable
+            network:BroadcastMessage(MSG_CHAT, true, true, sendMsg)
+        end
+        ShowChatText(text)
+    end
+end
+
+function HandleConnectionStatus(eventType, eventData)
+    UpdateButtons()
+end

+ 40 - 31
Source/Extras/LuaScript/pkgs/Core/Variant.pkg

@@ -107,7 +107,8 @@ class Variant
     const Quaternion& GetQuaternion() const;
     const Quaternion& GetQuaternion() const;
     const Color& GetColor() const;
     const Color& GetColor() const;
     const String& GetString() const;
     const String& GetString() const;
-
+    
+    
     const ResourceRef& GetResourceRef() const;
     const ResourceRef& GetResourceRef() const;
     const ResourceRefList& GetResourceRefList() const;
     const ResourceRefList& GetResourceRefList() const;
     const IntRect& GetIntRect() const;
     const IntRect& GetIntRect() const;
@@ -158,6 +159,8 @@ class VariantMap
     tolua_outside const Quaternion& VariantMapGetQuaternion @ GetQuaternion(const String key);
     tolua_outside const Quaternion& VariantMapGetQuaternion @ GetQuaternion(const String key);
     tolua_outside const Color& VariantMapGetColor @ GetColor(const String key);
     tolua_outside const Color& VariantMapGetColor @ GetColor(const String key);
     tolua_outside const String& VariantMapGetString @ GetString(const String key);
     tolua_outside const String& VariantMapGetString @ GetString(const String key);
+    
+    tolua_outside VectorBuffer VariantMapGetBuffer @ GetBuffer(const String key);
 
 
     tolua_outside const ResourceRef& VariantMapGetResourceRef @ GetResourceRef(const String key);
     tolua_outside const ResourceRef& VariantMapGetResourceRef @ GetResourceRef(const String key);
     tolua_outside const ResourceRefList& VariantMapGetResourceRefList @ GetResourceRefList(const String key);
     tolua_outside const ResourceRefList& VariantMapGetResourceRefList @ GetResourceRefList(const String key);
@@ -168,153 +171,159 @@ class VariantMap
 };
 };
 
 
 ${
 ${
-void VariantMapSetInt(VariantMap* vmap, const String& key, int value)
+static void VariantMapSetInt(VariantMap* vmap, const String& key, int value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetUInt(VariantMap* vmap, const String& key, unsigned value)
+static void VariantMapSetUInt(VariantMap* vmap, const String& key, unsigned value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetBool(VariantMap* vmap, const String& key, bool value)
+static void VariantMapSetBool(VariantMap* vmap, const String& key, bool value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetFloat(VariantMap* vmap, const String& key, float value)
+static void VariantMapSetFloat(VariantMap* vmap, const String& key, float value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetVector2(VariantMap* vmap, const String& key, const Vector2& value)
+static void VariantMapSetVector2(VariantMap* vmap, const String& key, const Vector2& value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetVector3(VariantMap* vmap, const String& key, const Vector3& value)
+static void VariantMapSetVector3(VariantMap* vmap, const String& key, const Vector3& value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetVector4(VariantMap* vmap, const String& key, const Vector4& value)
+static void VariantMapSetVector4(VariantMap* vmap, const String& key, const Vector4& value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetQuaternion(VariantMap* vmap, const String& key, const Quaternion& value)
+static void VariantMapSetQuaternion(VariantMap* vmap, const String& key, const Quaternion& value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetColor(VariantMap* vmap, const String& key, const Color& value)
+static void VariantMapSetColor(VariantMap* vmap, const String& key, const Color& value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetString(VariantMap* vmap, const String& key, const String& value)
+static void VariantMapSetString(VariantMap* vmap, const String& key, const String& value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetPtr(VariantMap* vmap, const String& key, void* value)
+static void VariantMapSetPtr(VariantMap* vmap, const String& key, void* value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetResourceRef(VariantMap* vmap, const String& key, const ResourceRef& value)
+static void VariantMapSetResourceRef(VariantMap* vmap, const String& key, const ResourceRef& value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetResourceRefList(VariantMap* vmap, const String& key, const ResourceRefList& value)
+static void VariantMapSetResourceRefList(VariantMap* vmap, const String& key, const ResourceRefList& value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetIntRect(VariantMap* vmap, const String& key, const IntRect& value)
+static void VariantMapSetIntRect(VariantMap* vmap, const String& key, const IntRect& value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-void VariantMapSetIntVector2(VariantMap* vmap, const String& key, const IntVector2& value)
+static void VariantMapSetIntVector2(VariantMap* vmap, const String& key, const IntVector2& value)
 {
 {
     (*vmap)[ShortStringHash(key)] = value;
     (*vmap)[ShortStringHash(key)] = value;
 }
 }
 
 
-const Variant& FindVariant(const VariantMap* vmap, const String& key)
+static const Variant& FindVariant(const VariantMap* vmap, const String& key)
 {
 {
     VariantMap::ConstIterator i = vmap->Find(ShortStringHash(key));
     VariantMap::ConstIterator i = vmap->Find(ShortStringHash(key));
     return i != vmap->End() ? i->second_ : Variant::EMPTY;
     return i != vmap->End() ? i->second_ : Variant::EMPTY;
 }
 }
 
 
-int VariantMapGetInt(const VariantMap* vmap, const String& key)
+static int VariantMapGetInt(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetInt();
     return FindVariant(vmap, key).GetInt();
 }
 }
 
 
-unsigned VariantMapGetUInt(const VariantMap* vmap, const String& key)
+static unsigned VariantMapGetUInt(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetUInt();
     return FindVariant(vmap, key).GetUInt();
 }
 }
 
 
-bool VariantMapGetBool(const VariantMap* vmap, const String& key)
+static bool VariantMapGetBool(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetBool();
     return FindVariant(vmap, key).GetBool();
 }
 }
 
 
-float VariantMapGetFloat(const VariantMap* vmap, const String& key)
+static float VariantMapGetFloat(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetFloat();
     return FindVariant(vmap, key).GetFloat();
 }
 }
 
 
-const Vector2& VariantMapGetVector2(const VariantMap* vmap, const String& key)
+static const Vector2& VariantMapGetVector2(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetVector2();
     return FindVariant(vmap, key).GetVector2();
 }
 }
 
 
-const Vector3& VariantMapGetVector3(const VariantMap* vmap, const String& key)
+static const Vector3& VariantMapGetVector3(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetVector3();
     return FindVariant(vmap, key).GetVector3();
 }
 }
 
 
-const Vector4& VariantMapGetVector4(const VariantMap* vmap, const String& key)
+static const Vector4& VariantMapGetVector4(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetVector4();
     return FindVariant(vmap, key).GetVector4();
 }
 }
 
 
-const Quaternion& VariantMapGetQuaternion(const VariantMap* vmap, const String& key)
+static const Quaternion& VariantMapGetQuaternion(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetQuaternion();
     return FindVariant(vmap, key).GetQuaternion();
 }
 }
 
 
-const Color& VariantMapGetColor(const VariantMap* vmap, const String& key)
+static const Color& VariantMapGetColor(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetColor();
     return FindVariant(vmap, key).GetColor();
 }
 }
 
 
-const String& VariantMapGetString(const VariantMap* vmap, const String& key)
+static const String& VariantMapGetString(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetString();
     return FindVariant(vmap, key).GetString();
 }
 }
 
 
-const ResourceRef& VariantMapGetResourceRef(const VariantMap* vmap, const String& key)
+static VectorBuffer VariantMapGetBuffer(const VariantMap* vmap, const String key)
+{
+    const PODVector<unsigned char>& buffer = FindVariant(vmap, key).GetBuffer();
+    return VectorBuffer(buffer);
+}
+
+static const ResourceRef& VariantMapGetResourceRef(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetResourceRef();
     return FindVariant(vmap, key).GetResourceRef();
 }
 }
 
 
-const ResourceRefList& VariantMapGetResourceRefList(const VariantMap* vmap, const String& key)
+static const ResourceRefList& VariantMapGetResourceRefList(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetResourceRefList();
     return FindVariant(vmap, key).GetResourceRefList();
 }
 }
 
 
-const IntRect& VariantMapGetIntRect(const VariantMap* vmap, const String& key)
+static const IntRect& VariantMapGetIntRect(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetIntRect();
     return FindVariant(vmap, key).GetIntRect();
 }
 }
 
 
-const IntVector2& VariantMapGetIntVector2(const VariantMap* vmap, const String& key)
+static const IntVector2& VariantMapGetIntVector2(const VariantMap* vmap, const String& key)
 {
 {
     return FindVariant(vmap, key).GetIntVector2();
     return FindVariant(vmap, key).GetIntVector2();
 }
 }