From b688ba9be8da66c2df428f0842be4b73092baa81 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 3 Aug 2013 20:05:07 +0200 Subject: Removed the unused BlockY parameter from cChunkDef::BlockToChunk() --- source/BlockEntities/ChestEntity.cpp | 2 +- source/BlockEntities/HopperEntity.cpp | 2 +- source/ChunkDef.h | 5 ++--- source/ChunkMap.cpp | 26 +++++++++++++------------- 4 files changed, 17 insertions(+), 18 deletions(-) (limited to 'source') diff --git a/source/BlockEntities/ChestEntity.cpp b/source/BlockEntities/ChestEntity.cpp index 24d2aef11..d5cd076be 100644 --- a/source/BlockEntities/ChestEntity.cpp +++ b/source/BlockEntities/ChestEntity.cpp @@ -123,7 +123,7 @@ void cChestEntity::UsedBy(cPlayer * a_Player) // We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first. // The few false positives aren't much to worry about int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ); m_World->MarkChunkDirty(ChunkX, ChunkZ); } diff --git a/source/BlockEntities/HopperEntity.cpp b/source/BlockEntities/HopperEntity.cpp index 23e4b8096..591db7b4d 100644 --- a/source/BlockEntities/HopperEntity.cpp +++ b/source/BlockEntities/HopperEntity.cpp @@ -125,7 +125,7 @@ void cHopperEntity::UsedBy(cPlayer * a_Player) // We cannot properly detect contents change, but such a change doesn't happen without a player opening the chest first. // The few false positives aren't much to worry about int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(m_PosX, m_PosY, m_PosZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(m_PosX, m_PosZ, ChunkX, ChunkZ); m_World->MarkChunkDirty(ChunkX, ChunkZ); } diff --git a/source/ChunkDef.h b/source/ChunkDef.h index 7f9c0ca98..3e78b59b1 100644 --- a/source/ChunkDef.h +++ b/source/ChunkDef.h @@ -137,7 +137,7 @@ public: /// Converts absolute block coords into relative (chunk + block) coords: inline static void AbsoluteToRelative(/* in-out */ int & a_X, int & a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ ) { - BlockToChunk(a_X, a_Y, a_Z, a_ChunkX, a_ChunkZ); + BlockToChunk(a_X, a_Z, a_ChunkX, a_ChunkZ); a_X = a_X - a_ChunkX * Width; a_Z = a_Z - a_ChunkZ * Width; @@ -145,9 +145,8 @@ public: /// Converts absolute block coords to chunk coords: - inline static void BlockToChunk( int a_X, int a_Y, int a_Z, int & a_ChunkX, int & a_ChunkZ ) + inline static void BlockToChunk(int a_X, int a_Z, int & a_ChunkX, int & a_ChunkZ) { - (void)a_Y; a_ChunkX = a_X / Width; if ((a_X < 0) && (a_X % Width != 0)) { diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp index 0db4b898a..9a9e0dcf6 100644 --- a/source/ChunkMap.cpp +++ b/source/ChunkMap.cpp @@ -345,7 +345,7 @@ void cChunkMap::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, c x = a_BlockX; y = a_BlockY; z = a_BlockZ; - cChunkDef::BlockToChunk(x, y, z, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(x, z, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); if (Chunk == NULL) { @@ -364,7 +364,7 @@ void cChunkMap::BroadcastBlockBreakAnimation(int a_entityID, int a_blockX, int a cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_blockX, a_blockY, a_blockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_blockX, a_blockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -382,7 +382,7 @@ void cChunkMap::BroadcastBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, c { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { @@ -592,7 +592,7 @@ void cChunkMap::BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, in cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_SrcX / 8, a_SrcY / 8, a_SrcZ / 8, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_SrcX / 8, a_SrcZ / 8, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -611,7 +611,7 @@ void cChunkMap::BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_S cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_SrcX / 8, a_SrcY / 8, a_SrcZ / 8, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_SrcX / 8, a_SrcZ / 8, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -645,7 +645,7 @@ void cChunkMap::BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, c { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -664,7 +664,7 @@ void cChunkMap::BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bl cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if (Chunk == NULL) { @@ -682,7 +682,7 @@ void cChunkMap::SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClien { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { @@ -700,7 +700,7 @@ void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, i // a_Player rclked block entity at the coords specified, handle it cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { @@ -717,7 +717,7 @@ void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, 0, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { @@ -735,8 +735,8 @@ void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_M { cSimulatorManager * SimMgr = m_World->GetSimulatorManager(); int MinChunkX, MinChunkZ, MaxChunkX, MaxChunkZ; - cChunkDef::BlockToChunk(a_MinBlockX, ZERO_CHUNK_Y, a_MinBlockZ, MinChunkX, MinChunkZ); - cChunkDef::BlockToChunk(a_MaxBlockX, ZERO_CHUNK_Y, a_MaxBlockZ, MaxChunkX, MaxChunkZ); + cChunkDef::BlockToChunk(a_MinBlockX, a_MinBlockZ, MinChunkX, MinChunkZ); + cChunkDef::BlockToChunk(a_MaxBlockX, a_MaxBlockZ, MaxChunkX, MaxChunkZ); for (int z = MinChunkZ; z <= MaxChunkZ; z++) { int MinZ = std::max(a_MinBlockZ, z * cChunkDef::Width); @@ -1903,7 +1903,7 @@ bool cChunkMap::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const ASt { cCSLock Lock(m_CSLayers); int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); if ((Chunk == NULL) || !Chunk->IsValid()) { -- cgit v1.2.3 From 4f26f11dc77ab032feec8c746fc6ddaa1ea44057 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 3 Aug 2013 20:26:50 +0200 Subject: Added cWorld::DoWithChunk() function. This will be used by the blocktracers to gain direct access to chunk data. --- source/ChunkMap.cpp | 15 +++++++++++++++ source/ChunkMap.h | 4 ++++ source/World.cpp | 9 +++++++++ source/World.h | 3 +++ 4 files changed, 31 insertions(+) (limited to 'source') diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp index 9a9e0dcf6..0d49ce9c4 100644 --- a/source/ChunkMap.cpp +++ b/source/ChunkMap.cpp @@ -713,6 +713,21 @@ void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, i +bool cChunkMap::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + if (Chunk == NULL) + { + return false; + } + return a_Callback.Item(Chunk); +} + + + + + void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) { cCSLock Lock(m_CSLayers); diff --git a/source/ChunkMap.h b/source/ChunkMap.h index 899f290c5..183031808 100644 --- a/source/ChunkMap.h +++ b/source/ChunkMap.h @@ -35,6 +35,7 @@ typedef cItemCallback cDispenserCallback; typedef cItemCallback cDropperCallback; typedef cItemCallback cDropSpenserCallback; typedef cItemCallback cFurnaceCallback; +typedef cItemCallback cChunkCallback; @@ -79,6 +80,9 @@ public: /// a_Player rclked block entity at the coords specified, handle it void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); + /// Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback + bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback); + /// Wakes up simulators for the specified block void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ); diff --git a/source/World.cpp b/source/World.cpp index 880f6e5b2..03e086148 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -832,6 +832,15 @@ bool cWorld::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_ +bool cWorld::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback) +{ + return m_ChunkMap->DoWithChunk(a_ChunkX, a_ChunkZ, a_Callback); +} + + + + + void cWorld::GrowTree(int a_X, int a_Y, int a_Z) { if (GetBlock(a_X, a_Y, a_Z) == E_BLOCK_SAPLING) diff --git a/source/World.h b/source/World.h index 9de00ceec..52d634769 100644 --- a/source/World.h +++ b/source/World.h @@ -404,6 +404,9 @@ public: /// a_Player is using block entity at [x, y, z], handle that: void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) {m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); } + + /// Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback + bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback); void GrowTree (int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export void GrowTreeFromSapling(int a_BlockX, int a_BlockY, int a_BlockZ, char a_SaplingMeta); // tolua_export -- cgit v1.2.3 From 5fe7008966f70de2af53cce7fc13014c220ab721 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 4 Aug 2013 13:25:48 +0200 Subject: First attempt at implementing a cLineBlockTracer class Not yet tested, will probably have lots of bugs, if it is at all usable. --- source/BlockTracer.h | 104 ++++++++++++++++++ source/LineBlockTracer.cpp | 258 +++++++++++++++++++++++++++++++++++++++++++++ source/LineBlockTracer.h | 84 +++++++++++++++ 3 files changed, 446 insertions(+) create mode 100644 source/BlockTracer.h create mode 100644 source/LineBlockTracer.cpp create mode 100644 source/LineBlockTracer.h (limited to 'source') diff --git a/source/BlockTracer.h b/source/BlockTracer.h new file mode 100644 index 000000000..4adc61f00 --- /dev/null +++ b/source/BlockTracer.h @@ -0,0 +1,104 @@ + +// BlockTracer.h + +// Declares the classes common for all blocktracers + + + + + +#pragma once + + + + + +// fwd: World.h +class cWorld; + + + + + +class cBlockTracer abstract +{ +public: + /** The callback class is used to notify the caller of individual events that are being traced. + */ + class cCallbacks abstract + { + public: + /** Called on each block encountered along the path, including the first block (path start) + When this callback returns true, the tracing is aborted. + */ + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; + + /** Called on each block encountered along the path, including the first block (path start), if chunk data is not loaded + When this callback returns true, the tracing is aborted. + */ + virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ) {} + + /** Called when the path goes out of world, either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height) + The coords specify the exact point at which the path exited the world. + If this callback returns true, the tracing is aborted. + Note that some paths can go out of the world and come back again (parabola), + in such a case this callback is followed by OnIntoWorld() and further OnNextBlock() calls + */ + virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) {} + + /** Called when the path goes into the world, from either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height) + The coords specify the exact point at which the path entered the world. + If this callback returns true, the tracing is aborted. + Note that some paths can go out of the world and come back again (parabola), + in such a case this callback is followed by further OnNextBlock() calls + */ + virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) {} + + /** Called when the path is sure not to hit any more blocks. + Note that for some shapes this might never happen (line with constant Y) + */ + virtual void OnNoMoreHits(void) {} + + /** Called when the block tracing walks into a chunk that is not allocated. + This usually means that the tracing is aborted. + */ + virtual void OnNoChunk(void) {} + } ; + + + /// Creates the BlockTracer parent with the specified callbacks + cBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks) : + m_World(&a_World), + m_Callbacks(&a_Callbacks) + { + } + + + /// Sets new world, returns the old one. Note that both need to be valid + cWorld & SetWorld(cWorld & a_World) + { + cWorld & Old = *m_World; + m_World = &a_World; + return Old; + } + + + /// Sets new callbacks, returns the old ones. Note that both need to be valid + cCallbacks & SetCallbacks(cCallbacks & a_NewCallbacks) + { + cCallbacks & Old = *m_Callbacks; + m_Callbacks = &a_NewCallbacks; + return Old; + } + +protected: + /// The world upon which to operate + cWorld * m_World; + + /// The callback to use for reporting + cCallbacks * m_Callbacks; +} ; + + + + diff --git a/source/LineBlockTracer.cpp b/source/LineBlockTracer.cpp new file mode 100644 index 000000000..c5939cb78 --- /dev/null +++ b/source/LineBlockTracer.cpp @@ -0,0 +1,258 @@ + +// LineBlockTracer.cpp + +// Implements the cLineBlockTracer class representing a cBlockTracer that traces along a straight line between two points + +#include "Globals.h" +#include "LineBlockTracer.h" +#include "Vector3d.h" +#include "World.h" +#include "Chunk.h" + + + + + + +cLineBlockTracer::cLineBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks) : + super(a_World, a_Callbacks) +{ +} + + + + + +bool cLineBlockTracer::Trace(cWorld & a_World, cBlockTracer::cCallbacks & a_Callbacks, const Vector3d & a_Start, const Vector3d & a_End) +{ + cLineBlockTracer Tracer(a_World, a_Callbacks); + return Tracer.Trace(a_Start.x, a_Start.y, a_Start.z, a_End.x, a_End.y, a_End.z); +} + + + + + +bool cLineBlockTracer::Trace(cWorld & a_World, cBlockTracer::cCallbacks &a_Callbacks, double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ) +{ + cLineBlockTracer Tracer(a_World, a_Callbacks); + return Tracer.Trace(a_StartX, a_StartY, a_StartZ, a_EndX, a_EndY, a_EndZ); +} + + + + + +bool cLineBlockTracer::Trace(double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ) +{ + // Initialize the member veriables: + m_StartX = a_StartX; + m_StartY = a_StartY; + m_StartZ = a_StartZ; + m_EndX = a_EndX; + m_EndY = a_EndY; + m_EndZ = a_EndZ; + m_DirX = (m_StartX < m_EndX) ? 1 : -1; + m_DirY = (m_StartY < m_EndY) ? 1 : -1; + m_DirZ = (m_StartZ < m_EndZ) ? 1 : -1; + + // Check the start coords, adjust into the world: + if (m_StartY < 0) + { + if (m_EndY < 0) + { + // Nothing to trace + m_Callbacks->OnNoMoreHits(); + return true; + } + FixStartBelowWorld(); + m_Callbacks->OnIntoWorld(m_StartX, m_StartY, m_StartZ); + } + else if (m_StartY >= cChunkDef::Height) + { + if (m_EndY >= cChunkDef::Height) + { + m_Callbacks->OnNoMoreHits(); + return true; + } + FixStartAboveWorld(); + m_Callbacks->OnIntoWorld(m_StartX, m_StartY, m_StartZ); + } + + m_CurrentX = (int)floor(m_StartX); + m_CurrentY = (int)floor(m_StartY); + m_CurrentZ = (int)floor(m_StartZ); + + m_DiffX = m_EndX - m_StartX; + m_DiffY = m_EndY - m_StartY; + m_DiffZ = m_EndZ - m_StartZ; + + // The actual trace is handled with ChunkMapCS locked by calling our Item() for the specified chunk + int BlockX = (int)floor(m_StartX); + int BlockZ = (int)floor(m_StartZ); + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(BlockX, BlockZ, ChunkX, ChunkZ); + return m_World->DoWithChunk(ChunkX, ChunkZ, *this); +} + + + + + +void cLineBlockTracer::FixStartAboveWorld(void) +{ + // We must set the start Y to less than cChunkDef::Height so that it is considered inside the world later on + // Therefore we use an EPS-offset from the height, as small as reasonably possible. + const double Height = (double)cChunkDef::Height - 0.00001; + CalcXZIntersection(Height, m_StartX, m_StartZ); + m_StartY = Height; +} + + + + + +void cLineBlockTracer::FixStartBelowWorld(void) +{ + CalcXZIntersection(0, m_StartX, m_StartZ); + m_StartY = 0; +} + + + + + +void cLineBlockTracer::CalcXZIntersection(double a_Y, double & a_IntersectX, double & a_IntersectZ) +{ + double Ratio = (m_StartY - a_Y) / (m_StartY - m_EndY); + a_IntersectX = m_StartX + (m_EndX - m_StartX) * Ratio; + a_IntersectZ = m_StartZ + (m_EndZ - m_StartZ) * Ratio; +} + + + + + +bool cLineBlockTracer::MoveToNextBlock(void) +{ + // Find out which of the current block's walls gets hit by the path: + static const double EPS = 0.00001; + double Coeff = 1; + enum eDirection + { + dirNONE, + dirX, + dirY, + dirZ, + } Direction = dirNONE; + if (abs(m_DiffX) > EPS) + { + double DestX = (m_DirX > 0) ? (m_CurrentX + 1) : m_CurrentX; + Coeff = (m_EndX - DestX) / m_DiffX; + Direction = dirX; + } + if (abs(m_DiffY) > EPS) + { + double DestY = (m_DirY > 0) ? (m_CurrentY + 1) : m_CurrentY; + double CoeffY = (DestY - m_StartY) / m_DiffY; + if (CoeffY < Coeff) + { + Coeff = CoeffY; + Direction = dirY; + } + } + if (abs(m_DiffZ) > EPS) + { + double DestZ = (m_DirZ > 0) ? (m_CurrentZ + 1) : m_CurrentZ; + double CoeffZ = (DestZ - m_StartZ) / m_DiffZ; + if (CoeffZ < Coeff) + { + Coeff = CoeffZ; + Direction = dirZ; + } + } + + // Based on the wall hit, adjust the current coords + switch (Direction) + { + case dirX: m_CurrentX += m_DirX; break; + case dirY: m_CurrentY += m_DirY; break; + case dirZ: m_CurrentZ += m_DirZ; break; + case dirNONE: return false; + } + return true; +} + + + + + +bool cLineBlockTracer::Item(cChunk * a_Chunk) +{ + ASSERT((m_CurrentY >= 0) && (m_CurrentY < cChunkDef::Height)); // This should be provided by FixStartAboveWorld() / FixStartBelowWorld() + + // This is the actual line tracing loop. + bool Finished = false; + while (true) + { + // Report the current block through the callbacks: + if (a_Chunk == NULL) + { + m_Callbacks->OnNoChunk(); + return false; + } + if (a_Chunk->IsValid()) + { + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + int RelX = FAST_FLOOR_DIV(m_CurrentX, cChunkDef::Width); + int RelZ = FAST_FLOOR_DIV(m_CurrentZ, cChunkDef::Width); + a_Chunk->GetBlockTypeMeta(RelX, m_CurrentY, RelZ, BlockType, BlockMeta); + if (m_Callbacks->OnNextBlock(m_CurrentX, m_CurrentY, m_CurrentZ, BlockType, BlockMeta)) + { + // The callback terminated the trace + return false; + } + } + else + { + if (m_Callbacks->OnNextBlockNoData(m_CurrentX, m_CurrentY, m_CurrentZ)) + { + // The callback terminated the trace + return false; + } + } + + // Move to next block + if (!MoveToNextBlock()) + { + // We've reached the end + m_Callbacks->OnNoMoreHits(); + return true; + } + + // Update the current chunk + if (a_Chunk != NULL) + { + a_Chunk = a_Chunk->GetNeighborChunk(m_CurrentX, m_CurrentZ); + } + + if ((m_CurrentY < 0) || (m_CurrentY >= cChunkDef::Height)) + { + // We've gone out of the world, that's the end of this trace + double IntersectX, IntersectZ; + CalcXZIntersection(m_CurrentY, IntersectX, IntersectZ); + if (m_Callbacks->OnOutOfWorld(IntersectX, m_CurrentY, IntersectZ)) + { + // The callback terminated the trace + return false; + } + m_Callbacks->OnNoMoreHits(); + return true; + } + } +} + + + + diff --git a/source/LineBlockTracer.h b/source/LineBlockTracer.h new file mode 100644 index 000000000..4616cb191 --- /dev/null +++ b/source/LineBlockTracer.h @@ -0,0 +1,84 @@ + +// LineBlockTracer.h + +// Declares the cLineBlockTracer class representing a cBlockTracer that traces along a straight line between two points + + + + + +#pragma once + +#include "BlockTracer.h" + + + + + +// fwd: Chunk.h +class cChunk; + +// fwd: cChunkMap.h +typedef cItemCallback cChunkCallback; + + + + + + +class cLineBlockTracer : + public cBlockTracer, + public cChunkCallback +{ + typedef cBlockTracer super; + +public: + cLineBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks); + + /// Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits()) + bool Trace(double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ); + + // Utility functions for simple one-line usage: + /// Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits()) + static bool Trace(cWorld & a_World, cCallbacks & a_Callbacks, double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ); + + /// Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits()) + static bool Trace(cWorld & a_World, cCallbacks & a_Callbacks, const Vector3d & a_Start, const Vector3d & a_End); + +protected: + // The start point of the trace + double m_StartX, m_StartY, m_StartZ; + + // The end point of the trace + double m_EndX, m_EndY, m_EndZ; + + // The difference in coords, End - Start + double m_DiffX, m_DiffY, m_DiffZ; + + // The increment at which the block coords are going from Start to End; either +1 or -1 + int m_DirX, m_DirY, m_DirZ; + + // The current block + int m_CurrentX, m_CurrentY, m_CurrentZ; + + + /// Adjusts the start point above the world to just at the world's top + void FixStartAboveWorld(void); + + /// Adjusts the start point below the world to just at the world's bottom + void FixStartBelowWorld(void); + + /// Calculates the XZ coords of an intersection with the specified Yconst plane; assumes that such an intersection exists + void CalcXZIntersection(double a_Y, double & a_IntersectX, double & a_IntersectZ); + + /// Moves m_Current to the next block on the line; returns false if no move is possible (reached the end) + bool MoveToNextBlock(void); + + // cChunkCallback overrides: + virtual bool Item(cChunk * a_Chunk) override; +} ; + + + + + -- cgit v1.2.3 From 6af81c66e9aea6ecc5913266815e7e468872dee4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 4 Aug 2013 16:06:28 +0200 Subject: cItem: Removed a warning emitted when creating an item from air --- source/Item.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source') diff --git a/source/Item.h b/source/Item.h index fc54da51d..fee861050 100644 --- a/source/Item.h +++ b/source/Item.h @@ -55,7 +55,10 @@ public: { if (!IsValidItem(m_ItemType)) { - LOGWARNING("%s: creating an invalid item type (%d), resetting to empty.", __FUNCTION__, a_ItemType); + if (m_ItemType != E_BLOCK_AIR) + { + LOGWARNING("%s: creating an invalid item type (%d), resetting to empty.", __FUNCTION__, a_ItemType); + } Empty(); } } -- cgit v1.2.3 From 654714e7bc34b61d01202e3f87adc2fa60baeeab Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 4 Aug 2013 16:07:15 +0200 Subject: LineBlockTracer: Fixed initial errors --- source/BlockTracer.h | 6 +++--- source/LineBlockTracer.cpp | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'source') diff --git a/source/BlockTracer.h b/source/BlockTracer.h index 4adc61f00..6d67f1052 100644 --- a/source/BlockTracer.h +++ b/source/BlockTracer.h @@ -36,7 +36,7 @@ public: /** Called on each block encountered along the path, including the first block (path start), if chunk data is not loaded When this callback returns true, the tracing is aborted. */ - virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ) {} + virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ) { return false; } /** Called when the path goes out of world, either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height) The coords specify the exact point at which the path exited the world. @@ -44,7 +44,7 @@ public: Note that some paths can go out of the world and come back again (parabola), in such a case this callback is followed by OnIntoWorld() and further OnNextBlock() calls */ - virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) {} + virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) { return false; } /** Called when the path goes into the world, from either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height) The coords specify the exact point at which the path entered the world. @@ -52,7 +52,7 @@ public: Note that some paths can go out of the world and come back again (parabola), in such a case this callback is followed by further OnNextBlock() calls */ - virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) {} + virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) { return false; } /** Called when the path is sure not to hit any more blocks. Note that for some shapes this might never happen (line with constant Y) diff --git a/source/LineBlockTracer.cpp b/source/LineBlockTracer.cpp index c5939cb78..03464314a 100644 --- a/source/LineBlockTracer.cpp +++ b/source/LineBlockTracer.cpp @@ -148,8 +148,11 @@ bool cLineBlockTracer::MoveToNextBlock(void) if (abs(m_DiffX) > EPS) { double DestX = (m_DirX > 0) ? (m_CurrentX + 1) : m_CurrentX; - Coeff = (m_EndX - DestX) / m_DiffX; - Direction = dirX; + Coeff = (DestX - m_StartX) / m_DiffX; + if (Coeff <= 1) + { + Direction = dirX; + } } if (abs(m_DiffY) > EPS) { @@ -205,8 +208,8 @@ bool cLineBlockTracer::Item(cChunk * a_Chunk) { BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; - int RelX = FAST_FLOOR_DIV(m_CurrentX, cChunkDef::Width); - int RelZ = FAST_FLOOR_DIV(m_CurrentZ, cChunkDef::Width); + int RelX = m_CurrentX - a_Chunk->GetPosX() * cChunkDef::Width; + int RelZ = m_CurrentZ - a_Chunk->GetPosZ() * cChunkDef::Width; a_Chunk->GetBlockTypeMeta(RelX, m_CurrentY, RelZ, BlockType, BlockMeta); if (m_Callbacks->OnNextBlock(m_CurrentX, m_CurrentY, m_CurrentZ, BlockType, BlockMeta)) { -- cgit v1.2.3 From e21ed58d5fbf901e10cf829bba0fb3d1c9952f7b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 4 Aug 2013 16:08:09 +0200 Subject: cWorld: Added a self-test for LineBlockTracer, disabled by an #ifdef. --- source/World.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'source') diff --git a/source/World.cpp b/source/World.cpp index 03e086148..1ff5a5970 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -59,6 +59,9 @@ #include "tolua++.h" +// DEBUG: Test out the cLineBlockTracer class by tracing a few lines: +#include "LineBlockTracer.h" + #ifndef _WIN32 #include #endif @@ -442,6 +445,60 @@ void cWorld::InitializeSpawn(void) // TODO: Better spawn detection - move spawn out of the water if it isn't set in the INI already m_SpawnY = (double)GetHeight((int)m_SpawnX, (int)m_SpawnZ) + 1.6f; // +1.6f eye height + + + #ifdef TEST_LINEBLOCKTRACER + // DEBUG: Test out the cLineBlockTracer class by tracing a few lines: + class cTracerCallbacks : + public cBlockTracer::cCallbacks + { + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override + { + LOGD("Block {%d, %d, %d}: %d:%d (%s)", + a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, + ItemToString(cItem(a_BlockType, 1, a_BlockMeta)).c_str() + ); + return false; + } + + virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ) override + { + LOGD("Block {%d, %d, %d}: no data available", + a_BlockX, a_BlockY, a_BlockZ + ); + return false; + } + + virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override + { + LOGD("Out of world at {%f, %f, %f}", a_BlockX, a_BlockY, a_BlockZ); + return false; + } + + virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override + { + LOGD("Into world at {%f, %f, %f}", a_BlockX, a_BlockY, a_BlockZ); + return false; + } + + virtual void OnNoMoreHits(void) override + { + LOGD("No more hits"); + } + } Callbacks; + LOGD("Spawn is at {%f, %f, %f}", m_SpawnX, m_SpawnY, m_SpawnZ); + LOGD("Tracing a line along +X:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX - 10, m_SpawnY, m_SpawnZ, m_SpawnX + 10, m_SpawnY, m_SpawnZ); + LOGD("Tracing a line along -Z:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX, m_SpawnY, m_SpawnZ + 10, m_SpawnX, m_SpawnY, m_SpawnZ - 10); + LOGD("Tracing a line along -Y, out of world:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX, 260, m_SpawnZ, m_SpawnX, -5, m_SpawnZ); + LOGD("Tracing a line along XY:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX - 10, m_SpawnY - 10, m_SpawnZ, m_SpawnX + 10, m_SpawnY + 10, m_SpawnZ); + LOGD("Tracing a line in generic direction:"); + cLineBlockTracer::Trace(*this, Callbacks, m_SpawnX - 15, m_SpawnY - 5, m_SpawnZ + 7.5, m_SpawnX + 13, m_SpawnY - 10, m_SpawnZ + 8.5); + LOGD("Tracing tests done"); + #endif // TEST_LINEBLOCKTRACER } -- cgit v1.2.3 From 71bb41ee86e262103909d8007dbc2ef876cd0b24 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 4 Aug 2013 23:11:25 +0200 Subject: LuaState refactoring: initial part. The cLuaState class is a wrapper for the lua_State * and for the common functions on it. The cPlugin_NewLua has been rewritten to use it instead of the raw pointer. Part of #33 --- source/LuaState.cpp | 218 +++++++++++++++++++++++++++++ source/LuaState.h | 90 ++++++++++++ source/ManualBindings.cpp | 19 +-- source/Plugin_NewLua.cpp | 350 ++++++++++++++++------------------------------ source/Plugin_NewLua.h | 11 +- 5 files changed, 439 insertions(+), 249 deletions(-) create mode 100644 source/LuaState.cpp create mode 100644 source/LuaState.h (limited to 'source') diff --git a/source/LuaState.cpp b/source/LuaState.cpp new file mode 100644 index 000000000..da86a4b20 --- /dev/null +++ b/source/LuaState.cpp @@ -0,0 +1,218 @@ + +// LuaState.cpp + +// Implements the cLuaState class representing the wrapper over lua_State *, provides associated helper functions + +#include "Globals.h" +#include "LuaState.h" + +extern "C" +{ + #include "lualib.h" +} + +#include "tolua++.h" +#include "Bindings.h" +#include "ManualBindings.h" + +// fwd: SQLite/lsqlite3.c +extern "C" +{ + LUALIB_API int luaopen_lsqlite3(lua_State * L); +} + +// fwd: LuaExpat/lxplib.c: +extern "C" +{ + int luaopen_lxp(lua_State * L); +} + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cLuaState: + +cLuaState::cLuaState(const AString & a_SubsystemName) : + m_LuaState(NULL), + m_SubsystemName(a_SubsystemName) +{ +} + + + + + +cLuaState::~cLuaState() +{ + if (IsValid()) + { + Close(); + } +} + + + + + +void cLuaState::Create(void) +{ + if (m_LuaState != NULL) + { + LOGWARNING("%s: Trying to create an already-existing LuaState, ignoring.", __FUNCTION__); + return; + } + m_LuaState = lua_open(); + luaL_openlibs(m_LuaState); + tolua_AllToLua_open(m_LuaState); + ManualBindings::Bind(m_LuaState); + luaopen_lsqlite3(m_LuaState); + luaopen_lxp(m_LuaState); +} + + + + + +void cLuaState::Close(void) +{ + if (m_LuaState == NULL) + { + LOGWARNING("%s: Trying to close an invalid LuaState, ignoring.", __FUNCTION__); + return; + } + lua_close(m_LuaState); + m_LuaState = NULL; +} + + + + + +bool cLuaState::LoadFile(const AString & a_FileName) +{ + ASSERT(IsValid()); + + // Load the file: + int s = luaL_loadfile(m_LuaState, a_FileName.c_str()); + if (ReportErrors(s)) + { + LOGWARNING("Can't load %s because of an error in file %s", m_SubsystemName.c_str(), a_FileName.c_str()); + return false; + } + + // Execute the globals: + s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); + if (ReportErrors(s)) + { + LOGWARNING("Error in %s in file %s", m_SubsystemName.c_str(), a_FileName.c_str()); + return false; + } + + return true; +} + + + + + +bool cLuaState::PushFunction(const char * a_FunctionName, bool a_ShouldLogFailure /* = true */) +{ + if (!IsValid()) + { + // This happens if cPlugin::Initialize() fails with an error + return false; + } + + lua_getglobal(m_LuaState, a_FunctionName); + if (!lua_isfunction(m_LuaState, -1)) + { + if (a_ShouldLogFailure) + { + LOGWARNING("Error in %s: Could not find function %s()", m_SubsystemName.c_str(), a_FunctionName); + } + lua_pop(m_LuaState, 1); + return false; + } + return true; +} + + + + + +bool cLuaState::PushFunctionFromRegistry(int a_FnRef) +{ + lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // same as lua_getref() + if (!lua_isfunction(m_LuaState, -1)) + { + lua_pop(m_LuaState, 1); + return false; + } + return true; +} + + + + + +void cLuaState::PushStringVector(const AStringVector & a_Vector) +{ + lua_createtable(m_LuaState, a_Vector.size(), 0); + int newTable = lua_gettop(m_LuaState); + int index = 1; + for (AStringVector::const_iterator itr = a_Vector.begin(), end = a_Vector.end(); itr != end; ++itr, ++index) + { + tolua_pushstring(m_LuaState, itr->c_str()); + lua_rawseti(m_LuaState, newTable, index); + } +} + + + + + +bool cLuaState::CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName) +{ + ASSERT(lua_isfunction(m_LuaState, -a_NumArgs - 1)); + + int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); + if (ReportErrors(s)) + { + LOGWARNING("Error in %s calling function %s()", m_SubsystemName.c_str(), a_FunctionName); + return false; + } + return true; +} + + + + + +bool cLuaState::ReportErrors(int a_Status) +{ + return ReportErrors(m_LuaState, a_Status); +} + + + + + +bool cLuaState::ReportErrors(lua_State * a_LuaState, int a_Status) +{ + if (a_Status == 0) + { + // No error to report + return false; + } + + LOGWARNING("LUA: %d - %s", a_Status, lua_tostring(a_LuaState, -1)); + lua_pop(a_LuaState, 1); + return true; +} + + + + diff --git a/source/LuaState.h b/source/LuaState.h new file mode 100644 index 000000000..10ff53911 --- /dev/null +++ b/source/LuaState.h @@ -0,0 +1,90 @@ + +// LuaState.h + +// Declares the cLuaState class representing the wrapper over lua_State *, provides associated helper functions + + + + + +#pragma once + + + + + +// fwd: lua.h +struct lua_State; + + + + + +class cLuaState +{ +public: + /** Creates a new instance. The LuaState is not initialized. + a_SubsystemName is used for reporting problems in the console, it is "plugin %s" for plugins, + or "LuaScript" for the cLuaScript template + */ + cLuaState(const AString & a_SubsystemName); + + ~cLuaState(); + + operator lua_State * (void) { return m_LuaState; } + + /// Creates the m_LuaState, if not closed already + void Create(void); + + /// Closes the m_LuaState, if not closed already + void Close(void); + + /// Returns true if the m_LuaState is valid + bool IsValid(void) const { return (m_LuaState != NULL); } + + /** Loads the specified file + Returns false and logs a warning to the console if not successful (but the LuaState is kept open). + m_SubsystemName is displayed in the warning log message. + */ + bool LoadFile(const AString & a_FileName); + + /** Pushes the function of the specified name onto the stack. + Returns true if successful. + If a_ShouldLogFail is true, logs a warning on failure (incl. m_SubsystemName) + */ + bool PushFunction(const char * a_FunctionName, bool a_ShouldLogFailure = true); + + /** Pushes a function that has been saved into the global registry, identified by a_FnRef. + Returns true if successful. Logs a warning on failure + */ + bool PushFunctionFromRegistry(int a_FnRef); + + /// Pushes a string vector, as a table, onto the stack + void PushStringVector(const AStringVector & a_Vector); + + /** + Calls the function that has been pushed onto the stack by PushFunction. + Returns true if successful, logs a warning on failure. + a_FunctionName is used only for the warning log message, the function + to be called must be pushed by PushFunction() beforehand. + */ + bool CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName); + + /// If the status is nonzero, prints the text on the top of Lua stack and returns true + bool ReportErrors(int status); + + /// If the status is nonzero, prints the text on the top of Lua stack and returns true + static bool ReportErrors(lua_State * a_LuaState, int status); + +protected: + lua_State * m_LuaState; + + /** The subsystem name is used for reporting errors to the console, it is either "plugin %s" or "LuaScript" + whatever is given to the constructor + */ + AString m_SubsystemName; +} ; + + + + diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 7a13d94c0..403ad21d5 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -19,13 +19,14 @@ #include "BlockEntities/FurnaceEntity.h" #include "md5/md5.h" #include "LuaWindow.h" +#include "LuaState.h" // fwd: LuaCommandBinder.cpp -bool report_errors(lua_State* lua, int status); +// bool cLuaState::ReportErrors(lua_State* lua, int status); @@ -233,7 +234,7 @@ static int tolua_DoWith(lua_State* tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; // Abort enumeration } @@ -328,7 +329,7 @@ static int tolua_DoWithXYZ(lua_State* tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; // Abort enumeration } @@ -421,7 +422,7 @@ static int tolua_ForEachInChunk(lua_State* tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; /* Abort enumeration */ } @@ -512,7 +513,7 @@ static int tolua_ForEach(lua_State * tolua_S) } int s = lua_pcall(LuaState, (TableRef == LUA_REFNIL ? 1 : 2), 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; /* Abort enumeration */ } @@ -677,7 +678,7 @@ static int tolua_cPluginManager_ForEachCommand(lua_State * tolua_S) tolua_pushcppstring(LuaState, a_HelpString); int s = lua_pcall(LuaState, 3, 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; /* Abort enumeration */ } @@ -751,7 +752,7 @@ static int tolua_cPluginManager_ForEachConsoleCommand(lua_State * tolua_S) tolua_pushcppstring(LuaState, a_HelpString); int s = lua_pcall(LuaState, 2, 1, 0); - if (report_errors(LuaState, s)) + if (cLuaState::ReportErrors(LuaState, s)) { return true; /* Abort enumeration */ } @@ -1171,8 +1172,8 @@ static int tolua_cPlugin_Call(lua_State* tolua_S) return 0; } - int s = lua_pcall(targetState, top-2, LUA_MULTRET, 0); - if( report_errors( targetState, s ) ) + int s = lua_pcall(targetState, top - 2, LUA_MULTRET, 0); + if (cLuaState::ReportErrors(targetState, s)) { LOGWARN("Error while calling function '%s' in plugin '%s'", funcName.c_str(), self->GetName().c_str() ); return 0; diff --git a/source/Plugin_NewLua.cpp b/source/Plugin_NewLua.cpp index 8b0f047cd..51d16c839 100644 --- a/source/Plugin_NewLua.cpp +++ b/source/Plugin_NewLua.cpp @@ -7,45 +7,10 @@ extern "C" { -#include "lualib.h" + #include "lualib.h" } #include "tolua++.h" -#include "Bindings.h" -#include "ManualBindings.h" - - - - - -// fwd: SQLite/lsqlite3.c -extern "C" -{ - LUALIB_API int luaopen_lsqlite3(lua_State * L); -} - -// fwd: LuaExpat/lxplib.c: -extern "C" -{ - int luaopen_lxp(lua_State * L); -} - - - - - -bool report_errors(lua_State * lua, int status) -{ - if (status == 0) - { - // No error to report - return false; - } - - LOGERROR("LUA: %s", lua_tostring(lua, -1)); - lua_pop(lua, 1); - return true; -} @@ -54,10 +19,9 @@ bool report_errors(lua_State * lua, int status) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cPlugin_NewLua: -cPlugin_NewLua::cPlugin_NewLua(const AString & a_PluginDirectory) - : m_LuaState( 0 ) - , cWebPlugin() - , cPlugin(a_PluginDirectory) +cPlugin_NewLua::cPlugin_NewLua(const AString & a_PluginDirectory) : + cPlugin(a_PluginDirectory), + m_LuaState(Printf("plugin %s", GetName().c_str())) { } @@ -68,12 +32,7 @@ cPlugin_NewLua::cPlugin_NewLua(const AString & a_PluginDirectory) cPlugin_NewLua::~cPlugin_NewLua() { cCSLock Lock(m_CriticalSection); - - if( m_LuaState ) - { - lua_close( m_LuaState ); - m_LuaState = 0; - } + m_LuaState.Close(); } @@ -83,14 +42,9 @@ cPlugin_NewLua::~cPlugin_NewLua() bool cPlugin_NewLua::Initialize(void) { cCSLock Lock(m_CriticalSection); - if (m_LuaState == NULL) + if (!m_LuaState.IsValid()) { - m_LuaState = lua_open(); - luaL_openlibs(m_LuaState); - tolua_AllToLua_open(m_LuaState); - ManualBindings::Bind(m_LuaState); - luaopen_lsqlite3(m_LuaState); - luaopen_lxp(m_LuaState); + m_LuaState.Create(); // Inject the identification global variables into the state: lua_pushlightuserdata(m_LuaState, this); @@ -110,47 +64,32 @@ bool cPlugin_NewLua::Initialize(void) continue; } AString Path = PluginPath + *itr; - int s = luaL_loadfile(m_LuaState, Path.c_str() ); - if( report_errors( m_LuaState, s ) ) + if (!m_LuaState.LoadFile(Path)) { - LOGERROR("Can't load plugin %s because of an error in file %s", GetLocalDirectory().c_str(), Path.c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; - return false; - } - - s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); - if( report_errors( m_LuaState, s ) ) - { - LOGERROR("Error in plugin %s in file %s", GetLocalDirectory().c_str(), Path.c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; + m_LuaState.Close(); return false; } } // for itr - Files[] // Call intialize function - if (!PushFunction("Initialize")) + if (!m_LuaState.PushFunction("Initialize")) { - lua_close( m_LuaState ); - m_LuaState = 0; + m_LuaState.Close(); return false; } tolua_pushusertype(m_LuaState, this, "cPlugin_NewLua"); - if (!CallFunction(1, 1, "Initialize")) + if (!m_LuaState.CallFunction(1, 1, "Initialize")) { - lua_close( m_LuaState ); - m_LuaState = 0; + m_LuaState.Close(); return false; } - if( !lua_isboolean( m_LuaState, -1 ) ) + if (!lua_isboolean(m_LuaState, -1)) { - LOGWARN("Error in plugin %s Initialize() must return a boolean value!", GetLocalDirectory().c_str() ); - lua_close( m_LuaState ); - m_LuaState = 0; + LOGWARNING("Error in plugin %s: Initialize() must return a boolean value!", GetName().c_str()); + m_LuaState.Close(); return false; } @@ -165,12 +104,12 @@ bool cPlugin_NewLua::Initialize(void) void cPlugin_NewLua::OnDisable() { cCSLock Lock(m_CriticalSection); - if (!PushFunction("OnDisable", false)) // false = don't log error if not found + if (!m_LuaState.PushFunction("OnDisable", false)) // false = don't log error if not found { return; } - CallFunction(0, 0, "OnDisable"); + m_LuaState.CallFunction(0, 0, "OnDisable"); } @@ -181,14 +120,14 @@ void cPlugin_NewLua::Tick(float a_Dt) { cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_TICK); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return; } tolua_pushnumber( m_LuaState, a_Dt ); - CallFunction(1, 0, FnName); + m_LuaState.CallFunction(1, 0, FnName); } @@ -200,7 +139,7 @@ bool cPlugin_NewLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_BLOCK_TO_PICKUPS); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -214,7 +153,7 @@ bool cPlugin_NewLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int tolua_pushnumber (m_LuaState, a_BlockMeta); tolua_pushusertype(m_LuaState, &a_Pickups, "cItems"); - if (!CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(8, 1, FnName)) { return false; } @@ -233,7 +172,7 @@ bool cPlugin_NewLua::OnChat(cPlayer * a_Player, AString & a_Message) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHAT); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -241,7 +180,7 @@ bool cPlugin_NewLua::OnChat(cPlayer * a_Player, AString & a_Message) tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); tolua_pushstring (m_LuaState, a_Message.c_str()); - if (!CallFunction(2, 2, FnName)) + if (!m_LuaState.CallFunction(2, 2, FnName)) { return false; } @@ -264,7 +203,7 @@ bool cPlugin_NewLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_Chun cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_AVAILABLE); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -273,7 +212,7 @@ bool cPlugin_NewLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_Chun tolua_pushnumber (m_LuaState, a_ChunkX); tolua_pushnumber (m_LuaState, a_ChunkZ); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -292,7 +231,7 @@ bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_Chun cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_GENERATED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -302,7 +241,7 @@ bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_Chun tolua_pushnumber (m_LuaState, a_ChunkZ); tolua_pushusertype(m_LuaState, a_ChunkDesc, "cChunkDesc"); - if (!CallFunction(4, 1, FnName)) + if (!m_LuaState.CallFunction(4, 1, FnName)) { return false; } @@ -321,7 +260,7 @@ bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_Chu cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_GENERATING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -331,7 +270,7 @@ bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_Chu tolua_pushnumber (m_LuaState, a_ChunkZ); tolua_pushusertype(m_LuaState, a_pLuaChunk, "cChunkDesc"); - if (!CallFunction(4, 1, FnName)) + if (!m_LuaState.CallFunction(4, 1, FnName)) { return false; } @@ -350,7 +289,7 @@ bool cPlugin_NewLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_Chunk cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_UNLOADED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -359,7 +298,7 @@ bool cPlugin_NewLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_Chunk tolua_pushnumber (m_LuaState, a_ChunkX); tolua_pushnumber (m_LuaState, a_ChunkZ); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -378,7 +317,7 @@ bool cPlugin_NewLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_Chun cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_UNLOADING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -387,7 +326,7 @@ bool cPlugin_NewLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_Chun tolua_pushnumber (m_LuaState, a_ChunkX); tolua_pushnumber (m_LuaState, a_ChunkZ); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -406,7 +345,7 @@ bool cPlugin_NewLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_COLLECTING_PICKUP); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -414,7 +353,7 @@ bool cPlugin_NewLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup) tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); tolua_pushusertype(m_LuaState, a_Pickup, "cPickup"); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -433,7 +372,7 @@ bool cPlugin_NewLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftin cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CRAFTING_NO_RECIPE); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -442,7 +381,7 @@ bool cPlugin_NewLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftin tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -461,7 +400,7 @@ bool cPlugin_NewLua::OnDisconnect(cPlayer * a_Player, const AString & a_Reason) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_DISCONNECT); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -469,7 +408,7 @@ bool cPlugin_NewLua::OnDisconnect(cPlayer * a_Player, const AString & a_Reason) tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); tolua_pushstring (m_LuaState, a_Reason.c_str()); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -488,7 +427,7 @@ bool cPlugin_NewLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_EXECUTE_COMMAND); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -508,7 +447,7 @@ bool cPlugin_NewLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & ++index; } - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -527,7 +466,7 @@ bool cPlugin_NewLua::OnHandshake(cClientHandle * a_Client, const AString & a_Use cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_HANDSHAKE); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -535,7 +474,7 @@ bool cPlugin_NewLua::OnHandshake(cClientHandle * a_Client, const AString & a_Use tolua_pushusertype(m_LuaState, a_Client, "cClientHandle"); tolua_pushstring (m_LuaState, a_Username.c_str()); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -554,7 +493,7 @@ bool cPlugin_NewLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_KILLING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -562,7 +501,7 @@ bool cPlugin_NewLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer) tolua_pushusertype(m_LuaState, &a_Victim, "cEntity"); tolua_pushusertype(m_LuaState, a_Killer, "cEntity"); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -581,7 +520,7 @@ bool cPlugin_NewLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, co cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_LOGIN); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -590,7 +529,7 @@ bool cPlugin_NewLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, co tolua_pushnumber (m_LuaState, a_ProtocolVersion); tolua_pushcppstring(m_LuaState, a_Username); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -609,7 +548,7 @@ bool cPlugin_NewLua::OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_BREAKING_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -622,7 +561,7 @@ bool cPlugin_NewLua::OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(7, 1, FnName)) + if (!m_LuaState.CallFunction(7, 1, FnName)) { return false; } @@ -641,7 +580,7 @@ bool cPlugin_NewLua::OnPlayerBrokenBlock(cPlayer & a_Player, int a_BlockX, int a cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_BROKEN_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -654,7 +593,7 @@ bool cPlugin_NewLua::OnPlayerBrokenBlock(cPlayer & a_Player, int a_BlockX, int a tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(7, 1, FnName)) + if (!m_LuaState.CallFunction(7, 1, FnName)) { return false; } @@ -673,14 +612,14 @@ bool cPlugin_NewLua::OnPlayerEating(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_EATING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -699,14 +638,14 @@ bool cPlugin_NewLua::OnPlayerJoined(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_JOINED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -725,7 +664,7 @@ bool cPlugin_NewLua::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_B cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_LEFT_CLICK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -737,7 +676,7 @@ bool cPlugin_NewLua::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_B tolua_pushnumber (m_LuaState, a_BlockFace); tolua_pushnumber (m_LuaState, a_Status); - if (!CallFunction(6, 1, FnName)) + if (!m_LuaState.CallFunction(6, 1, FnName)) { return false; } @@ -756,14 +695,14 @@ bool cPlugin_NewLua::OnPlayerMoved(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_MOVING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -782,7 +721,7 @@ bool cPlugin_NewLua::OnPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_PLACED_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -798,7 +737,7 @@ bool cPlugin_NewLua::OnPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(10, 1, FnName)) { return false; } @@ -817,7 +756,7 @@ bool cPlugin_NewLua::OnPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_PLACING_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -833,7 +772,7 @@ bool cPlugin_NewLua::OnPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(10, 1, FnName)) { return false; } @@ -852,7 +791,7 @@ bool cPlugin_NewLua::OnPlayerRightClick(cPlayer & a_Player, int a_BlockX, int a_ cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_RIGHT_CLICK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -866,7 +805,7 @@ bool cPlugin_NewLua::OnPlayerRightClick(cPlayer & a_Player, int a_BlockX, int a_ tolua_pushnumber (m_LuaState, a_CursorY); tolua_pushnumber (m_LuaState, a_CursorZ); - if (!CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(8, 1, FnName)) { return false; } @@ -885,7 +824,7 @@ bool cPlugin_NewLua::OnPlayerRightClickingEntity(cPlayer & a_Player, cEntity & a cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_RIGHT_CLICKING_ENTITY); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -893,7 +832,7 @@ bool cPlugin_NewLua::OnPlayerRightClickingEntity(cPlayer & a_Player, cEntity & a tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); tolua_pushusertype(m_LuaState, &a_Entity, "cEntity"); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -912,14 +851,14 @@ bool cPlugin_NewLua::OnPlayerShooting(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_SHOOTING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -938,14 +877,14 @@ bool cPlugin_NewLua::OnPlayerSpawned(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_SPAWNED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -964,14 +903,14 @@ bool cPlugin_NewLua::OnPlayerTossingItem(cPlayer & a_Player) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_TOSSING_ITEM); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -990,7 +929,7 @@ bool cPlugin_NewLua::OnPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, int a_B cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_USED_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1006,7 +945,7 @@ bool cPlugin_NewLua::OnPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, int a_B tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(10, 1, FnName)) { return false; } @@ -1025,7 +964,7 @@ bool cPlugin_NewLua::OnPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_Bl cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_USED_ITEM); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1039,7 +978,7 @@ bool cPlugin_NewLua::OnPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_Bl tolua_pushnumber (m_LuaState, a_CursorY); tolua_pushnumber (m_LuaState, a_CursorZ); - if (!CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(8, 1, FnName)) { return false; } @@ -1058,7 +997,7 @@ bool cPlugin_NewLua::OnPlayerUsingBlock(cPlayer & a_Player, int a_BlockX, int a_ cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_USING_BLOCK); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1074,7 +1013,7 @@ bool cPlugin_NewLua::OnPlayerUsingBlock(cPlayer & a_Player, int a_BlockX, int a_ tolua_pushnumber (m_LuaState, a_BlockType); tolua_pushnumber (m_LuaState, a_BlockMeta); - if (!CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(10, 1, FnName)) { return false; } @@ -1093,7 +1032,7 @@ bool cPlugin_NewLua::OnPlayerUsingItem(cPlayer & a_Player, int a_BlockX, int a_B cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PLAYER_USING_ITEM); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1107,7 +1046,7 @@ bool cPlugin_NewLua::OnPlayerUsingItem(cPlayer & a_Player, int a_BlockX, int a_B tolua_pushnumber (m_LuaState, a_CursorY); tolua_pushnumber (m_LuaState, a_CursorZ); - if (!CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(8, 1, FnName)) { return false; } @@ -1126,7 +1065,7 @@ bool cPlugin_NewLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGri cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_POST_CRAFTING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1135,7 +1074,7 @@ bool cPlugin_NewLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGri tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -1154,7 +1093,7 @@ bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_PRE_CRAFTING); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1163,7 +1102,7 @@ bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); - if (!CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(3, 1, FnName)) { return false; } @@ -1182,7 +1121,7 @@ bool cPlugin_NewLua::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_TAKE_DAMAGE); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1190,7 +1129,7 @@ bool cPlugin_NewLua::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI) tolua_pushusertype(m_LuaState, &a_Receiver, "cEntity"); tolua_pushusertype(m_LuaState, &a_TDI, "TakeDamageInfo"); - if (!CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(2, 1, FnName)) { return false; } @@ -1214,7 +1153,7 @@ bool cPlugin_NewLua::OnUpdatedSign( cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_UPDATED_SIGN); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1229,7 +1168,7 @@ bool cPlugin_NewLua::OnUpdatedSign( tolua_pushstring (m_LuaState, a_Line4.c_str()); tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - if (!CallFunction(9, 1, FnName)) + if (!m_LuaState.CallFunction(9, 1, FnName)) { return false; } @@ -1253,7 +1192,7 @@ bool cPlugin_NewLua::OnUpdatingSign( cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_UPDATING_SIGN); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1268,7 +1207,7 @@ bool cPlugin_NewLua::OnUpdatingSign( tolua_pushstring (m_LuaState, a_Line4.c_str()); tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - if (!CallFunction(9, 5, "OnUpdatingSign")) + if (!m_LuaState.CallFunction(9, 5, "OnUpdatingSign")) { return false; } @@ -1303,14 +1242,14 @@ bool cPlugin_NewLua::OnWeatherChanged(cWorld & a_World) cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_WEATHER_CHANGED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } tolua_pushusertype(m_LuaState, &a_World, "cWorld"); - if (!CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1, 1, FnName)) { return false; } @@ -1329,7 +1268,7 @@ bool cPlugin_NewLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_WEATHER_CHANGED); ASSERT(FnName != NULL); - if (!PushFunction(FnName)) + if (!m_LuaState.PushFunction(FnName)) { return false; } @@ -1337,7 +1276,7 @@ bool cPlugin_NewLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather tolua_pushusertype(m_LuaState, &a_World, "cWorld"); tolua_pushnumber (m_LuaState, a_NewWeather); - if (!CallFunction(2, 2, FnName)) + if (!m_LuaState.CallFunction(2, 2, FnName)) { return false; } @@ -1368,29 +1307,22 @@ bool cPlugin_NewLua::HandleCommand(const AStringVector & a_Split, cPlayer * a_Pl cCSLock Lock(m_CriticalSection); // Push the function to be called: - lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, cmd->second); // same as lua_getref() - - // Push the split: - lua_createtable(m_LuaState, a_Split.size(), 0); - int newTable = lua_gettop(m_LuaState); - int index = 1; - std::vector::const_iterator iter = a_Split.begin(), end = a_Split.end(); - while(iter != end) + if (!m_LuaState.PushFunctionFromRegistry(cmd->second)) { - tolua_pushstring(m_LuaState, (*iter).c_str()); - lua_rawseti(m_LuaState, newTable, index); - ++iter; - ++index; + LOGWARNING("Command handler function for \"%s\" is invalid", cmd->first.c_str()); + return false; } + // Push the split: + m_LuaState.PushStringVector(a_Split); + // Push player: tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); // Call function: - int s = lua_pcall(m_LuaState, 2, 1, 0); - if (report_errors(m_LuaState, s)) + if (!m_LuaState.CallFunction(2, 1, __FUNCTION__)) { - LOGERROR("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); + LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; } @@ -1436,10 +1368,9 @@ bool cPlugin_NewLua::HandleConsoleCommand(const AStringVector & a_Split, cComman } // Call function: - int s = lua_pcall(m_LuaState, 1, 2, 0); - if (report_errors(m_LuaState, s)) + if (!m_LuaState.CallFunction(1, 2, __FUNCTION__)) { - LOGERROR("Lua error. Stack size: %i", lua_gettop(m_LuaState)); + LOGWARNING("Lua error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; } @@ -1604,9 +1535,9 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) return ""; sWebPluginTab* Tab = 0; - for( TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr ) + for (TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr) { - if( (*itr)->SafeTitle.compare( SafeTabName ) == 0 ) // This is the one! Rawr + if ((*itr)->SafeTitle.compare(SafeTabName) == 0) // This is the one! Rawr { Tab = *itr; break; @@ -1615,13 +1546,13 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) if( Tab ) { - //LOGINFO("1. Stack size: %i", lua_gettop(m_LuaState) ); + // LOGINFO("1. Stack size: %i", lua_gettop(m_LuaState) ); lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, Tab->UserData); // same as lua_getref() - //LOGINFO("2. Stack size: %i", lua_gettop(m_LuaState) ); + // LOGINFO("2. Stack size: %i", lua_gettop(m_LuaState) ); // Push HTTPRequest tolua_pushusertype( m_LuaState, (void*)a_Request, "const HTTPRequest" ); - //LOGINFO("Calling bound function! :D"); + // LOGINFO("Calling bound function! :D"); int s = lua_pcall( m_LuaState, 1, 1, 0); if ( s != 0 ) @@ -1642,7 +1573,7 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) RetVal += tolua_tostring(m_LuaState, -1, 0); lua_pop(m_LuaState, 1); // Pop return value - //LOGINFO("ok. Stack size: %i", lua_gettop(m_LuaState) ); + // LOGINFO("ok. Stack size: %i", lua_gettop(m_LuaState) ); } return RetVal; @@ -1652,7 +1583,7 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) -bool cPlugin_NewLua::AddWebTab( const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference ) +bool cPlugin_NewLua::AddWebTab(const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference) { cCSLock Lock(m_CriticalSection); if (a_LuaState != m_LuaState) @@ -1666,7 +1597,7 @@ bool cPlugin_NewLua::AddWebTab( const AString & a_Title, lua_State * a_LuaState, Tab->UserData = a_FunctionReference; - GetTabs().push_back( Tab ); + GetTabs().push_back(Tab); return true; } @@ -1715,10 +1646,9 @@ bool cPlugin_NewLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPla tolua_pushboolean (m_LuaState, a_CanRefuse ? 1 : 0); // Call function: - int s = lua_pcall(m_LuaState, 3, 1, 0); - if (report_errors(m_LuaState, s)) + if (!m_LuaState.CallFunction(3, 1, __FUNCTION__)) { - LOGERROR("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); + LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; } @@ -1741,56 +1671,12 @@ void cPlugin_NewLua::CallbackWindowSlotChanged(int a_FnRef, cWindow & a_Window, tolua_pushnumber (m_LuaState, a_SlotNum); // Call function: - int s = lua_pcall(m_LuaState, 2, 0, 0); - if (report_errors(m_LuaState, s)) + if (!m_LuaState.CallFunction(2, 0, __FUNCTION__)) { - LOGERROR("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); + LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); } } - -// Helper functions -bool cPlugin_NewLua::PushFunction(const char * a_FunctionName, bool a_bLogError /* = true */) -{ - if (m_LuaState == NULL) - { - // This happens if Initialize() fails with an error - return false; - } - - lua_getglobal(m_LuaState, a_FunctionName); - if (!lua_isfunction(m_LuaState, -1)) - { - if (a_bLogError) - { - LOGWARN("Error in plugin %s: Could not find function %s()", GetName().c_str(), a_FunctionName); - } - lua_pop(m_LuaState, 1); - return false; - } - return true; -} - - - - - -bool cPlugin_NewLua::CallFunction( int a_NumArgs, int a_NumResults, const char * a_FunctionName) -{ - ASSERT(lua_isfunction(m_LuaState, -a_NumArgs - 1)); - - int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); - if (report_errors(m_LuaState, s)) - { - LOGWARN("Error in plugin %s calling function %s()", GetName().c_str(), a_FunctionName); - return false; - } - return true; -} - - - - diff --git a/source/Plugin_NewLua.h b/source/Plugin_NewLua.h index a79affd5d..d31a62601 100644 --- a/source/Plugin_NewLua.h +++ b/source/Plugin_NewLua.h @@ -3,6 +3,7 @@ #include "Plugin.h" #include "WebPlugin.h" +#include "LuaState.h" // Names for the global variables through which the plugin is identified in its LuaState #define LUA_PLUGIN_NAME_VAR_NAME "_MCServerInternal_PluginName" @@ -11,9 +12,6 @@ -// fwd: Lua -typedef struct lua_State lua_State; - // fwd: UI/Window.h class cWindow; @@ -99,7 +97,7 @@ public: /// Binds the console command to call the function specified by a Lua function reference. Simply adds to CommandMap. void BindConsoleCommand(const AString & a_Command, int a_FnRef); - lua_State * GetLuaState(void) { return m_LuaState; } + cLuaState & GetLuaState(void) { return m_LuaState; } cCriticalSection & GetCriticalSection(void) { return m_CriticalSection; } @@ -114,7 +112,7 @@ public: protected: cCriticalSection m_CriticalSection; - lua_State * m_LuaState; + cLuaState m_LuaState; /// Maps command name into Lua function reference typedef std::map CommandMap; @@ -122,9 +120,6 @@ protected: CommandMap m_Commands; CommandMap m_ConsoleCommands; - bool PushFunction(const char * a_FunctionName, bool a_bLogError = true); - bool CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName ); // a_FunctionName is only used for error messages, nothing else - /// Returns the name of Lua function that should handle the specified hook const char * GetHookFnName(cPluginManager::PluginHook a_Hook); } ; // tolua_export -- cgit v1.2.3 From 2151bb8f5bad91975010ab1022177fdb94cc2a3e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 6 Aug 2013 08:01:00 +0200 Subject: cLuaState can now contain a detached LuaState, too. This will be useful for cases when we get a lua_State * from the outside and are asked to perform operations on it. --- source/LuaState.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ source/LuaState.h | 23 +++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-) (limited to 'source') diff --git a/source/LuaState.cpp b/source/LuaState.cpp index da86a4b20..117023755 100644 --- a/source/LuaState.cpp +++ b/source/LuaState.cpp @@ -37,6 +37,7 @@ extern "C" cLuaState::cLuaState(const AString & a_SubsystemName) : m_LuaState(NULL), + m_IsOwned(false), m_SubsystemName(a_SubsystemName) { } @@ -45,6 +46,17 @@ cLuaState::cLuaState(const AString & a_SubsystemName) : +cLuaState::cLuaState(lua_State * a_AttachState) : + m_LuaState(a_AttachState), + m_IsOwned(false), + m_SubsystemName("") +{ +} + + + + + cLuaState::~cLuaState() { if (IsValid()) @@ -70,6 +82,7 @@ void cLuaState::Create(void) ManualBindings::Bind(m_LuaState); luaopen_lsqlite3(m_LuaState); luaopen_lxp(m_LuaState); + m_IsOwned = true; } @@ -83,8 +96,62 @@ void cLuaState::Close(void) LOGWARNING("%s: Trying to close an invalid LuaState, ignoring.", __FUNCTION__); return; } + if (!m_IsOwned) + { + LOGWARNING( + "%s: Detected mis-use, calling Close() on an attached state (0x%p). Detaching instead.", + __FUNCTION__, m_LuaState + ); + Detach(); + return; + } lua_close(m_LuaState); m_LuaState = NULL; + m_IsOwned = false; +} + + + + + +void cLuaState::Attach(lua_State * a_State) +{ + if (m_LuaState != NULL) + { + LOGINFO("%s: Already contains a LuaState (0x%p), will be closed / detached.", __FUNCTION__, m_LuaState); + if (m_IsOwned) + { + Close(); + } + else + { + Detach(); + } + } + m_LuaState = a_State; + m_IsOwned = false; +} + + + + + +void cLuaState::Detach(void) +{ + if (m_LuaState == NULL) + { + return; + } + if (m_IsOwned) + { + LOGWARNING( + "%s: Detected a mis-use, calling Detach() when the state is owned. Closing the owned state (0x%p).", + __FUNCTION__, m_LuaState + ); + Close(); + return; + } + m_LuaState = NULL; } diff --git a/source/LuaState.h b/source/LuaState.h index 10ff53911..fca532d89 100644 --- a/source/LuaState.h +++ b/source/LuaState.h @@ -3,6 +3,12 @@ // Declares the cLuaState class representing the wrapper over lua_State *, provides associated helper functions +/* +The contained lua_State can be either owned or attached. +Owned lua_State is created by calling Create() and the cLuaState automatically closes the state +Or, lua_State can be attached by calling Attach(), the cLuaState doesn't close such a state +Attaching a state will automatically close an owned state. +*/ @@ -29,16 +35,28 @@ public: */ cLuaState(const AString & a_SubsystemName); + /** Creates a new instance. The a_AttachState is attached. + Subsystem name is set to "". + */ + explicit cLuaState(lua_State * a_AttachState); + ~cLuaState(); + /// Allows this object to be used in the same way as a lua_State *, for example in the LuaLib functions operator lua_State * (void) { return m_LuaState; } - /// Creates the m_LuaState, if not closed already + /// Creates the m_LuaState, if not closed already. This state will be automatically closed in the destructor void Create(void); /// Closes the m_LuaState, if not closed already void Close(void); + /// Attaches the specified state. Operations will be carried out on this state, but it will not be closed in the destructor + void Attach(lua_State * a_State); + + /// Detaches a previously attached state. + void Detach(void); + /// Returns true if the m_LuaState is valid bool IsValid(void) const { return (m_LuaState != NULL); } @@ -79,6 +97,9 @@ public: protected: lua_State * m_LuaState; + /// If true, the state is owned by this object and will be auto-Closed. False => attached state + bool m_IsOwned; + /** The subsystem name is used for reporting errors to the console, it is either "plugin %s" or "LuaScript" whatever is given to the constructor */ -- cgit v1.2.3 From 2030bd47c823b47606e9567a1974761f80cf0d55 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 6 Aug 2013 08:59:54 +0200 Subject: cLuaState now tracks the function name and number of args --- source/LuaState.cpp | 188 +++++++++++++++++- source/LuaState.h | 50 ++++- source/Plugin_NewLua.cpp | 498 ++++++++++++++++++++++------------------------- 3 files changed, 459 insertions(+), 277 deletions(-) (limited to 'source') diff --git a/source/LuaState.cpp b/source/LuaState.cpp index 117023755..e60a0f80c 100644 --- a/source/LuaState.cpp +++ b/source/LuaState.cpp @@ -38,7 +38,8 @@ extern "C" cLuaState::cLuaState(const AString & a_SubsystemName) : m_LuaState(NULL), m_IsOwned(false), - m_SubsystemName(a_SubsystemName) + m_SubsystemName(a_SubsystemName), + m_NumCurrentFunctionArgs(-1) { } @@ -49,7 +50,8 @@ cLuaState::cLuaState(const AString & a_SubsystemName) : cLuaState::cLuaState(lua_State * a_AttachState) : m_LuaState(a_AttachState), m_IsOwned(false), - m_SubsystemName("") + m_SubsystemName(""), + m_NumCurrentFunctionArgs(-1) { } @@ -187,6 +189,8 @@ bool cLuaState::LoadFile(const AString & a_FileName) bool cLuaState::PushFunction(const char * a_FunctionName, bool a_ShouldLogFailure /* = true */) { + ASSERT(m_NumCurrentFunctionArgs == -1); // If not, there's already something pushed onto the stack + if (!IsValid()) { // This happens if cPlugin::Initialize() fails with an error @@ -203,6 +207,8 @@ bool cLuaState::PushFunction(const char * a_FunctionName, bool a_ShouldLogFailur lua_pop(m_LuaState, 1); return false; } + m_CurrentFunctionName.assign(a_FunctionName); + m_NumCurrentFunctionArgs = 0; return true; } @@ -212,12 +218,17 @@ bool cLuaState::PushFunction(const char * a_FunctionName, bool a_ShouldLogFailur bool cLuaState::PushFunctionFromRegistry(int a_FnRef) { + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs == -1); // If not, there's already something pushed onto the stack + lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // same as lua_getref() if (!lua_isfunction(m_LuaState, -1)) { lua_pop(m_LuaState, 1); return false; } + m_CurrentFunctionName = ""; + m_NumCurrentFunctionArgs = 0; return true; } @@ -227,6 +238,9 @@ bool cLuaState::PushFunctionFromRegistry(int a_FnRef) void cLuaState::PushStringVector(const AStringVector & a_Vector) { + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + lua_createtable(m_LuaState, a_Vector.size(), 0); int newTable = lua_gettop(m_LuaState); int index = 1; @@ -235,22 +249,184 @@ void cLuaState::PushStringVector(const AStringVector & a_Vector) tolua_pushstring(m_LuaState, itr->c_str()); lua_rawseti(m_LuaState, newTable, index); } + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushUserType(void * a_Object, const char * a_Type) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Object, a_Type); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushNumber(int a_Value) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushnumber(m_LuaState, a_Value); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushNumber(double a_Value) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushnumber(m_LuaState, a_Value); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushString(const char * a_Value) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushstring(m_LuaState, a_Value); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushBool(bool a_Value) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushboolean(m_LuaState, a_Value ? 1 : 0); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cWorld * a_World) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_World, "cWorld"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cPlayer * a_Player) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cEntity * a_Entity) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Entity, "cEntity"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cItem * a_Item) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Item, "cItem"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cItems * a_Items) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Items, "cItems"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cClientHandle * a_Client) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Client, "cClientHandle"); + m_NumCurrentFunctionArgs += 1; +} + + + + + +void cLuaState::PushObject(cPickup * a_Pickup) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + + tolua_pushusertype(m_LuaState, a_Pickup, "cPickup"); + m_NumCurrentFunctionArgs += 1; } -bool cLuaState::CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName) +bool cLuaState::CallFunction(int a_NumResults) { - ASSERT(lua_isfunction(m_LuaState, -a_NumArgs - 1)); + ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first + ASSERT(lua_isfunction(m_LuaState, -m_NumCurrentFunctionArgs - 1)); - int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); + int s = lua_pcall(m_LuaState, m_NumCurrentFunctionArgs, a_NumResults, 0); if (ReportErrors(s)) { - LOGWARNING("Error in %s calling function %s()", m_SubsystemName.c_str(), a_FunctionName); + LOGWARNING("Error in %s calling function %s()", m_SubsystemName.c_str(), m_CurrentFunctionName); + m_NumCurrentFunctionArgs = -1; + m_CurrentFunctionName.clear(); return false; } + m_NumCurrentFunctionArgs = -1; + m_CurrentFunctionName.clear(); return true; } diff --git a/source/LuaState.h b/source/LuaState.h index fca532d89..18c7c1354 100644 --- a/source/LuaState.h +++ b/source/LuaState.h @@ -8,6 +8,11 @@ The contained lua_State can be either owned or attached. Owned lua_State is created by calling Create() and the cLuaState automatically closes the state Or, lua_State can be attached by calling Attach(), the cLuaState doesn't close such a state Attaching a state will automatically close an owned state. + +Calling a Lua function is done by pushing the function, either by PushFunction() or PushFunctionFromRegistry(), +then pushing the arguments (PushString(), PushNumber(), PushUserData() etc.) and finally +executing CallFunction(). cLuaState automatically keeps track of the number of arguments and the name of the +function (for logging purposes), which makes the call less error-prone. */ @@ -22,6 +27,14 @@ Attaching a state will automatically close an owned state. // fwd: lua.h struct lua_State; +class cWorld; +class cPlayer; +class cEntity; +class cItem; +class cItems; +class cClientHandle; +class cPickup; + @@ -80,13 +93,36 @@ public: /// Pushes a string vector, as a table, onto the stack void PushStringVector(const AStringVector & a_Vector); + /// Pushes a usertype of the specified class type onto the stack + void PushUserType(void * a_Object, const char * a_Type); + + /// Pushes an integer onto the stack + void PushNumber(int a_Value); + + /// Pushes a double onto the stack + void PushNumber(double a_Value); + + /// Pushes a string onto the stack + void PushString(const char * a_Value); + + /// Pushes a bool onto the stack + void PushBool(bool a_Value); + + // Special family of functions that do PushUserType internally, but require one less parameter + void PushObject(cWorld * a_World); + void PushObject(cPlayer * a_Player); + void PushObject(cEntity * a_Entity); + void PushObject(cItem * a_Item); + void PushObject(cItems * a_Items); + void PushObject(cClientHandle * a_ClientHandle); + void PushObject(cPickup * a_Pickup); + /** - Calls the function that has been pushed onto the stack by PushFunction. + Calls the function that has been pushed onto the stack by PushFunction(), + with arguments pushed by PushXXX(). Returns true if successful, logs a warning on failure. - a_FunctionName is used only for the warning log message, the function - to be called must be pushed by PushFunction() beforehand. */ - bool CallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName); + bool CallFunction(int a_NumReturnValues); /// If the status is nonzero, prints the text on the top of Lua stack and returns true bool ReportErrors(int status); @@ -104,6 +140,12 @@ protected: whatever is given to the constructor */ AString m_SubsystemName; + + /// Name of the currently pushed function (for the Push / Call chain) + AString m_CurrentFunctionName; + + /// Number of arguments currently pushed (for the Push / Call chain) + int m_NumCurrentFunctionArgs; } ; diff --git a/source/Plugin_NewLua.cpp b/source/Plugin_NewLua.cpp index 51d16c839..b3dac7912 100644 --- a/source/Plugin_NewLua.cpp +++ b/source/Plugin_NewLua.cpp @@ -78,9 +78,9 @@ bool cPlugin_NewLua::Initialize(void) return false; } - tolua_pushusertype(m_LuaState, this, "cPlugin_NewLua"); + m_LuaState.PushUserType(this, "cPlugin_NewLua"); - if (!m_LuaState.CallFunction(1, 1, "Initialize")) + if (!m_LuaState.CallFunction(1)) { m_LuaState.Close(); return false; @@ -109,7 +109,7 @@ void cPlugin_NewLua::OnDisable() return; } - m_LuaState.CallFunction(0, 0, "OnDisable"); + m_LuaState.CallFunction(0); } @@ -124,10 +124,8 @@ void cPlugin_NewLua::Tick(float a_Dt) { return; } - - tolua_pushnumber( m_LuaState, a_Dt ); - - m_LuaState.CallFunction(1, 0, FnName); + m_LuaState.PushNumber(a_Dt); + m_LuaState.CallFunction(0); } @@ -144,16 +142,16 @@ bool cPlugin_NewLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int return false; } - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushusertype(m_LuaState, a_Digger, "cEntity"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); - tolua_pushusertype(m_LuaState, &a_Pickups, "cItems"); + m_LuaState.PushObject(a_World); + m_LuaState.PushObject(a_Digger); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); + m_LuaState.PushObject(&a_Pickups); - if (!m_LuaState.CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -177,10 +175,10 @@ bool cPlugin_NewLua::OnChat(cPlayer * a_Player, AString & a_Message) return false; } - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - tolua_pushstring (m_LuaState, a_Message.c_str()); + m_LuaState.PushObject(a_Player); + m_LuaState.PushString(a_Message.c_str()); - if (!m_LuaState.CallFunction(2, 2, FnName)) + if (!m_LuaState.CallFunction(2)) { return false; } @@ -208,11 +206,11 @@ bool cPlugin_NewLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_Chun return false; } - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_ChunkX); - tolua_pushnumber (m_LuaState, a_ChunkZ); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_ChunkX); + m_LuaState.PushNumber(a_ChunkZ); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -236,12 +234,12 @@ bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_Chun return false; } - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_ChunkX); - tolua_pushnumber (m_LuaState, a_ChunkZ); - tolua_pushusertype(m_LuaState, a_ChunkDesc, "cChunkDesc"); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_ChunkX); + m_LuaState.PushNumber(a_ChunkZ); + m_LuaState.PushUserType(a_ChunkDesc, "cChunkDesc"); - if (!m_LuaState.CallFunction(4, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -255,7 +253,7 @@ bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_Chun -bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_pLuaChunk) +bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) { cCSLock Lock(m_CriticalSection); const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_GENERATING); @@ -265,12 +263,12 @@ bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_Chu return false; } - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_ChunkX); - tolua_pushnumber (m_LuaState, a_ChunkZ); - tolua_pushusertype(m_LuaState, a_pLuaChunk, "cChunkDesc"); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_ChunkX); + m_LuaState.PushNumber(a_ChunkZ); + m_LuaState.PushUserType(a_ChunkDesc, "cChunkDesc"); - if (!m_LuaState.CallFunction(4, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -294,11 +292,11 @@ bool cPlugin_NewLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_Chunk return false; } - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_ChunkX); - tolua_pushnumber (m_LuaState, a_ChunkZ); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_ChunkX); + m_LuaState.PushNumber(a_ChunkZ); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -322,11 +320,11 @@ bool cPlugin_NewLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_Chun return false; } - tolua_pushusertype(m_LuaState, a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_ChunkX); - tolua_pushnumber (m_LuaState, a_ChunkZ); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_ChunkX); + m_LuaState.PushNumber(a_ChunkZ); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -350,10 +348,10 @@ bool cPlugin_NewLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup) return false; } - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, a_Pickup, "cPickup"); + m_LuaState.PushObject(a_Player); + m_LuaState.PushObject(a_Pickup); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -377,11 +375,11 @@ bool cPlugin_NewLua::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftin return false; } - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); - tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); + m_LuaState.PushUserType((void *)a_Player, "cPlayer"); + m_LuaState.PushUserType((void *)a_Grid, "cCraftingGrid"); + m_LuaState.PushUserType((void *)a_Recipe, "cCraftingRecipe"); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -405,10 +403,10 @@ bool cPlugin_NewLua::OnDisconnect(cPlayer * a_Player, const AString & a_Reason) return false; } - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - tolua_pushstring (m_LuaState, a_Reason.c_str()); + m_LuaState.PushObject(a_Player); + m_LuaState.PushString(a_Reason.c_str()); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -432,22 +430,10 @@ bool cPlugin_NewLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & return false; } - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); - - // Push the split: - lua_createtable(m_LuaState, a_Split.size(), 0); - int newTable = lua_gettop(m_LuaState); - int index = 1; - std::vector::const_iterator iter = a_Split.begin(), end = a_Split.end(); - while(iter != end) - { - tolua_pushstring(m_LuaState, (*iter).c_str()); - lua_rawseti(m_LuaState, newTable, index); - ++iter; - ++index; - } + m_LuaState.PushObject(a_Player); + m_LuaState.PushStringVector(a_Split); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -471,10 +457,10 @@ bool cPlugin_NewLua::OnHandshake(cClientHandle * a_Client, const AString & a_Use return false; } - tolua_pushusertype(m_LuaState, a_Client, "cClientHandle"); - tolua_pushstring (m_LuaState, a_Username.c_str()); + m_LuaState.PushUserType(a_Client, "cClientHandle"); + m_LuaState.PushString (a_Username.c_str()); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -498,10 +484,10 @@ bool cPlugin_NewLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer) return false; } - tolua_pushusertype(m_LuaState, &a_Victim, "cEntity"); - tolua_pushusertype(m_LuaState, a_Killer, "cEntity"); + m_LuaState.PushObject(&a_Victim); + m_LuaState.PushObject(a_Killer); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -525,11 +511,11 @@ bool cPlugin_NewLua::OnLogin(cClientHandle * a_Client, int a_ProtocolVersion, co return false; } - tolua_pushusertype (m_LuaState, a_Client, "cClientHandle"); - tolua_pushnumber (m_LuaState, a_ProtocolVersion); - tolua_pushcppstring(m_LuaState, a_Username); + m_LuaState.PushObject(a_Client); + m_LuaState.PushNumber(a_ProtocolVersion); + m_LuaState.PushString(a_Username.c_str()); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -553,15 +539,15 @@ bool cPlugin_NewLua::OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); - if (!m_LuaState.CallFunction(7, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -585,15 +571,15 @@ bool cPlugin_NewLua::OnPlayerBrokenBlock(cPlayer & a_Player, int a_BlockX, int a return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); - if (!m_LuaState.CallFunction(7, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -617,9 +603,9 @@ bool cPlugin_NewLua::OnPlayerEating(cPlayer & a_Player) return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + m_LuaState.PushObject(&a_Player); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -643,9 +629,9 @@ bool cPlugin_NewLua::OnPlayerJoined(cPlayer & a_Player) return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + m_LuaState.PushObject(&a_Player); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -669,14 +655,14 @@ bool cPlugin_NewLua::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_B return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_Status); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_Status); - if (!m_LuaState.CallFunction(6, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -700,9 +686,9 @@ bool cPlugin_NewLua::OnPlayerMoved(cPlayer & a_Player) return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + m_LuaState.PushObject(&a_Player); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -726,18 +712,18 @@ bool cPlugin_NewLua::OnPlayerPlacedBlock(cPlayer & a_Player, int a_BlockX, int a return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); - if (!m_LuaState.CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -761,18 +747,18 @@ bool cPlugin_NewLua::OnPlayerPlacingBlock(cPlayer & a_Player, int a_BlockX, int return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); - if (!m_LuaState.CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -796,16 +782,16 @@ bool cPlugin_NewLua::OnPlayerRightClick(cPlayer & a_Player, int a_BlockX, int a_ return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); - if (!m_LuaState.CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -829,10 +815,10 @@ bool cPlugin_NewLua::OnPlayerRightClickingEntity(cPlayer & a_Player, cEntity & a return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, &a_Entity, "cEntity"); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushObject(&a_Entity); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -856,9 +842,9 @@ bool cPlugin_NewLua::OnPlayerShooting(cPlayer & a_Player) return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + m_LuaState.PushObject(&a_Player); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -882,9 +868,9 @@ bool cPlugin_NewLua::OnPlayerSpawned(cPlayer & a_Player) return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + m_LuaState.PushObject(&a_Player); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -908,9 +894,9 @@ bool cPlugin_NewLua::OnPlayerTossingItem(cPlayer & a_Player) return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); + m_LuaState.PushObject(&a_Player); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -934,18 +920,18 @@ bool cPlugin_NewLua::OnPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, int a_B return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); - if (!m_LuaState.CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -969,16 +955,16 @@ bool cPlugin_NewLua::OnPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_Bl return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); - if (!m_LuaState.CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1002,18 +988,18 @@ bool cPlugin_NewLua::OnPlayerUsingBlock(cPlayer & a_Player, int a_BlockX, int a_ return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); - tolua_pushnumber (m_LuaState, a_BlockType); - tolua_pushnumber (m_LuaState, a_BlockMeta); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); - if (!m_LuaState.CallFunction(10, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1037,16 +1023,16 @@ bool cPlugin_NewLua::OnPlayerUsingItem(cPlayer & a_Player, int a_BlockX, int a_B return false; } - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushnumber (m_LuaState, a_BlockFace); - tolua_pushnumber (m_LuaState, a_CursorX); - tolua_pushnumber (m_LuaState, a_CursorY); - tolua_pushnumber (m_LuaState, a_CursorZ); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockFace); + m_LuaState.PushNumber(a_CursorX); + m_LuaState.PushNumber(a_CursorY); + m_LuaState.PushNumber(a_CursorZ); - if (!m_LuaState.CallFunction(8, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1070,11 +1056,11 @@ bool cPlugin_NewLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGri return false; } - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); - tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); + m_LuaState.PushUserType((void *)a_Player, "cPlayer"); + m_LuaState.PushUserType((void *)a_Grid, "cCraftingGrid"); + m_LuaState.PushUserType((void *)a_Recipe, "cCraftingRecipe"); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1098,11 +1084,11 @@ bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid return false; } - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); - tolua_pushusertype(m_LuaState, (void *)a_Grid, "cCraftingGrid"); - tolua_pushusertype(m_LuaState, (void *)a_Recipe, "cCraftingRecipe"); + m_LuaState.PushUserType((void *)a_Player, "cPlayer"); + m_LuaState.PushUserType((void *)a_Grid, "cCraftingGrid"); + m_LuaState.PushUserType((void *)a_Recipe, "cCraftingRecipe"); - if (!m_LuaState.CallFunction(3, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1126,10 +1112,10 @@ bool cPlugin_NewLua::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI) return false; } - tolua_pushusertype(m_LuaState, &a_Receiver, "cEntity"); - tolua_pushusertype(m_LuaState, &a_TDI, "TakeDamageInfo"); + m_LuaState.PushObject(&a_Receiver); + m_LuaState.PushUserType(&a_TDI, "TakeDamageInfo"); - if (!m_LuaState.CallFunction(2, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1158,17 +1144,17 @@ bool cPlugin_NewLua::OnUpdatedSign( return false; } - tolua_pushusertype(m_LuaState, (void *)a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushstring (m_LuaState, a_Line1.c_str()); - tolua_pushstring (m_LuaState, a_Line2.c_str()); - tolua_pushstring (m_LuaState, a_Line3.c_str()); - tolua_pushstring (m_LuaState, a_Line4.c_str()); - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushString(a_Line1.c_str()); + m_LuaState.PushString(a_Line2.c_str()); + m_LuaState.PushString(a_Line3.c_str()); + m_LuaState.PushString(a_Line4.c_str()); + m_LuaState.PushObject(a_Player); - if (!m_LuaState.CallFunction(9, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1197,17 +1183,17 @@ bool cPlugin_NewLua::OnUpdatingSign( return false; } - tolua_pushusertype(m_LuaState, (void *)a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_BlockX); - tolua_pushnumber (m_LuaState, a_BlockY); - tolua_pushnumber (m_LuaState, a_BlockZ); - tolua_pushstring (m_LuaState, a_Line1.c_str()); - tolua_pushstring (m_LuaState, a_Line2.c_str()); - tolua_pushstring (m_LuaState, a_Line3.c_str()); - tolua_pushstring (m_LuaState, a_Line4.c_str()); - tolua_pushusertype(m_LuaState, (void *)a_Player, "cPlayer"); + m_LuaState.PushObject(a_World); + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushString(a_Line1.c_str()); + m_LuaState.PushString(a_Line2.c_str()); + m_LuaState.PushString(a_Line3.c_str()); + m_LuaState.PushString(a_Line4.c_str()); + m_LuaState.PushObject(a_Player); - if (!m_LuaState.CallFunction(9, 5, "OnUpdatingSign")) + if (!m_LuaState.CallFunction(5)) { return false; } @@ -1247,9 +1233,9 @@ bool cPlugin_NewLua::OnWeatherChanged(cWorld & a_World) return false; } - tolua_pushusertype(m_LuaState, &a_World, "cWorld"); + m_LuaState.PushObject(&a_World); - if (!m_LuaState.CallFunction(1, 1, FnName)) + if (!m_LuaState.CallFunction(1)) { return false; } @@ -1273,10 +1259,10 @@ bool cPlugin_NewLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather return false; } - tolua_pushusertype(m_LuaState, &a_World, "cWorld"); - tolua_pushnumber (m_LuaState, a_NewWeather); + m_LuaState.PushObject(&a_World); + m_LuaState.PushNumber(a_NewWeather); - if (!m_LuaState.CallFunction(2, 2, FnName)) + if (!m_LuaState.CallFunction(2)) { return false; } @@ -1313,14 +1299,11 @@ bool cPlugin_NewLua::HandleCommand(const AStringVector & a_Split, cPlayer * a_Pl return false; } - // Push the split: m_LuaState.PushStringVector(a_Split); - - // Push player: - tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + m_LuaState.PushObject(a_Player); // Call function: - if (!m_LuaState.CallFunction(2, 1, __FUNCTION__)) + if (!m_LuaState.CallFunction(1)) { LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; @@ -1352,23 +1335,12 @@ bool cPlugin_NewLua::HandleConsoleCommand(const AStringVector & a_Split, cComman cCSLock Lock(m_CriticalSection); // Push the function to be called: - lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, cmd->second); // same as lua_getref() + m_LuaState.PushFunctionFromRegistry(cmd->second); - // Push the split: - lua_createtable(m_LuaState, a_Split.size(), 0); - int newTable = lua_gettop(m_LuaState); - int index = 1; - std::vector::const_iterator iter = a_Split.begin(), end = a_Split.end(); - while(iter != end) - { - tolua_pushstring(m_LuaState, (*iter).c_str()); - lua_rawseti(m_LuaState, newTable, index); - ++iter; - ++index; - } + m_LuaState.PushStringVector(a_Split); // Call function: - if (!m_LuaState.CallFunction(1, 2, __FUNCTION__)) + if (!m_LuaState.CallFunction(2)) { LOGWARNING("Lua error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; @@ -1546,29 +1518,21 @@ AString cPlugin_NewLua::HandleWebRequest(const HTTPRequest * a_Request ) if( Tab ) { - // LOGINFO("1. Stack size: %i", lua_gettop(m_LuaState) ); - lua_rawgeti( m_LuaState, LUA_REGISTRYINDEX, Tab->UserData); // same as lua_getref() + m_LuaState.PushFunctionFromRegistry(Tab->UserData); - // LOGINFO("2. Stack size: %i", lua_gettop(m_LuaState) ); // Push HTTPRequest - tolua_pushusertype( m_LuaState, (void*)a_Request, "const HTTPRequest" ); - // LOGINFO("Calling bound function! :D"); - int s = lua_pcall( m_LuaState, 1, 1, 0); - - if ( s != 0 ) + m_LuaState.PushUserType((void*)a_Request, "const HTTPRequest"); + + if (!m_LuaState.CallFunction(1)) { - std::string err = lua_tostring(m_LuaState, -1); - LOGERROR("-- %s", err.c_str() ); - lua_pop(m_LuaState, 1); - LOGINFO("error. Stack size: %i", lua_gettop(m_LuaState) ); - return err; // Show the error message in the web page, looks cool + return "Lua encountered error while processing the page request"; } - if( !lua_isstring( m_LuaState, -1 ) ) + if (!lua_isstring(m_LuaState, -1)) { - LOGWARN("WARNING: WebPlugin tab '%s' did not return a string!", Tab->Title.c_str() ); - lua_pop(m_LuaState, 1); // Pop return value - return std::string("WARNING: WebPlugin tab '") + Tab->Title + std::string("' did not return a string!"); + LOGWARNING("WebPlugin tab '%s' did not return a string!", Tab->Title.c_str()); + lua_pop(m_LuaState, 1); // Pop return value + return Printf("WARNING: WebPlugin tab '%s' did not return a string!", Tab->Title.c_str()); } RetVal += tolua_tostring(m_LuaState, -1, 0); @@ -1640,13 +1604,13 @@ bool cPlugin_NewLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPla ASSERT(a_FnRef != LUA_REFNIL); cCSLock Lock(m_CriticalSection); - lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // Push the function to be called - tolua_pushusertype(m_LuaState, &a_Window, "cWindow"); - tolua_pushusertype(m_LuaState, &a_Player, "cPlayer"); - tolua_pushboolean (m_LuaState, a_CanRefuse ? 1 : 0); + m_LuaState.PushFunctionFromRegistry(a_FnRef); + m_LuaState.PushUserType(&a_Window, "cWindow"); + m_LuaState.PushObject(&a_Player); + m_LuaState.PushBool(a_CanRefuse); // Call function: - if (!m_LuaState.CallFunction(3, 1, __FUNCTION__)) + if (!m_LuaState.CallFunction(1)) { LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); return false; @@ -1666,12 +1630,12 @@ void cPlugin_NewLua::CallbackWindowSlotChanged(int a_FnRef, cWindow & a_Window, ASSERT(a_FnRef != LUA_REFNIL); cCSLock Lock(m_CriticalSection); - lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // Push the function to be called - tolua_pushusertype(m_LuaState, &a_Window, "cWindow"); - tolua_pushnumber (m_LuaState, a_SlotNum); + m_LuaState.PushFunctionFromRegistry(a_FnRef); + m_LuaState.PushUserType(&a_Window, "cWindow"); + m_LuaState.PushNumber(a_SlotNum); // Call function: - if (!m_LuaState.CallFunction(2, 0, __FUNCTION__)) + if (!m_LuaState.CallFunction(0)) { LOGWARNING("LUA error in %s. Stack size: %i", __FUNCTION__, lua_gettop(m_LuaState)); } -- cgit v1.2.3 From 4034136922a5b47450fa25c6be4bc35411a8d1ba Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 6 Aug 2013 17:17:26 +0200 Subject: cLuaState is used for pushing splits in ManualBindings --- source/ManualBindings.cpp | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) (limited to 'source') diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 141335602..292b33726 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -25,13 +25,6 @@ -// fwd: LuaCommandBinder.cpp -// bool cLuaState::ReportErrors(lua_State* lua, int status); - - - - - /**************************** * Better error reporting for Lua **/ @@ -84,23 +77,14 @@ int lua_do_error(lua_State* L, const char * a_pFormat, ...) * Lua bound functions with special return types **/ -static int tolua_StringSplit(lua_State* tolua_S) +static int tolua_StringSplit(lua_State * tolua_S) { - std::string str = ((std::string) tolua_tocppstring(tolua_S,1,0)); - std::string delim = ((std::string) tolua_tocppstring(tolua_S,2,0)); - - AStringVector Split = StringSplit( str, delim ); + cLuaState LuaState(tolua_S); + std::string str = (std::string)tolua_tocppstring(LuaState, 1, 0); + std::string delim = (std::string)tolua_tocppstring(LuaState, 2, 0); - lua_createtable(tolua_S, Split.size(), 0); - int newTable = lua_gettop(tolua_S); - int index = 1; - std::vector::const_iterator iter = Split.begin(); - while(iter != Split.end()) { - tolua_pushstring( tolua_S, (*iter).c_str() ); - lua_rawseti(tolua_S, newTable, index); - ++iter; - ++index; - } + AStringVector Split = StringSplit(str, delim); + LuaState.PushStringVector(Split); return 1; } @@ -158,7 +142,8 @@ cPlugin_NewLua * GetLuaPlugin(lua_State * L) lua_getglobal(L, LUA_PLUGIN_INSTANCE_VAR_NAME); if (!lua_islightuserdata(L, -1)) { - LOGERROR("%s: cannot get plugin instance, what have you done to my Lua state?", __FUNCTION__); + LOGWARNING("%s: cannot get plugin instance, what have you done to my Lua state?", __FUNCTION__); + lua_pop(L); return NULL; } cPlugin_NewLua * Plugin = (cPlugin_NewLua *)lua_topointer(L, -1); -- cgit v1.2.3 From 0281b1db6e862af628bd9ea6712ce7e2f66cc4d8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 6 Aug 2013 19:27:48 +0200 Subject: Fixed compilation in ManualBindings --- source/ManualBindings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source') diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index 292b33726..f428b0905 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -143,7 +143,7 @@ cPlugin_NewLua * GetLuaPlugin(lua_State * L) if (!lua_islightuserdata(L, -1)) { LOGWARNING("%s: cannot get plugin instance, what have you done to my Lua state?", __FUNCTION__); - lua_pop(L); + lua_pop(L, 1); return NULL; } cPlugin_NewLua * Plugin = (cPlugin_NewLua *)lua_topointer(L, -1); -- cgit v1.2.3 From c55fabb5ad34ec57760b90ea11960f7f426990db Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 6 Aug 2013 19:28:09 +0200 Subject: cLuaScript now uses cLuaState --- source/LuaScript.cpp | 232 ++++----------------------------------------------- source/LuaScript.h | 36 ++++---- source/LuaState.cpp | 2 +- source/WebAdmin.cpp | 8 +- 4 files changed, 36 insertions(+), 242 deletions(-) (limited to 'source') diff --git a/source/LuaScript.cpp b/source/LuaScript.cpp index 8d92c238f..f27d1793f 100644 --- a/source/LuaScript.cpp +++ b/source/LuaScript.cpp @@ -9,31 +9,16 @@ extern "C" { -#include "lualib.h" + #include "lualib.h" } - #include "tolua++.h" -#include "Bindings.h" -#include "ManualBindings.h" - -// fwd: SQLite/lsqlite3.c -extern "C" -{ - LUALIB_API int luaopen_lsqlite3(lua_State * L); -} - -// fwd: LuaExpat/lxplib.c: -extern "C" -{ - int luaopen_lxp(lua_State * L); -} cLuaScript::cLuaScript() - : m_LuaState(NULL) + : m_LuaState("cLuaScript") { } @@ -42,166 +27,45 @@ cLuaScript::cLuaScript() -cLuaScript::~cLuaScript() -{ - if( m_LuaState ) - { - lua_close( m_LuaState ); - m_LuaState = 0; - } -} - - - - - void cLuaScript::Initialize() { // Check to see if this script has not been initialized before - ASSERT(!m_LuaState); + ASSERT(!m_LuaState.IsValid()); // Create a Lua state and bind all libraries to it - m_LuaState = lua_open(); - luaL_openlibs(m_LuaState); - tolua_AllToLua_open(m_LuaState); - ManualBindings::Bind(m_LuaState); - luaopen_lsqlite3(m_LuaState); - luaopen_lxp(m_LuaState); + m_LuaState.Create(); } -bool cLuaScript::LoadFile( const char* a_FilePath ) +bool cLuaScript::LoadFile(const char * a_FilePath) { // Make sure the plugin is initialized - ASSERT(m_LuaState); - - // Load the file into the Lua state - int s = luaL_loadfile(m_LuaState, a_FilePath ); - if (ReportErrors(s)) - { - return false; - } - return true; -} - - - - - -bool cLuaScript::Execute() -{ - // Make sure we got a Lua state - ASSERT(m_LuaState); - - // Execute the script as it is right now - int s = lua_pcall(m_LuaState, 0, LUA_MULTRET, 0); - if( ReportErrors( s ) ) - { - return false; - } - return true; -} - - + ASSERT(m_LuaState.IsValid()); - - -bool cLuaScript::ReportErrors( int a_Status ) -{ - if (a_Status == 0) - { - // No error to report - return false; - } - - // Status was set to error so get the error from the Lua state and log it - LOGERROR("LUA: %s", lua_tostring(m_LuaState, -1)); - lua_pop(m_LuaState, 1); - - // Return true to indicate that an error was returned - return true; + return m_LuaState.LoadFile(a_FilePath); } -bool cLuaScript::LuaPushFunction( const char * a_FunctionName, bool a_bLogError /*= true*/ ) +bool cLuaScript::CallShowPage(cWebAdmin & a_WebAdmin, HTTPTemplateRequest & a_Request, AString & a_ReturnedString) { - ASSERT(m_LuaState); - - // Find and push the function on the Lua stack - lua_getglobal(m_LuaState, a_FunctionName); - - // Make sure we found a function - if (!lua_isfunction(m_LuaState, -1)) - { - if (a_bLogError) - { - LOGWARN("LUA: Could not find function %s()", a_FunctionName); - } - - // Pop the pushed 'object' back - lua_pop(m_LuaState, 1); - return false; - } - - // Successfully pushed a function to the Lua stack - return true; -} - - - - - -bool cLuaScript::LuaCallFunction( int a_NumArgs, int a_NumResults, const char * a_FunctionName ) -{ - ASSERT(m_LuaState); - - // Make sure there's a lua function on the stack - ASSERT(lua_isfunction(m_LuaState, -a_NumArgs - 1)); - - // Call the desired function - int s = lua_pcall(m_LuaState, a_NumArgs, a_NumResults, 0); - - // Check for errors - if (ReportErrors(s)) + ASSERT(m_LuaState.IsValid()); + + m_LuaState.PushFunction("ShowPage"); + m_LuaState.PushUserType(&a_WebAdmin, "cWebAdmin"); + m_LuaState.PushUserType(&a_Request, "HTTPTemplateRequest"); + if (!m_LuaState.CallFunction(1)) { - LOGWARN("LUA: Error calling function %s()", a_FunctionName); return false; } - - // Successfully executed function - return true; -} - - - - - -bool cLuaScript::CallFunction( const char* a_Function, AString& ReturnedString ) -{ - // Make sure we have the required things to call a function - ASSERT(m_LuaState); - ASSERT(a_Function); - - // Push the desired function on the stack - if (!LuaPushFunction(a_Function)) - { - return false; - } - - if (!LuaCallFunction(0, 1, a_Function)) - { - return false; - } - if (lua_isstring(m_LuaState, -1)) { - ReturnedString = tolua_tostring(m_LuaState, -1, ""); + a_ReturnedString.assign(tolua_tostring(m_LuaState, -1, "")); } lua_pop(m_LuaState, 1); return true; @@ -210,69 +74,3 @@ bool cLuaScript::CallFunction( const char* a_Function, AString& ReturnedString ) - -bool cLuaScript::CallFunction( const char* a_Function, const sLuaUsertype& a_UserType, AString& ReturnedString ) -{ - // Make sure we have the required things to call a function - ASSERT(m_LuaState); - ASSERT(a_Function); - - // Push the desired function on the stack - if (!LuaPushFunction(a_Function)) - { - return false; - } - - tolua_pushusertype(m_LuaState, a_UserType.Object, a_UserType.ClassName); - - if (!LuaCallFunction(1, 1, a_Function)) - { - return false; - } - - if (lua_isstring(m_LuaState, -1)) - { - ReturnedString = tolua_tostring(m_LuaState, -1, ""); - } - lua_pop(m_LuaState, 1); - return true; -} - - - - - -bool cLuaScript::CallFunction( const char* a_Function, const sLuaUsertype& a_UserType1, const sLuaUsertype& a_UserType2, AString& ReturnedString ) -{ - // Make sure we have the required things to call a function - ASSERT(m_LuaState); - ASSERT(a_Function); - - // Push the desired function on the stack - if (!LuaPushFunction(a_Function)) - { - return false; - } - - tolua_pushusertype(m_LuaState, a_UserType1.Object, a_UserType1.ClassName); - tolua_pushusertype(m_LuaState, a_UserType2.Object, a_UserType2.ClassName); - - if (!LuaCallFunction(2, 1, a_Function)) - { - return false; - } - - if (lua_isstring(m_LuaState, -1)) - { - ReturnedString = tolua_tostring(m_LuaState, -1, ""); - } - lua_pop(m_LuaState, 1); - return true; -} - - - - - - - diff --git a/source/LuaScript.h b/source/LuaScript.h index f98b2e65b..6c224e115 100644 --- a/source/LuaScript.h +++ b/source/LuaScript.h @@ -9,12 +9,13 @@ #pragma once -struct lua_State; +#include "LuaState.h" +/* struct sLuaUsertype { sLuaUsertype(void* a_pObject, const char* a_pClassName) : Object(a_pObject), ClassName(a_pClassName) {} @@ -22,6 +23,15 @@ struct sLuaUsertype void* Object; const char* ClassName; } ; +*/ + + + + + +// fwd: +class cWebAdmin; +struct HTTPTemplateRequest; @@ -30,32 +40,18 @@ struct sLuaUsertype class cLuaScript { public: - cLuaScript(); - ~cLuaScript(); + cLuaScript(void); /// Prepares a Lua state - void Initialize(); + void Initialize(); /// Load a Lua script on the given path - bool LoadFile(const char* a_FilePath); - - /// Execute the loaded Lua script - bool Execute(); + bool LoadFile(const char * a_FilePath); - /// Call a function on the Lua script. Put all overloads here - bool CallFunction(const char* a_Function, AString& ReturnedString); - bool CallFunction(const char* a_Function, const sLuaUsertype& a_UserType, AString& ReturnedString); - bool CallFunction(const char* a_Function, const sLuaUsertype& a_UserType1, const sLuaUsertype& a_UserType2, AString& ReturnedString); + bool CallShowPage(cWebAdmin & a_WebAdmin, HTTPTemplateRequest & a_Request, AString & a_ReturnedString); protected: - /// Reports an error in the log if a_Status is flagged as an error. Returns true when a_Status is flagged as error, returns false when no error occured. - bool ReportErrors(int a_Status); - - /// Helper functions for calling functions in Lua - bool LuaPushFunction(const char * a_FunctionName, bool a_bLogError = true); - bool LuaCallFunction(int a_NumArgs, int a_NumResults, const char * a_FunctionName ); // a_FunctionName is only used for error messages, nothing else -private: - lua_State* m_LuaState; + cLuaState m_LuaState; } ; diff --git a/source/LuaState.cpp b/source/LuaState.cpp index e60a0f80c..aa9d796c3 100644 --- a/source/LuaState.cpp +++ b/source/LuaState.cpp @@ -420,7 +420,7 @@ bool cLuaState::CallFunction(int a_NumResults) int s = lua_pcall(m_LuaState, m_NumCurrentFunctionArgs, a_NumResults, 0); if (ReportErrors(s)) { - LOGWARNING("Error in %s calling function %s()", m_SubsystemName.c_str(), m_CurrentFunctionName); + LOGWARNING("Error in %s calling function %s()", m_SubsystemName.c_str(), m_CurrentFunctionName.c_str()); m_NumCurrentFunctionArgs = -1; m_CurrentFunctionName.clear(); return false; diff --git a/source/WebAdmin.cpp b/source/WebAdmin.cpp index 3d04ce8f3..be7efa18d 100644 --- a/source/WebAdmin.cpp +++ b/source/WebAdmin.cpp @@ -178,7 +178,7 @@ void cWebAdmin::Request_Handler(webserver::http_request* r) if (!bDontShowTemplate) { // New Lua web template - bLuaTemplateSuccessful = WebAdmin->m_pTemplate->CallFunction("ShowPage", sLuaUsertype(WebAdmin, "cWebAdmin"), sLuaUsertype(&TemplateRequest, "HTTPTemplateRequest"), Template); + bLuaTemplateSuccessful = WebAdmin->m_pTemplate->CallShowPage(*WebAdmin, TemplateRequest, Template); } if (!bLuaTemplateSuccessful) @@ -274,14 +274,14 @@ bool cWebAdmin::Init( int a_Port ) m_Port = a_Port; m_IniFile = new cIniFile("webadmin.ini"); - if( m_IniFile->ReadFile() ) + if (m_IniFile->ReadFile()) { - m_Port = m_IniFile->GetValueI("WebAdmin", "Port", 8080 ); + m_Port = m_IniFile->GetValueI("WebAdmin", "Port", 8080); } // Initialize the WebAdmin template script and load the file m_pTemplate->Initialize(); - if (!m_pTemplate->LoadFile( FILE_IO_PREFIX "webadmin/template.lua") || !m_pTemplate->Execute()) + if (!m_pTemplate->LoadFile(FILE_IO_PREFIX "webadmin/template.lua")) { LOGWARN("Could not load WebAdmin template."); } -- cgit v1.2.3 From 9b839aa32efe0287f5b28fd60285b10c6cf21d59 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 7 Aug 2013 14:26:18 +0200 Subject: cLuaState has reference management, param checking and a fixed destructor. References are now managed as RAII objects, cLuaState::cRef. Destructor now calls correct function, either Close() or Detach(), based on the owned-ness of the lua_State *. --- source/LuaState.cpp | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++- source/LuaState.h | 51 +++++++++++++- 2 files changed, 234 insertions(+), 4 deletions(-) (limited to 'source') diff --git a/source/LuaState.cpp b/source/LuaState.cpp index aa9d796c3..664ba8147 100644 --- a/source/LuaState.cpp +++ b/source/LuaState.cpp @@ -63,7 +63,14 @@ cLuaState::~cLuaState() { if (IsValid()) { - Close(); + if (m_IsOwned) + { + Close(); + } + else + { + Detach(); + } } } @@ -236,6 +243,35 @@ bool cLuaState::PushFunctionFromRegistry(int a_FnRef) +bool cLuaState::PushFunctionFromRefTable(cRef & a_TableRef, const char * a_FnName) +{ + ASSERT(IsValid()); + ASSERT(m_NumCurrentFunctionArgs == -1); // If not, there's already something pushed onto the stack + + lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_TableRef); // Get the table ref + if (!lua_istable(m_LuaState, -1)) + { + // Not a table, bail out + lua_pop(m_LuaState, 1); + return false; + } + lua_getfield(m_LuaState, -1, a_FnName); + if (lua_isnil(m_LuaState, -1) || !lua_isfunction(m_LuaState, -1)) + { + // Not a valid function, bail out + lua_pop(m_LuaState, 2); + return false; + } + lua_remove(m_LuaState, -2); // Remove the table ref from the stack + m_CurrentFunctionName = ""; + m_NumCurrentFunctionArgs = 0; + return true; +} + + + + + void cLuaState::PushStringVector(const AStringVector & a_Vector) { ASSERT(IsValid()); @@ -434,6 +470,125 @@ bool cLuaState::CallFunction(int a_NumResults) +bool cLuaState::CheckParamUserType(int a_StartParam, const char * a_UserType, int a_EndParam) +{ + ASSERT(IsValid()); + + if (a_EndParam < 0) + { + a_EndParam = a_StartParam; + } + + tolua_Error tolua_err; + for (int i = a_StartParam; i <= a_EndParam; i++) + { + if (tolua_isusertype(m_LuaState, i, a_UserType, 0, &tolua_err)) + { + continue; + } + // Not the correct parameter + lua_Debug entry; + VERIFY(lua_getstack(m_LuaState, 0, &entry)); + VERIFY(lua_getinfo (m_LuaState, "n", &entry)); + AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != NULL) ? entry.name : "?"); + tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); + return false; + } // for i - Param + + // All params checked ok + return true; +} + + + + + +bool cLuaState::CheckParamTable(int a_StartParam, int a_EndParam) +{ + ASSERT(IsValid()); + + if (a_EndParam < 0) + { + a_EndParam = a_StartParam; + } + + tolua_Error tolua_err; + for (int i = a_StartParam; i <= a_EndParam; i++) + { + if (tolua_istable(m_LuaState, i, 0, &tolua_err)) + { + continue; + } + // Not the correct parameter + lua_Debug entry; + VERIFY(lua_getstack(m_LuaState, 0, &entry)); + VERIFY(lua_getinfo (m_LuaState, "n", &entry)); + AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != NULL) ? entry.name : "?"); + tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); + return false; + } // for i - Param + + // All params checked ok + return true; +} + + + + + +bool cLuaState::CheckParamNumber(int a_StartParam, int a_EndParam) +{ + ASSERT(IsValid()); + + if (a_EndParam < 0) + { + a_EndParam = a_StartParam; + } + + tolua_Error tolua_err; + for (int i = a_StartParam; i <= a_EndParam; i++) + { + if (tolua_isnumber(m_LuaState, i, 0, &tolua_err)) + { + continue; + } + // Not the correct parameter + lua_Debug entry; + VERIFY(lua_getstack(m_LuaState, 0, &entry)); + VERIFY(lua_getinfo (m_LuaState, "n", &entry)); + AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != NULL) ? entry.name : "?"); + tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); + return false; + } // for i - Param + + // All params checked ok + return true; +} + + + + + +bool cLuaState::CheckParamEnd(int a_Param) +{ + tolua_Error tolua_err; + if (tolua_isnoobj(m_LuaState, a_Param, &tolua_err)) + { + return true; + } + // Not the correct parameter + lua_Debug entry; + VERIFY(lua_getstack(m_LuaState, 0, &entry)); + VERIFY(lua_getinfo (m_LuaState, "n", &entry)); + AString ErrMsg = Printf("#ferror in function '%s': Too many arguments.", (entry.name != NULL) ? entry.name : "?"); + tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); + return false; +} + + + + + bool cLuaState::ReportErrors(int a_Status) { return ReportErrors(m_LuaState, a_Status); @@ -459,3 +614,33 @@ bool cLuaState::ReportErrors(lua_State * a_LuaState, int a_Status) + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cLuaState::cRef: + +cLuaState::cRef::cRef(cLuaState & a_LuaState, int a_StackPos) : + m_LuaState(a_LuaState) +{ + ASSERT(m_LuaState.IsValid()); + + lua_pushvalue(m_LuaState, a_StackPos); // Push a copy of the value at a_StackPos onto the stack + m_Ref = luaL_ref(m_LuaState, LUA_REGISTRYINDEX); +} + + + + + +cLuaState::cRef::~cRef() +{ + ASSERT(m_LuaState.IsValid()); + + if (IsValid()) + { + luaL_unref(m_LuaState, LUA_REGISTRYINDEX, m_Ref); + } +} + + + + diff --git a/source/LuaState.h b/source/LuaState.h index 18c7c1354..6820f1777 100644 --- a/source/LuaState.h +++ b/source/LuaState.h @@ -13,6 +13,10 @@ Calling a Lua function is done by pushing the function, either by PushFunction() then pushing the arguments (PushString(), PushNumber(), PushUserData() etc.) and finally executing CallFunction(). cLuaState automatically keeps track of the number of arguments and the name of the function (for logging purposes), which makes the call less error-prone. + +Reference management is provided by the cLuaState::cRef class. This is used when you need to hold a reference to +any Lua object across several function calls; usually this is used for callbacks. The class is RAII-like, with +automatic resource management. */ @@ -20,12 +24,14 @@ function (for logging purposes), which makes the call less error-prone. #pragma once +extern "C" +{ + #include "lauxlib.h" +} -// fwd: lua.h -struct lua_State; class cWorld; class cPlayer; @@ -39,9 +45,31 @@ class cPickup; +/// Encapsulates a Lua state and provides some syntactic sugar for common operations class cLuaState { public: + + /// Used for storing references to object in the global registry + class cRef + { + public: + /// Creates a reference in the specified LuaState for object at the specified StackPos + cRef(cLuaState & a_LuaState, int a_StackPos); + ~cRef(); + + /// Returns true if the reference is valid + bool IsValid(void) const {return (m_Ref != LUA_REFNIL); } + + /// Allows to use this class wherever an int (i. e. ref) is to be used + operator int(void) { return m_Ref; } + + protected: + cLuaState & m_LuaState; + int m_Ref; + } ; + + /** Creates a new instance. The LuaState is not initialized. a_SubsystemName is used for reporting problems in the console, it is "plugin %s" for plugins, or "LuaScript" for the cLuaScript template @@ -90,6 +118,11 @@ public: */ bool PushFunctionFromRegistry(int a_FnRef); + /** Pushes a function that is stored in a table ref. + Returns true if successful, false on failure. Doesn't log failure. + */ + bool PushFunctionFromRefTable(cRef & a_TableRef, const char * a_FnName); + /// Pushes a string vector, as a table, onto the stack void PushStringVector(const AStringVector & a_Vector); @@ -123,7 +156,19 @@ public: Returns true if successful, logs a warning on failure. */ bool CallFunction(int a_NumReturnValues); - + + /// Returns true if the specified parameters on the stack are of the specified usertype; also logs warning if not + bool CheckParamUserType(int a_StartParam, const char * a_UserType, int a_EndParam = -1); + + /// Returns true if the specified parameters on the stack are a table; also logs warning if not + bool CheckParamTable(int a_StartParam, int a_EndParam = -1); + + /// Returns true if the specified parameters on the stack are a number; also logs warning if not + bool CheckParamNumber(int a_StartParam, int a_EndParam = -1); + + /// Returns true if the specified parameter on the stack is nil (indicating an end-of-parameters) + bool CheckParamEnd(int a_Param); + /// If the status is nonzero, prints the text on the top of Lua stack and returns true bool ReportErrors(int status); -- cgit v1.2.3 From 29b9fb0a8b138134eb929e3d1886f28e9b348dd5 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 7 Aug 2013 14:32:40 +0200 Subject: LuaScript: removed unused code --- source/LuaScript.cpp | 5 ----- source/LuaScript.h | 14 -------------- 2 files changed, 19 deletions(-) (limited to 'source') diff --git a/source/LuaScript.cpp b/source/LuaScript.cpp index f27d1793f..d406c2c02 100644 --- a/source/LuaScript.cpp +++ b/source/LuaScript.cpp @@ -6,11 +6,6 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "LuaScript.h" - -extern "C" -{ - #include "lualib.h" -} #include "tolua++.h" diff --git a/source/LuaScript.h b/source/LuaScript.h index 6c224e115..99ccb3d49 100644 --- a/source/LuaScript.h +++ b/source/LuaScript.h @@ -15,20 +15,6 @@ -/* -struct sLuaUsertype -{ - sLuaUsertype(void* a_pObject, const char* a_pClassName) : Object(a_pObject), ClassName(a_pClassName) {} - // - void* Object; - const char* ClassName; -} ; -*/ - - - - - // fwd: class cWebAdmin; struct HTTPTemplateRequest; -- cgit v1.2.3 From 10b8ee74413ccb7b84e22a0852cb4273b5ef2a80 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 7 Aug 2013 14:33:16 +0200 Subject: Plugin: Fixed plugin name in the cLuaState's subsystem --- source/Plugin_NewLua.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source') diff --git a/source/Plugin_NewLua.cpp b/source/Plugin_NewLua.cpp index b3dac7912..704bb3a95 100644 --- a/source/Plugin_NewLua.cpp +++ b/source/Plugin_NewLua.cpp @@ -21,7 +21,7 @@ extern "C" cPlugin_NewLua::cPlugin_NewLua(const AString & a_PluginDirectory) : cPlugin(a_PluginDirectory), - m_LuaState(Printf("plugin %s", GetName().c_str())) + m_LuaState(Printf("plugin %s", a_PluginDirectory.c_str())) { } -- cgit v1.2.3 From 58a76a90dc640af707aab073325827f3e8f41d71 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 7 Aug 2013 14:34:00 +0200 Subject: Added cLineBlockTracer to the API --- source/AllToLua.pkg | 8 +++ source/Bindings.cpp | 161 ++++++++++++++++++++++++++++------------- source/Bindings.h | 2 +- source/ManualBindings.cpp | 180 ++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 296 insertions(+), 55 deletions(-) (limited to 'source') diff --git a/source/AllToLua.pkg b/source/AllToLua.pkg index 7041211b5..cd22aba0a 100644 --- a/source/AllToLua.pkg +++ b/source/AllToLua.pkg @@ -63,3 +63,11 @@ $cfile "LuaWindow.h" + +// Need to declare this class so that the usertype is properly registered in Bindings.cpp - +// it seems impossible to register a usertype in ManualBindings.cpp +class cLineBlockTracer; + + + + diff --git a/source/Bindings.cpp b/source/Bindings.cpp index df45cb1b3..fd953e29d 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/02/13 08:41:18. +** Generated automatically by tolua++-1.0.92 on 08/07/13 12:06:03. */ #ifndef __cplusplus @@ -202,8 +202,11 @@ static int tolua_collect_Vector3d (lua_State* tolua_S) static void tolua_reg_types (lua_State* tolua_S) { tolua_usertype(tolua_S,"TakeDamageInfo"); - tolua_usertype(tolua_S,"cCraftingRecipe"); tolua_usertype(tolua_S,"cPlugin_NewLua"); + tolua_usertype(tolua_S,"cCraftingGrid"); + tolua_usertype(tolua_S,"cCraftingRecipe"); + tolua_usertype(tolua_S,"cPlugin"); + tolua_usertype(tolua_S,"cWindow"); tolua_usertype(tolua_S,"cStringMap"); tolua_usertype(tolua_S,"cItemGrid"); tolua_usertype(tolua_S,"cBlockArea"); @@ -211,42 +214,42 @@ static void tolua_reg_types (lua_State* tolua_S) tolua_usertype(tolua_S,"cLuaWindow"); tolua_usertype(tolua_S,"cInventory"); tolua_usertype(tolua_S,"cRoot"); - tolua_usertype(tolua_S,"cWindow"); - tolua_usertype(tolua_S,"cCraftingGrid"); - tolua_usertype(tolua_S,"cTracer"); - tolua_usertype(tolua_S,"cPickup"); - tolua_usertype(tolua_S,"cItems"); + tolua_usertype(tolua_S,"cCuboid"); + tolua_usertype(tolua_S,"std::vector"); tolua_usertype(tolua_S,"cGroup"); + tolua_usertype(tolua_S,"cPickup"); + tolua_usertype(tolua_S,"std::vector"); + tolua_usertype(tolua_S,"cTracer"); tolua_usertype(tolua_S,"cClientHandle"); tolua_usertype(tolua_S,"cChunkDesc"); tolua_usertype(tolua_S,"cFurnaceRecipe"); - tolua_usertype(tolua_S,"cCuboid"); - tolua_usertype(tolua_S,"cChatColor"); tolua_usertype(tolua_S,"Vector3i"); - tolua_usertype(tolua_S,"cEntity"); + tolua_usertype(tolua_S,"cChatColor"); + tolua_usertype(tolua_S,"cWorld"); + tolua_usertype(tolua_S,"Lua__cPickup"); tolua_usertype(tolua_S,"Lua__cWebPlugin"); - tolua_usertype(tolua_S,"cPlugin"); tolua_usertype(tolua_S,"cCraftingRecipes"); + tolua_usertype(tolua_S,"cEntity"); tolua_usertype(tolua_S,"cItem"); tolua_usertype(tolua_S,"Vector3f"); - tolua_usertype(tolua_S,"Lua__cPickup"); + tolua_usertype(tolua_S,"cWebPlugin"); tolua_usertype(tolua_S,"cDropSpenserEntity"); tolua_usertype(tolua_S,"Lua__cPlayer"); - tolua_usertype(tolua_S,"cWebPlugin"); + tolua_usertype(tolua_S,"cWebAdmin"); tolua_usertype(tolua_S,"cChestEntity"); tolua_usertype(tolua_S,"cDispenserEntity"); - tolua_usertype(tolua_S,"cWebAdmin"); + tolua_usertype(tolua_S,"sWebAdminPage"); tolua_usertype(tolua_S,"cBlockEntity"); tolua_usertype(tolua_S,"cCriticalSection"); tolua_usertype(tolua_S,"HTTPTemplateRequest"); - tolua_usertype(tolua_S,"sWebAdminPage"); tolua_usertype(tolua_S,"HTTPRequest"); tolua_usertype(tolua_S,"HTTPFormData"); tolua_usertype(tolua_S,"cFurnaceEntity"); - tolua_usertype(tolua_S,"cPluginManager"); tolua_usertype(tolua_S,"cDropperEntity"); + tolua_usertype(tolua_S,"cLineBlockTracer"); + tolua_usertype(tolua_S,"cPluginManager"); tolua_usertype(tolua_S,"cIniFile"); - tolua_usertype(tolua_S,"cWorld"); + tolua_usertype(tolua_S,"cBlockEntityWithItems"); tolua_usertype(tolua_S,"cListeners"); tolua_usertype(tolua_S,"cPawn"); tolua_usertype(tolua_S,"cPlayer"); @@ -254,7 +257,7 @@ static void tolua_reg_types (lua_State* tolua_S) tolua_usertype(tolua_S,"cBlockEntityWindowOwner"); tolua_usertype(tolua_S,"cItemGrid::cListener"); tolua_usertype(tolua_S,"cServer"); - tolua_usertype(tolua_S,"cBlockEntityWithItems"); + tolua_usertype(tolua_S,"cItems"); tolua_usertype(tolua_S,"Lua__cEntity"); tolua_usertype(tolua_S,"Vector3d"); } @@ -267,16 +270,14 @@ static int tolua_AllToLua_cIniFile_new00(lua_State* tolua_S) tolua_Error tolua_err; if ( !tolua_isusertable(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,1,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) + !tolua_isnoobj(tolua_S,2,&tolua_err) ) goto tolua_lerror; else #endif { - const std::string iniPath = ((const std::string) tolua_tocppstring(tolua_S,2,"")); { - cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)(iniPath)); + cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)()); tolua_pushusertype(tolua_S,(void*)tolua_ret,"cIniFile"); } } @@ -297,16 +298,14 @@ static int tolua_AllToLua_cIniFile_new00_local(lua_State* tolua_S) tolua_Error tolua_err; if ( !tolua_isusertable(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,1,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) + !tolua_isnoobj(tolua_S,2,&tolua_err) ) goto tolua_lerror; else #endif { - const std::string iniPath = ((const std::string) tolua_tocppstring(tolua_S,2,"")); { - cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)(iniPath)); + cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)()); tolua_pushusertype(tolua_S,(void*)tolua_ret,"cIniFile"); tolua_register_gc(tolua_S,lua_gettop(tolua_S)); } @@ -320,6 +319,59 @@ static int tolua_AllToLua_cIniFile_new00_local(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: new of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_new01 +static int tolua_AllToLua_cIniFile_new01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const std::string a_Path = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + { + cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)(a_Path)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cIniFile"); + tolua_pushcppstring(tolua_S,(const char*)a_Path); + } + } + return 2; +tolua_lerror: + return tolua_AllToLua_cIniFile_new00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + +/* method: new_local of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_new01_local +static int tolua_AllToLua_cIniFile_new01_local(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + const std::string a_Path = ((const std::string) tolua_tocppstring(tolua_S,2,0)); + { + cIniFile* tolua_ret = (cIniFile*) Mtolua_new((cIniFile)(a_Path)); + tolua_pushusertype(tolua_S,(void*)tolua_ret,"cIniFile"); + tolua_register_gc(tolua_S,lua_gettop(tolua_S)); + tolua_pushcppstring(tolua_S,(const char*)a_Path); + } + } + return 2; +tolua_lerror: + return tolua_AllToLua_cIniFile_new00_local(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + /* method: CaseSensitive of class cIniFile */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_CaseSensitive00 static int tolua_AllToLua_cIniFile_CaseSensitive00(lua_State* tolua_S) @@ -433,7 +485,7 @@ static int tolua_AllToLua_cIniFile_Path01(lua_State* tolua_S) if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Path'", NULL); #endif { - std::string tolua_ret = (std::string) self->Path(); + const std::string tolua_ret = (const std::string) self->Path(); tolua_pushcppstring(tolua_S,(const char*)tolua_ret); } } @@ -485,18 +537,20 @@ static int tolua_AllToLua_cIniFile_ReadFile00(lua_State* tolua_S) tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) + !tolua_isboolean(tolua_S,2,1,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) ) goto tolua_lerror; else #endif { cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + bool a_AllowExampleRedirect = ((bool) tolua_toboolean(tolua_S,2,true)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ReadFile'", NULL); #endif { - bool tolua_ret = (bool) self->ReadFile(); + bool tolua_ret = (bool) self->ReadFile(a_AllowExampleRedirect); tolua_pushboolean(tolua_S,(bool)tolua_ret); } } @@ -516,14 +570,14 @@ static int tolua_AllToLua_cIniFile_WriteFile00(lua_State* tolua_S) #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_isusertype(tolua_S,1,"cIniFile",0,&tolua_err) || + !tolua_isusertype(tolua_S,1,"const cIniFile",0,&tolua_err) || !tolua_isnoobj(tolua_S,2,&tolua_err) ) goto tolua_lerror; else #endif { - cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); + const cIniFile* self = (const cIniFile*) tolua_tousertype(tolua_S,1,0); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'WriteFile'", NULL); #endif @@ -541,9 +595,9 @@ static int tolua_AllToLua_cIniFile_WriteFile00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: Erase of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Erase00 -static int tolua_AllToLua_cIniFile_Erase00(lua_State* tolua_S) +/* method: Clear of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Clear00 +static int tolua_AllToLua_cIniFile_Clear00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; @@ -557,24 +611,24 @@ static int tolua_AllToLua_cIniFile_Erase00(lua_State* tolua_S) { cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Erase'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); #endif { - self->Erase(); + self->Clear(); } } return 0; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Erase'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); return 0; #endif } #endif //#ifndef TOLUA_DISABLE -/* method: Clear of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Clear00 -static int tolua_AllToLua_cIniFile_Clear00(lua_State* tolua_S) +/* method: Reset of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Reset00 +static int tolua_AllToLua_cIniFile_Reset00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; @@ -588,24 +642,24 @@ static int tolua_AllToLua_cIniFile_Clear00(lua_State* tolua_S) { cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Clear'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Reset'", NULL); #endif { - self->Clear(); + self->Reset(); } } return 0; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Clear'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'Reset'.",&tolua_err); return 0; #endif } #endif //#ifndef TOLUA_DISABLE -/* method: Reset of class cIniFile */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Reset00 -static int tolua_AllToLua_cIniFile_Reset00(lua_State* tolua_S) +/* method: Erase of class cIniFile */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cIniFile_Erase00 +static int tolua_AllToLua_cIniFile_Erase00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; @@ -619,16 +673,16 @@ static int tolua_AllToLua_cIniFile_Reset00(lua_State* tolua_S) { cIniFile* self = (cIniFile*) tolua_tousertype(tolua_S,1,0); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Reset'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'Erase'", NULL); #endif { - self->Reset(); + self->Erase(); } } return 0; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'Reset'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'Erase'.",&tolua_err); return 0; #endif } @@ -28476,6 +28530,9 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"new",tolua_AllToLua_cIniFile_new00); tolua_function(tolua_S,"new_local",tolua_AllToLua_cIniFile_new00_local); tolua_function(tolua_S,".call",tolua_AllToLua_cIniFile_new00_local); + tolua_function(tolua_S,"new",tolua_AllToLua_cIniFile_new01); + tolua_function(tolua_S,"new_local",tolua_AllToLua_cIniFile_new01_local); + tolua_function(tolua_S,".call",tolua_AllToLua_cIniFile_new01_local); tolua_function(tolua_S,"CaseSensitive",tolua_AllToLua_cIniFile_CaseSensitive00); tolua_function(tolua_S,"CaseInsensitive",tolua_AllToLua_cIniFile_CaseInsensitive00); tolua_function(tolua_S,"Path",tolua_AllToLua_cIniFile_Path00); @@ -28483,9 +28540,9 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"SetPath",tolua_AllToLua_cIniFile_SetPath00); tolua_function(tolua_S,"ReadFile",tolua_AllToLua_cIniFile_ReadFile00); tolua_function(tolua_S,"WriteFile",tolua_AllToLua_cIniFile_WriteFile00); - tolua_function(tolua_S,"Erase",tolua_AllToLua_cIniFile_Erase00); tolua_function(tolua_S,"Clear",tolua_AllToLua_cIniFile_Clear00); tolua_function(tolua_S,"Reset",tolua_AllToLua_cIniFile_Reset00); + tolua_function(tolua_S,"Erase",tolua_AllToLua_cIniFile_Erase00); tolua_function(tolua_S,"FindKey",tolua_AllToLua_cIniFile_FindKey00); tolua_function(tolua_S,"FindValue",tolua_AllToLua_cIniFile_FindValue00); tolua_function(tolua_S,"NumKeys",tolua_AllToLua_cIniFile_NumKeys00); @@ -28699,6 +28756,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"E_BLOCK_QUARTZ_BLOCK",E_BLOCK_QUARTZ_BLOCK); tolua_constant(tolua_S,"E_BLOCK_ACTIVATOR_RAIL",E_BLOCK_ACTIVATOR_RAIL); tolua_constant(tolua_S,"E_BLOCK_DROPPER",E_BLOCK_DROPPER); + tolua_constant(tolua_S,"E_BLOCK_CARPET",E_BLOCK_CARPET); tolua_constant(tolua_S,"E_BLOCK_NUMBER_OF_TYPES",E_BLOCK_NUMBER_OF_TYPES); tolua_constant(tolua_S,"E_BLOCK_MAX_TYPE_ID",E_BLOCK_MAX_TYPE_ID); tolua_constant(tolua_S,"E_ITEM_EMPTY",E_ITEM_EMPTY); @@ -30283,6 +30341,9 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetContents",tolua_AllToLua_cLuaWindow_GetContents00); tolua_variable(tolua_S,"__cItemGrid__cListener__",tolua_get_cLuaWindow___cItemGrid__cListener__,NULL); tolua_endmodule(tolua_S); + tolua_cclass(tolua_S,"cLineBlockTracer","cLineBlockTracer","",NULL); + tolua_beginmodule(tolua_S,"cLineBlockTracer"); + tolua_endmodule(tolua_S); tolua_endmodule(tolua_S); return 1; } diff --git a/source/Bindings.h b/source/Bindings.h index 6dfe855d3..a5654c062 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/02/13 08:41:19. +** Generated automatically by tolua++-1.0.92 on 08/07/13 12:06:04. */ /* Exported function */ diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp index f428b0905..4041ccc94 100644 --- a/source/ManualBindings.cpp +++ b/source/ManualBindings.cpp @@ -20,6 +20,7 @@ #include "md5/md5.h" #include "LuaWindow.h" #include "LuaState.h" +#include "LineBlockTracer.h" @@ -340,9 +341,11 @@ static int tolua_DoWithID(lua_State* tolua_S) -template< class Ty1, - class Ty2, - bool (Ty1::*Func1)(int, int, int, cItemCallback &) > +template< + class Ty1, + class Ty2, + bool (Ty1::*Func1)(int, int, int, cItemCallback &) +> static int tolua_DoWithXYZ(lua_State* tolua_S) { int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ @@ -1483,9 +1486,174 @@ tolua_lerror: +/// Provides interface between a Lua table of callbacks and the cBlockTracer::cCallbacks +class cLuaBlockTracerCallbacks : + public cBlockTracer::cCallbacks +{ +public: + cLuaBlockTracerCallbacks(cLuaState & a_LuaState, int a_ParamNum) : + m_LuaState(a_LuaState), + m_TableRef(a_LuaState, a_ParamNum) + { + } + + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override + { + if (!m_LuaState.PushFunctionFromRefTable(m_TableRef, "OnNextBlock")) + { + // No such function in the table, skip the callback + return false; + } + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + m_LuaState.PushNumber(a_BlockType); + m_LuaState.PushNumber(a_BlockMeta); + if (!m_LuaState.CallFunction(1)) + { + return false; + } + bool res = false; + if (lua_isboolean(m_LuaState, -1)) + { + res = (lua_toboolean(m_LuaState, -1) != 0); + } + lua_pop(m_LuaState, 1); + return res; + } + + virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ) override + { + if (!m_LuaState.PushFunctionFromRefTable(m_TableRef, "OnNextBlockNoData")) + { + // No such function in the table, skip the callback + return false; + } + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + if (!m_LuaState.CallFunction(1)) + { + return false; + } + bool res = false; + if (lua_isboolean(m_LuaState, -1)) + { + res = (lua_toboolean(m_LuaState, -1) != 0); + } + lua_pop(m_LuaState, 1); + return res; + } + + virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override + { + if (!m_LuaState.PushFunctionFromRefTable(m_TableRef, "OnOutOfWorld")) + { + // No such function in the table, skip the callback + return false; + } + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + if (!m_LuaState.CallFunction(1)) + { + return false; + } + bool res = false; + if (lua_isboolean(m_LuaState, -1)) + { + res = (lua_toboolean(m_LuaState, -1) != 0); + } + lua_pop(m_LuaState, 1); + return res; + } + + virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override + { + if (!m_LuaState.PushFunctionFromRefTable(m_TableRef, "OnIntoWorld")) + { + // No such function in the table, skip the callback + return false; + } + m_LuaState.PushNumber(a_BlockX); + m_LuaState.PushNumber(a_BlockY); + m_LuaState.PushNumber(a_BlockZ); + if (!m_LuaState.CallFunction(1)) + { + return false; + } + bool res = false; + if (lua_isboolean(m_LuaState, -1)) + { + res = (lua_toboolean(m_LuaState, -1) != 0); + } + lua_pop(m_LuaState, 1); + return res; + } + + virtual void OnNoMoreHits(void) override + { + if (!m_LuaState.PushFunctionFromRefTable(m_TableRef, "OnNoMoreHits")) + { + // No such function in the table, skip the callback + return; + } + m_LuaState.CallFunction(0); + } + + virtual void OnNoChunk(void) override + { + if (!m_LuaState.PushFunctionFromRefTable(m_TableRef, "OnNoChunk")) + { + // No such function in the table, skip the callback + return; + } + m_LuaState.CallFunction(0); + } + +protected: + cLuaState & m_LuaState; + cLuaState::cRef m_TableRef; +} ; + + + + + +static int tolua_cLineBlockTracer_Trace(lua_State * tolua_S) +{ + // cLineBlockTracer.Trace(World, Callbacks, StartX, StartY, StartZ, EndX, EndY, EndZ) + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cWorld") || + !L.CheckParamTable (2) || + !L.CheckParamNumber (3, 8) || + !L.CheckParamEnd (9) + ) + { + return 0; + } + + cWorld * World = (cWorld *)tolua_tousertype(L, 1, NULL); + cLuaBlockTracerCallbacks Callbacks(L, 2); + double StartX = tolua_tonumber(L, 3, 0); + double StartY = tolua_tonumber(L, 4, 0); + double StartZ = tolua_tonumber(L, 5, 0); + double EndX = tolua_tonumber(L, 6, 0); + double EndY = tolua_tonumber(L, 7, 0); + double EndZ = tolua_tonumber(L, 8, 0); + bool res = cLineBlockTracer::Trace(*World, Callbacks, StartX, StartY, StartZ, EndX, EndY, EndZ); + tolua_pushboolean(L, res ? 1 : 0); + return 1; +} + + + + + void ManualBindings::Bind(lua_State * tolua_S) { - tolua_beginmodule(tolua_S,NULL); + tolua_beginmodule(tolua_S, NULL); tolua_function(tolua_S, "StringSplit", tolua_StringSplit); tolua_function(tolua_S, "LOG", tolua_LOG); tolua_function(tolua_S, "LOGINFO", tolua_LOGINFO); @@ -1493,6 +1661,10 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "LOGWARNING", tolua_LOGWARN); tolua_function(tolua_S, "LOGERROR", tolua_LOGERROR); + tolua_beginmodule(tolua_S, "cLineBlockTracer"); + tolua_function(tolua_S, "Trace", tolua_cLineBlockTracer_Trace); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S, "cRoot"); tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith ); tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach); -- cgit v1.2.3